Пример #1
0
/* PBC Overlapped detection */
int
wps_pb_check_pushtime(unsigned long time)
{
	int i;
	int PBC_sta = PBC_OVERLAP_CNT;
	for (i = 0; i < PBC_OVERLAP_CNT; i++) {
		/*
		 * 120 seconds is too sensitive, it have a chance that we receive 
		 * a last ProbeReq with WPS_DEVICEPWDID_PUSH_BTN after clearing
		 * this station.  So plus 2 seconds
		 */
		if ((time < pbc_info[i].last_time) ||
		    ((time - pbc_info[i].last_time) > (120 + 2))) {
			memset(&pbc_info[i], 0, sizeof(PBC_STA_INFO));
		}

		if (pbc_info[i].last_time == 0)
			PBC_sta--;
	}

	TUTRACE((TUTRACE_INFO, "There are %d sta in PBC mode!\n", PBC_sta));
	TUTRACE((TUTRACE_INFO, "sta1: %02x:%02x:%02x:%02x:%02x:%02x, LT:%d/CT:%d\n",
		pbc_info[0].mac[0], pbc_info[0].mac[1], pbc_info[0].mac[2], pbc_info[0].mac[3],
		pbc_info[0].mac[4], pbc_info[0].mac[5], pbc_info[0].last_time, time));
	TUTRACE((TUTRACE_INFO, "sta2: %02x:%02x:%02x:%02x:%02x:%02x, LT:%d/CT:%d\n",
		pbc_info[1].mac[0], pbc_info[1].mac[1], pbc_info[1].mac[2], pbc_info[1].mac[3],
		pbc_info[1].mac[4], pbc_info[1].mac[5], pbc_info[1].last_time, time));
	return PBC_sta;
}
Пример #2
0
static uint32
wps_sendMsg(void *mcdev, TRANSPORT_TYPE trType, char * dataBuffer, uint32 dataLen)
{
	uint32 retVal = WPS_SUCCESS;

	TUTRACE((TUTRACE_INFO, "In wps_sendMsg\n"));

	if (trType < 1 || trType >= TRANSPORT_TYPE_MAX) {
		TUTRACE((TUTRACE_ERR, "Transport Type is not within the "
			"accepted range\n"));
		return WPS_ERR_INVALID_PARAMETERS;
	}

	switch (trType) {
	case TRANSPORT_TYPE_EAP:
		retVal = ap_eap_sm_sendMsg(dataBuffer, dataLen);
		break;
#ifdef WPS_UPNP_DEVICE
	case TRANSPORT_TYPE_UPNP_DEV:
		retVal = ap_upnp_sm_sendMsg(dataBuffer, dataLen);
		break;
#endif /* WPS_UPNP_DEVICE */
	default:
		break;
	}

	if (retVal != WPS_SUCCESS) {
		TUTRACE((TUTRACE_ERR,  "WriteData for "
			"trType %d failed.\n", trType));
	}

	return retVal;
}
Пример #3
0
void
reg_proto_encrypt_data(BufferObj *plainText, BufferObj *encrKey, BufferObj *authKey,
	BufferObj *cipherText, BufferObj *iv)
{
	BufferObj *buf = buffobj_new();
	uint8 ivBuf[SIZE_128_BITS];
	/*  10 rounds for cbc 128  = (10+1) * 4 uint32 */
	uint32 rk[44];
	uint8 outBuf[1024];
	int encrypt_len;

	if (!buf)
		return;

	if (plainText->m_dataLength == 0) {
		TUTRACE((TUTRACE_ERR, "Invalid parameters \n"));
		buffobj_del(buf);
		return;
	}

	/* Generate a random iv */
	RAND_bytes(ivBuf, SIZE_128_BITS);
	buffobj_Reset(iv);
	buffobj_Append(iv, SIZE_128_BITS, ivBuf);

	/* Now encrypt the plaintext and mac using the encryption key and IV. */
	buffobj_Append(buf, plainText->m_dataLength, plainText->pBase);

	TUTRACE((TUTRACE_ERR, "RPROTO: calling encryption of %d bytes\n", buf->m_dataLength));
	rijndaelKeySetupEnc(rk, encrKey->pBase, 128);
	encrypt_len = aes_cbc_encrypt_pad(rk, 16, ivBuf, buf->m_dataLength,
		plainText->pBase, outBuf, PAD_LEN_PADDING);
	buffobj_Append(cipherText, encrypt_len, outBuf);
	buffobj_del(buf);
}
Пример #4
0
int
wps_osl_init(char *bssid)
{
	int eap_fd = wps_eap_get_handle();
	int ret;
	struct ifreq  ifr;

	if (!if_name[0]) {
		TUTRACE((TUTRACE_ERR, "Wireless Interface not specified.\n"));
		return WPS_ERR_SYSTEM;
	}

	/* Check interface address */
	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
	if ((ret = ioctl(eap_fd, SIOCGIFHWADDR, &ifr)) < 0) {
		TUTRACE((TUTRACE_ERR, "Get interface mac failed\n"));
		return WPS_ERR_SYSTEM;
	}
	/* Copy the result back */
	memcpy(my_mac, ifr.ifr_hwaddr.sa_data, 6);
	TUTRACE((TUTRACE_INFO, "set my_mac %02x:%02x:%02x:%02x:%02x:%02x\n", my_mac[0], my_mac[1],
		my_mac[2], my_mac[3], my_mac[4], my_mac[5]));

	/* record destination bssid */
	if (bssid) {
		memcpy(peer_mac, bssid, 6);
		TUTRACE((TUTRACE_INFO, "set peer_mac %02x:%02x:%02x:%02x:%02x:%02x\n", peer_mac[0],
		peer_mac[1], peer_mac[2], peer_mac[3], peer_mac[4], peer_mac[5]));
	}

	return WPS_SUCCESS;
}
Пример #5
0
void
reg_proto_derivekey(BufferObj *KDK, BufferObj *prsnlString, uint32 keyBits, BufferObj *key)
{
	uint32 i = 0, iterations = 0;
	BufferObj *input, *output;
	uint8 hmac[SIZE_256_BITS];
	uint32 hmacLen = 0;
	uint8 *inPtr;
	uint32 temp;

	input = buffobj_new();
	if (!input)
		return;
	output = buffobj_new();
	if (!output) {
		buffobj_del(input);
		return;
	}

	TUTRACE((TUTRACE_INFO, "RPROTO: Deriving a key of %d bits\n", keyBits));

	iterations = ((keyBits/8) + PRF_DIGEST_SIZE - 1)/PRF_DIGEST_SIZE;

	/* 
	 * Prepare the input buffer. During the iterations, we need only replace the
	 * value of i at the start of the buffer.
	 */
	temp = WpsHtonl(i);
	buffobj_Append(input, SIZE_4_BYTES, (uint8 *)&temp);
	buffobj_Append(input, prsnlString->m_dataLength, prsnlString->pBase);
	temp = WpsHtonl(keyBits);
	buffobj_Append(input, SIZE_4_BYTES, (uint8 *)&temp);
	inPtr = input->pBase;

	for (i = 0; i < iterations; i++) {
		/* Set the current value of i at the start of the input buffer */
		*(uint32 *)inPtr = WpsHtonl(i+1) ; /* i should start at 1 */
		hmac_sha256(KDK->pBase, SIZE_256_BITS, input->pBase,
			input->m_dataLength, hmac, &hmacLen);
		buffobj_Append(output, hmacLen, hmac);
	}

	/* Sanity check */
	if (keyBits/8 > output->m_dataLength) {
		TUTRACE((TUTRACE_ERR, "RPROTO: Key derivation generated less bits "
			"than asked\n"));
		buffobj_del(output);
		buffobj_del(input);
		return;
	}

	/*
	 * We now have at least the number of key bits requested.
	 * Return only the number of bits asked for. Discard the excess.
	 */
	buffobj_Append(key, keyBits/8, output->pBase);
	buffobj_del(output);
	buffobj_del(input);
	TUTRACE((TUTRACE_INFO, "RPROTO: End Deriving a key of %d bits\n", keyBits));
}
Пример #6
0
uint32
wps_enrUpnpGetDeviceInfoCheck(EnrSM *e, void *inbuffer, uint32 in_len,
	void *outbuffer, uint32 *out_len)
{
	if (!inbuffer || !in_len) {
		if (false == e->reg_info->initialized) {
			TUTRACE((TUTRACE_ERR, "ENRSM: Not yet initialized.\n"));
			return WPS_ERR_NOT_INITIALIZED;
		}

		if (START != e->reg_info->e_smState) {
			TUTRACE((TUTRACE_INFO, "\n======e_lastMsgSent != M1, "
				"Step GetDeviceInfo=%d ======\n",
				wps_getUpnpDevGetDeviceInfo(e->g_mc)));
			if (wps_getUpnpDevGetDeviceInfo(e->g_mc)) {
				wps_setUpnpDevGetDeviceInfo(e->g_mc, false);

				/* copy to msg_to_send buffer */
				if (*out_len < e->reg_info->outMsg->m_dataLength) {
					e->reg_info->e_smState = FAILURE;
					TUTRACE((TUTRACE_ERR, "output message buffer to small\n"));
					return WPS_MESSAGE_PROCESSING_ERROR;
				}
				memcpy(outbuffer, (char *)e->reg_info->outMsg->pBase,
					e->reg_info->outMsg->m_dataLength);
				*out_len = e->reg_info->outMsg->m_dataLength;
				return WPS_SEND_MSG_CONT;
			}
			return WPS_SUCCESS;
		}
	}

	return WPS_CONT;
}
Пример #7
0
int
ap_eap_sm_startWPSReg(unsigned char *sta_mac, unsigned char *ap_mac)
{
	unsigned char *mac;
	int retVal;

	mac = lookupSta(sta_mac, SEARCH_ENTER);

	if (!mac) {
		TUTRACE((TUTRACE_ERR,  "no sta...\n"));
		return -1;
	}

	TUTRACE((TUTRACE_ERR,  "Build WPS Start!\n"));

	/* reset counter  */
	apEapState->eap_id = 1;

	/* store whcih if sta come from */
	memcpy(&apEapState->bssid, ap_mac, ETHER_ADDR_LEN);

	/* Request Start message */
	retVal = ap_eap_sm_req_start();

	return retVal;
}
Пример #8
0
uint32
ap_eap_sm_init(void *mc_dev, char *mac_sta, char * (*parse_msg)(char *, int, int *),
	unsigned int (*send_data)(char *, uint32), int eap_frag_threshold)
{
	TUTRACE((TUTRACE_INFO,  "Initial...\n"));

	memset(&s_apEapState, 0, sizeof(EAP_WPS_AP_STATE));
	apEapState = &s_apEapState;
	apEapState->mc_dev = mc_dev;
	memcpy(apEapState->sta_mac, mac_sta, ETHER_ADDR_LEN);
	if (parse_msg)
		apEapState->parse_msg = parse_msg;
	if (send_data)
		apEapState->send_data = send_data;

	/* For fragmentation */
	apEapState->next_frag_to_send = apEapState->msg_to_send;

	/* WSC 2.0 */
	apEap_wps_version2 = wps_get_version2(mc_dev);
	apEapState->eap_frag_threshold = EAP_WPS_FRAG_MAX;

	if (eap_frag_threshold >= 100 && eap_frag_threshold < EAP_WPS_FRAG_MAX)
		apEapState->eap_frag_threshold = eap_frag_threshold;


	TUTRACE((TUTRACE_INFO,  "ap_eap_sm_init: EAP Frag Threshold %d\n",
		apEapState->eap_frag_threshold));

	return WPS_SUCCESS;
}
Пример #9
0
/* Send EAP fragment ACK */
static int
ap_eap_sm_sendFACK()
{
	WpsEapHdr wpsEapHdr;

	/* check sta status */
	if (!WPS_STA_ACTIVE()) {
		TUTRACE((TUTRACE_ERR,  "sta not in use!\n"));
		return WPS_ERROR_MSG_TIMEOUT;
	}

	TUTRACE((TUTRACE_INFO, "Build EAP fragment ACK\n"));

	wpsEapHdr.code = EAP_CODE_REQUEST;
	wpsEapHdr.id = apEapState->eap_id;
	wpsEapHdr.length = WpsHtons(sizeof(WpsEapHdr));
	wpsEapHdr.type = EAP_TYPE_WPS;
	wpsEapHdr.vendorId[0] = WPS_VENDORID1;
	wpsEapHdr.vendorId[1] = WPS_VENDORID2;
	wpsEapHdr.vendorId[2] = WPS_VENDORID3;
	wpsEapHdr.vendorType = WpsHtonl(WPS_VENDORTYPE);
	wpsEapHdr.opcode = WPS_FRAG_ACK;
	wpsEapHdr.flags = 0;

	ap_eap_sm_sendEapol(apEapState->msg_to_send, (char *)&wpsEapHdr, sizeof(WpsEapHdr));

	return WPS_SUCCESS;
}
Пример #10
0
uint32
ap_eap_sm_sendMsg(char *dataBuffer, uint32 dataLen)
{
	uint32 retVal;
	eapol_header_t *eapolHdr = (eapol_header_t *)apEapState->msg_to_send;
	WpsEapHdr *wpsEapHdr;

	TUTRACE((TUTRACE_INFO, "In ap_eap_sm_sendMsg buffer Length = %d\n",
		dataLen));

	retVal = ap_eap_sm_create_pkt(dataBuffer, dataLen, EAP_CODE_REQUEST);
	if (retVal == WPS_SUCCESS) {
		/* Shift EAP_WPS_LF_OFFSET */
		if (dataLen < apEapState->eap_frag_threshold)
			eapolHdr = (eapol_header_t *)&apEapState->msg_to_send[EAP_WPS_LF_OFFSET];

		wpsEapHdr = (WpsEapHdr *)eapolHdr->body;
		ap_eap_sm_sendEap((char *)wpsEapHdr, WpsNtohs((uint8*)&wpsEapHdr->length));
		apEapState->state = PROCESSING_PROTOCOL;
	}
	else {
		TUTRACE((TUTRACE_ERR,  "Send EAP FAILURE to station!\n"));
		ap_eap_sm_Failure(apEap_wps_version2 ? 1 : 0);

		retVal = TREAP_ERR_SENDRECV;
	}

	return retVal;
}
bool CRegProtocol::ValidateMac(BufferObj &data, uint8 *hmac, BufferObj &key)
{
    uint8 dataMac[BUF_SIZE_256_BITS];

    //First calculate the hmac of the data
    if(HMAC(EVP_sha256(), key.GetBuf(), SIZE_256_BITS, data.GetBuf(), 
            data.Length(), dataMac, NULL) == NULL)
    {
        TUTRACE((TUTRACE_ERR, "RPROTO: HMAC failed\n"));
		if (TUTRACELEVEL & TUVERBOSE && g_verbose)
		{
		// for debugging purposes
			printf("Computed HMAC (note: only first 64 bits will be compared)\n");
			for (int i = 0; i < BUF_SIZE_256_BITS; i++) {
				printf("%2x ",dataMac[i]);
			}
			printf("\nHMAC from Authenticator(should match first 64 bits of computed HMAC)\n");
			for (int i = 0; i < 8; i++) {
				printf("%2x ",hmac[i]);
			}
			printf("\nKey is:\n");
			for (int i = 0; i < 8; i++) {
				printf("%2x ",(key.GetBuf())[i]);
			}
			printf("\n");
		}
        throw RPROT_ERR_CRYPTO;
	} else { 
		if (TUTRACELEVEL & TUVERBOSE && g_verbose)
		{
		// for debugging purposes
			printf("Computed HMAC (note: only first 64 bits will be compared)\n");
			for (int i = 0; i < BUF_SIZE_256_BITS; i++) {
				printf("%2x ",dataMac[i]);
			}
			printf("\nHMAC from Authenticator(should match first 64 bits of computed HMAC)\n");
			for (int i = 0; i < 8; i++) {
				printf("%2x ",hmac[i]);
			}
			printf("\nKey is:\n");
			for (int i = 0; i < BUF_SIZE_256_BITS; i++) {
				printf("%2x ",(key.GetBuf())[i]);
			}
			printf("\n");
		}
	}

    //next, compare it against the received hmac
    TUTRACE((TUTRACE_INFO, "RPROTO: Verifying the first 64 bits of the generated HMAC\n"));

    if(memcmp(dataMac, hmac, SIZE_64_BITS) != 0)
    {
        printf("RPROTO: HMAC results don't match\n");
        return false;
    }
    TUTRACE((TUTRACE_VERBOSE, "RPROTO: HMAC results match\n"));
    
    return true;
}
Пример #12
0
/*
 * Receive a fragmentation then send EAP_FRAG_ACK.
 */
static int
ap_eap_sm_process_frag(char *eap_msg)
{
	int ret;
	int LF_bytes = 0;
	WpsEapHdr *wpsEapHdr = (WpsEapHdr *)eap_msg;
	uint32 wps_len = WpsNtohs((uint8*)&wpsEapHdr->length) - sizeof(WpsEapHdr);
	int wps_data_received = apEapState->total_received - sizeof(WpsEapHdr);


	TUTRACE((TUTRACE_INFO, "Receive a EAP WPS fragment packet\n"));

	/* Total length checking */
	if (apEapState->total_bytes_to_recv < wps_data_received + wps_len) {
		TUTRACE((TUTRACE_ERR, "Received WPS data len %d excess total bytes to "
			"receive %d\n", wps_data_received + wps_len,
			apEapState->total_bytes_to_recv));
		return EAP_FAILURE;
	}

	/* Copy to frags_received */
	/* First fragmentation include WpsEapHdr without length field */
	if (apEapState->total_received == 0) {
		memcpy(apEapState->frags_received, eap_msg, sizeof(WpsEapHdr));
		apEapState->total_received += sizeof(WpsEapHdr);

		/* Ignore length field 2 bytes copy */
		LF_bytes = EAP_WPS_LF_OFFSET;
	}
	/* WPS data */
	memcpy(&apEapState->frags_received[apEapState->total_received],
		eap_msg + sizeof(WpsEapHdr) + LF_bytes,	wps_len - LF_bytes);
	apEapState->total_received += wps_len - LF_bytes;

	/* Is last framentation? */
	if (wpsEapHdr->flags & EAP_WPS_FLAGS_MF) {
		/* Increase eap_id */
		apEapState->eap_id++;

		/* Send WPS_FRAG_ACK */
		ret = ap_eap_sm_sendFACK();
		if (ret == WPS_SUCCESS)
			return WPS_CONT;

		return ret;
	}

	/* Got all fragmentations, adjust WpsEapHdr */
	wpsEapHdr = (WpsEapHdr *)apEapState->frags_received;
	wpsEapHdr->length = WpsHtons((uint16)apEapState->total_received);

	TUTRACE((TUTRACE_ERR, "Received all WPS fragmentations, total bytes of WPS data "
		"to receive %d, received %d\n", apEapState->total_bytes_to_recv,
		apEapState->total_received - sizeof(WpsEapHdr)));

	return WPS_SUCCESS;
}
Пример #13
0
static void
wpssta_print_credential(WpsEnrCred *credential, char *title)
{
	char keystr[65];

	if (title)
		TUTRACE((TUTRACE_INFO, "\n%s\n", title));

	TUTRACE((TUTRACE_INFO, "SSID = %s\n", credential->ssid));
	TUTRACE((TUTRACE_INFO, "Key Mgmt type is %s\n", credential->keyMgmt));
	strncpy(keystr, credential->nwKey, credential->nwKeyLen);
	keystr[credential->nwKeyLen] = 0;
	TUTRACE((TUTRACE_INFO, "Key : %s\n", keystr));
	if (credential->encrType == 0) {
		TUTRACE((TUTRACE_INFO, "Encryption : NONE\n"));
	}
	else {
		if (credential->encrType & ENCRYPT_WEP) {
			TUTRACE((TUTRACE_INFO, "Encryption :  WEP\n"));
			TUTRACE((TUTRACE_INFO, "WEP Index: %d\n", credential->wepIndex));
		}
		if (credential->encrType & ENCRYPT_TKIP)
			TUTRACE((TUTRACE_INFO, "Encryption :  TKIP\n"));
		if (credential->encrType & ENCRYPT_AES)
			TUTRACE((TUTRACE_INFO, "Encryption :  AES\n"));
	}
}
uint32 CRegProtocol::CreatePrivateKey(char *name, 
                                      EVP_PKEY **key)
{
    TU_RET err = TU_ERROR_CRYPTO_FAILED;
    RSA *rsaKey;
    EVP_PKEY *pkey;
    FILE *fp;

    rsaKey = RSA_generate_key(1024, 65537, NULL, NULL);
    if(rsaKey == NULL)
    {
        TUTRACE((TUTRACE_ERR, "Couldn't generate RSA key\n"));
        goto EXIT;
    }

    //Now store it in a PKEY
    pkey = EVP_PKEY_new();
    if(!pkey)
    {
        TUTRACE((TUTRACE_ERR, "Couldn't generate new EVP key\n"));
        goto EXIT;
    }

    if(!EVP_PKEY_assign_RSA(pkey, rsaKey))
    {
        TUTRACE((TUTRACE_ERR, "Couldn't assign RSA key to EVP key\n"));
        RSA_free(rsaKey);
        goto EXIT;
    }

    fp = fopen(name, "w");
    
    if(!PEM_write_PKCS8PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL))
    {
        TUTRACE((TUTRACE_ERR, "Error writing Signing key to file\n"));
        fclose(fp);
        goto ERR_EVP;
    }
    
    fclose(fp);

    if(key)
        *key = pkey;
    else
        EVP_PKEY_free(pkey);

    return TU_SUCCESS;

ERR_EVP:
    EVP_PKEY_free(pkey);
EXIT:
    return err;
}
Пример #15
0
static int
wpssta_success(wpssta_wksp_t *sta_wksp)
{
	int retVal = WPS_RESULT_SUCCESS, ssidlen = 0;
	char ssid[SIZE_SSID_LENGTH];
	WpsEnrCred *credential = (WpsEnrCred *)malloc(sizeof(WpsEnrCred));

	/* Remove WPS IE before doing 4-way handshake */
	rem_wps_ie(NULL, 0, VNDR_IE_PRBREQ_FLAG);
	if (b_wps_version2)
		rem_wps_ie(NULL, 0, VNDR_IE_ASSOCREQ_FLAG);

	if (credential == NULL) {
		TUTRACE((TUTRACE_INFO, "memory allocate failed!!\n"));
		wpsenr_osl_proc_states(WPS_MSG_ERR); /* FAILED */
		return WPS_RESULT_FAILURE;
	}

	TUTRACE((TUTRACE_INFO, "WPS Protocol SUCCEEDED !!\n"));

	/* get credentials */
	if (sta_wksp->mode == WPSM_STA_BUILTINREG) {
		if (sta_wksp->configap == true)
			wps_get_reg_M8credentials(credential);
		else
			wps_get_reg_M7credentials(credential);
	}
	else {
		wps_get_ssid(ssid, &ssidlen);
		wps_get_credentials(credential, ssid, ssidlen);
	}

	wpssta_print_credential(credential, "Current AP Credential");

	wpsenr_osl_proc_states(WPS_OK); /* SUCCEEDED */

	if (wpsenr_osl_set_wsec(sta_wksp->ess_id, credential,
		(sta_wksp->mode == WPSM_STA_BUILTINREG) ?
		EModeRegistrar : EModeClient))
		retVal  = WPS_RESULT_SUCCESS_RESTART;
	else
		retVal  = WPS_RESULT_SUCCESS;

	/* free memory */
	free(credential);

	/* WPS 2.0. test 5.1.1, leave network before do_wpa_psk with new security */
	WpsSleepMs(500);
	leave_network();

	return retVal;
}
Пример #16
0
uint32
reg_proto_generate_dhkeypair(DH **DHKeyPair, BufferObj *pubKey)
{
	uint8 temp[SIZE_PUB_KEY];
	uint32 g = 0;


	/* 1. Initialize the DH structure */
	*DHKeyPair = DH_new();
	if (*DHKeyPair == NULL) {
		TUTRACE((TUTRACE_ERR, "RPROTO: DH_new failed\n"));
		return RPROT_ERR_CRYPTO;
	}

	(*DHKeyPair)->p = BN_new();
	if ((*DHKeyPair)->p == NULL) {
		TUTRACE((TUTRACE_ERR, "RPROTO: BN_new p failed\n"));
		return RPROT_ERR_CRYPTO;
	}

	(*DHKeyPair)->g = BN_new();
	if ((*DHKeyPair)->g == NULL) {
		TUTRACE((TUTRACE_ERR, "RPROTO: BN_new g failed\n"));
		return RPROT_ERR_CRYPTO;
	}

	/* 2. load the value of P */
	if (BN_bin2bn(DH_P_VALUE, BUF_SIZE_1536_BITS, (*DHKeyPair)->p) == NULL) {
		TUTRACE((TUTRACE_ERR, "RPROTO: load value p failed\n"));
		return RPROT_ERR_CRYPTO;
	}

	/* 3. load the value of G */
	g = WpsHtonl(DH_G_VALUE);
	if (BN_bin2bn((uint8 *)&g, 4, (*DHKeyPair)->g) == NULL) {
		TUTRACE((TUTRACE_ERR, "RPROTO: load value g failed\n"));
		return RPROT_ERR_CRYPTO;
	}

	/* 4. generate the DH key */
	if (WPS_DH_GENERATE_KEY(NULL, *DHKeyPair) == 0) {
		TUTRACE((TUTRACE_ERR, "RPROTO: DH generate key failed\n"));
		return RPROT_ERR_CRYPTO;
	}

	/* 5. extract the DH public key */
	if (reg_proto_BN_bn2bin((*DHKeyPair)->pub_key, temp) != SIZE_PUB_KEY) {
		TUTRACE((TUTRACE_ERR, "RPROTO: invalid public key length\n"));
		return RPROT_ERR_CRYPTO;
	}

	TUTRACE((TUTRACE_ERR, "DH generate 6\n"));
	buffobj_Append(pubKey, SIZE_PUB_KEY, temp);
	TUTRACE((TUTRACE_ERR, "DH generate 7\n"));
	return WPS_SUCCESS;
}
Пример #17
0
void *
wps_init(void *bcmwps, DevInfo *ap_devinfo)
{
	WPSAPI_T *gp_mc;
	DevInfo *dev_info;

	gp_mc = (WPSAPI_T *)alloc_init(sizeof(*gp_mc));
	if (!gp_mc) {
		TUTRACE((TUTRACE_INFO, "wps_init::malloc failed!\n"));
		return 0;
	}

	gp_mc->dev_info = devinfo_new();
	if (gp_mc->dev_info == NULL)
		goto error;

	/* copy user provided DevInfo to mp_deviceInfo */
	dev_info = gp_mc->dev_info;
	memcpy(dev_info, ap_devinfo, sizeof(DevInfo));

	/* copy prebuild enrollee noce and private key */
	if (dev_info->flags & DEVINFO_FLAG_PRE_PRIV_KEY) {
		if (reg_proto_generate_prebuild_dhkeypair(
			&dev_info->DHSecret, dev_info->pre_privkey) != WPS_SUCCESS) {
			TUTRACE((TUTRACE_ERR, "wps_init::prebuild_dhkeypair failed!\n"));
			goto error;
		}
	}
	else {
		if (reg_proto_generate_dhkeypair(&dev_info->DHSecret) != WPS_SUCCESS) {
			TUTRACE((TUTRACE_ERR, "wps_init::gen dhkeypair failed!\n"));
			goto error;
		}
	}

	gp_mc->mb_initialized = true;
	TUTRACE((TUTRACE_INFO, "wps_init::Done!\n"));

	/* Everything's initialized ok */
	gp_mc->bcmwps = bcmwps;

	return (void *)gp_mc;

error:
	TUTRACE((TUTRACE_ERR, "wps_init::Init failed\n"));
	if (gp_mc) {
		wps_deinit(gp_mc);
	}

	return 0;
}
void CRegProtocol::DeriveKey(BufferObj &KDK, 
                             BufferObj &prsnlString, 
                             uint32 keyBits, 
                             BufferObj &key)
{
    uint32 i = 0, iterations = 0;
    BufferObj input, output;    
    uint8 hmac[SIZE_256_BITS];
    uint32 hmacLen = 0;
    uint8 *inPtr;
    uint32 temp;

    TUTRACE((TUTRACE_INFO, "RPROTO: Deriving a key of %d bits\n", keyBits));

    iterations = ((keyBits/8) + PRF_DIGEST_SIZE - 1)/PRF_DIGEST_SIZE;

    //Prepare the input buffer. During the iterations, we need only replace the 
    //value of i at the start of the buffer.
    temp = WscHtonl(i);
    input.Append(SIZE_4_BYTES, (uint8 *)&temp);
    input.Append(prsnlString.Length(), prsnlString.GetBuf());
    temp = WscHtonl(keyBits);
    input.Append(SIZE_4_BYTES, (uint8 *)&temp);
    inPtr = input.GetBuf();

    for(i = 0; i < iterations; i++)
    {
        //Set the current value of i at the start of the input buffer
        *(uint32 *)inPtr = WscHtonl(i+1); //i should start at 1
        if(HMAC(EVP_sha256(), KDK.GetBuf(), SIZE_256_BITS, input.GetBuf(), 
                input.Length(), hmac, &hmacLen) == NULL)
        {
            TUTRACE((TUTRACE_ERR, "RPROTO: HMAC failed\n"));
            throw RPROT_ERR_CRYPTO;
        }
        output.Append(hmacLen, hmac);
    }

    //Sanity check
    if(keyBits/8 > output.Length())
    {
        TUTRACE((TUTRACE_ERR, "RPROTO: Key derivation generated less bits "
                              "than asked\n"));
        throw RPROT_ERR_CRYPTO;
    }

    //We now have at least the number of key bits requested.
    //Return only the number of bits asked for. Discard the excess.
    key.Append(keyBits/8, output.GetBuf());
}
Пример #19
0
/*
 * Search for or create a STA.
 * We can only handle only ONE station at a time.
 * If `enter' is not set, do not create it when one is not found.
 */
static unsigned char*
lookupSta(unsigned char *sta_mac, sta_lookup_mode_t mode)
{
	unsigned char *mac = NULL;
	int sta_active = WPS_STA_ACTIVE();

	/* Search if the entry in on the list */
	if (sta_active &&
		(!memcmp(&apEapState->sta_mac, sta_mac, ETHER_ADDR_LEN))) {
		mac = apEapState->sta_mac;
	}

	/* create a new entry if necessary */
	if (!mac && mode == SEARCH_ENTER) {
		if (!sta_active) {
			/* Initialize entry */
			memcpy(&apEapState->sta_mac, sta_mac, ETHER_ADDR_LEN);
			/* Initial STA state: */
			apEapState->state = INIT;
			apEapState->eap_id = 0;
			mac = apEapState->sta_mac;
		}
		else
			TUTRACE((TUTRACE_ERR,  "Sta in use\n"));
	}

	return mac;
}
Пример #20
0
uint32
ap_eap_sm_sendWPSStart()
{
	WpsEapHdr wpsEapHdr;

	/* check sta status */
	if (!WPS_STA_ACTIVE()) {
		TUTRACE((TUTRACE_ERR,  "sta not in use!\n"));
		return WPS_ERROR_MSG_TIMEOUT;
	}

	wpsEapHdr.code = EAP_CODE_REQUEST;
	wpsEapHdr.id = apEapState->eap_id;
	wpsEapHdr.length = WpsHtons(sizeof(WpsEapHdr));
	wpsEapHdr.type = EAP_TYPE_WPS;
	wpsEapHdr.vendorId[0] = WPS_VENDORID1;
	wpsEapHdr.vendorId[1] = WPS_VENDORID2;
	wpsEapHdr.vendorId[2] = WPS_VENDORID3;
	wpsEapHdr.vendorType = WpsHtonl(WPS_VENDORTYPE);
	wpsEapHdr.opcode = WPS_Start;
	wpsEapHdr.flags = 0;

	ap_eap_sm_sendEapol(apEapState->msg_to_send, (char *)&wpsEapHdr, sizeof(WpsEapHdr));
	apEapState->state = EAP_START_SEND;
	apEapState->sent_msg_id = WPS_PRIVATE_ID_WPS_START;

	return WPS_SUCCESS;
}
Пример #21
0
devcfg *
devcfg_new()
{
	devcfg *inf = (devcfg*)alloc_init(sizeof(devcfg));
	if (!inf)
		return NULL;

	inf->mp_deviceInfo = (DevInfo *)alloc_init(sizeof(DevInfo));

	if (!inf->mp_deviceInfo) {
		TUTRACE((TUTRACE_INFO, "Info::Info: Could not create deviceInfo\n"));
		free(inf);
		return NULL;
	}

	/* Initialize other member variables */
	memset(inf->mp_deviceInfo, 0, sizeof(DevInfo));
	inf->mp_deviceInfo->assocState = WPS_ASSOC_NOT_ASSOCIATED;
	inf->mp_deviceInfo->configError = 0; /* No error */
	inf->mp_deviceInfo->devPwdId = WPS_DEVICEPWDID_DEFAULT;
	inf->mb_infoConfigSet = false;
	inf->mb_useUsbKey = false;
	inf->mb_regWireless = false;
	inf->mb_useUpnp = false;
	inf->mb_nwKeySet = false;
	inf->m_nwKeyLen = 0;
	inf->mp_dhKeyPair = NULL;
	inf->mcp_devPwd = NULL;
	memset(inf->m_pubKey, 0, SIZE_PUB_KEY);
	memset(inf->m_sha256Hash, 0, SIZE_256_BITS);

	return inf;
}
Пример #22
0
/* Add for PF3 */
static uint32
wps_regUpnpERFilter(RegSM *r, BufferObj *msg, uint32 msgType)
{
	uint32 err;


	/*
	 * If AP have received M2 form one External Registrar,
	 * AP must ignore forwarding messages from other
	 * External Registrars.
	 */
	if (r->m_er_sentM2 == false) {
		if (msgType == WPS_ID_MESSAGE_M2) {
			/* Save R-Nonce */
			err = reg_proto_get_nonce(r->m_er_nonce, msg, WPS_ID_REGISTRAR_NONCE);
			if (err != WPS_SUCCESS) {
				TUTRACE((TUTRACE_ERR, "ENRSM: Get R-Nonce error: %d\n", err));
			}
			else {
				r->m_er_sentM2 = true;
			}
		}
	}
	else {
		/* Filter UPnP to EAP messages by R-Nonce */
		err = reg_proto_check_nonce(r->m_er_nonce, msg, WPS_ID_REGISTRAR_NONCE);
		if (err == RPROT_ERR_NONCE_MISMATCH)
			return WPS_CONT;
	}

	return WPS_SUCCESS;
}
Пример #23
0
int
wps_upnpDevSSR(WPSAPI_T *g_mc, CTlvSsrIE *ssrmsg)
{
	WPS_SCMODE sc_mode = g_mc->dev_info->sc_mode;
	uint8 scState = g_mc->dev_info->scState;

	TUTRACE((TUTRACE_INFO, "MC_Recd CB_TRUPNP_DEV_SSR\n"));

	/*
	 * Added to support SetSelectedRegistrar
	 * If we are an AP+Proxy, then add the SelectedRegistrar TLV
	 * to the WPS IE in the Beacon
	 * This call will fail if the right WLAN drivers are not used.
	 */
	if (sc_mode == SCMODE_AP_REGISTRAR) {
		wps_setWpsIE(g_mc,
			scState,
			ssrmsg->selReg.m_data,
			ssrmsg->devPwdId.m_data,
			ssrmsg->selRegCfgMethods.m_data,
			ssrmsg->authorizedMacs.m_data,
			ssrmsg->authorizedMacs.subtlvbase.m_len);
	}

	return WPS_CONT;
}
Пример #24
0
/* Get first non-WPS V2 registrar's ipaddr when no uuid_r and enroll_mac arguments */
char *
ap_ssr_get_ipaddr(char* uuid_r, char *enroll_mac)
{
	void *findobj;
	int findtype;
	WPS_SSR_SCB *scb;

	if (!uuid_r && !enroll_mac) {
		findobj = NULL;
		findtype = WPS_SSR_SCB_FIND_ANY;
	} else {
		if (uuid_r) {
			findobj = uuid_r;
			findtype = WPS_SSR_SCB_FIND_UUID_R;
		}
		else {
			findobj = enroll_mac;
			findtype = WPS_SSR_SCB_FIND_AUTHORIED_MAC;
		}
	}

	/* Find scb by findobj */
	scb = ap_ssr_find_scb(findobj, findtype, WPS_SSR_SCB_SEARCH_ONLY);
	if (scb == NULL) {
		TUTRACE((TUTRACE_INFO, "Can not find scb\n"));
		return empty_ipaddr;
	}

	return scb->ipaddr;
}
Пример #25
0
int ap_eap_sm_process_timeout()
{
	/* If there is a message pending, re-send for a limited number of time. */
	if (apEapState->last_sent_len == 0) {
		TUTRACE((TUTRACE_ERR, "No data avaliable to retransmit.\n"));
		return EAP_TIMEOUT;
	}

	if (apEapState->resent_count <= EAP_MAX_RESEND_COUNT) {
		ap_eap_sm_resend_last_sent();
		TUTRACE((TUTRACE_ERR, "timeout receiving from STA. Retry previous message\n"));
		return WPS_CONT;
	}
	else {
		TUTRACE((TUTRACE_ERR, "Retry count exceeded. Bail out\n"));
		return EAP_TIMEOUT;
	}
}
Пример #26
0
bool
reg_proto_validate_mac(BufferObj *data, uint8 *hmac, BufferObj *key)
{
	uint8 dataMac[BUF_SIZE_256_BITS];

	/* First calculate the hmac of the data */
	hmac_sha256(key->pBase, SIZE_256_BITS, data->pBase,
		data->m_dataLength, dataMac, NULL);

	/* next, compare it against the received hmac */
	TUTRACE((TUTRACE_INFO, "RPROTO: Verifying the first 64 bits of the generated HMAC\n"));

	if (memcmp(dataMac, hmac, SIZE_64_BITS) != 0) {
		TUTRACE((TUTRACE_ERR, "RPROTO: HMAC results don't match\n"));
		return false;
	}
	return true;
}
Пример #27
0
static void
wpssta_filter_credential(WpsEnrCred *credential)
{
	int encrType_mixed = (ENCRYPT_TKIP | ENCRYPT_AES);

	/* Always use WPA2PSK when both WPAPSK and WPA2PSK enabled */
	if (strstr(credential->keyMgmt, "WPA-PSK") &&
	    strstr(credential->keyMgmt, "WPA2-PSK")) {
		strcpy(credential->keyMgmt, "WPA2-PSK");
		TUTRACE((TUTRACE_INFO, "Key Mgmt type is mixed-mode, pick WPA2-PSK up\n"));
	}

	/* Always use AES when encryptoin type in mixed-mode */
	if ((credential->encrType & encrType_mixed) == encrType_mixed) {
		credential->encrType &= ~ENCRYPT_TKIP;
		TUTRACE((TUTRACE_INFO, "Encryption is mixed-mode, pick AES up\n"));
	}
}
Пример #28
0
void
reg_proto_generate_sha256hash(BufferObj *inBuf, BufferObj *outBuf)
{
	uint8 Hash[SIZE_256_BITS];
	if (SHA256(inBuf->pBase, inBuf->m_dataLength, Hash) == NULL) {
		TUTRACE((TUTRACE_ERR, "RPROTO: SHA256 calculation failed\n"));
		return;
	}
	buffobj_Append(outBuf, SIZE_256_BITS, Hash);
}
Пример #29
0
uint32
reg_proto_check_nonce(IN uint8 *nonce, IN BufferObj *msg, IN int nonceType)
{
	uint16 type;

	if ((nonceType != WPS_ID_REGISTRAR_NONCE) &&
		(nonceType !=  WPS_ID_ENROLLEE_NONCE)) {
		TUTRACE((TUTRACE_ERR, "RPROTO: Invalid attribute ID passed to"
			" CheckNonce\n"));
		return WPS_ERR_INVALID_PARAMETERS;
	}

	while (1) {
		type = buffobj_NextType(msg);
		if (!type)
			break;
		if (nonceType == type) {
			if (!(memcmp(nonce, msg->pCurrent+sizeof(WpsTlvHdr),
				SIZE_128_BITS))) {
				buffobj_Rewind(msg);
				return WPS_SUCCESS;
			}
			else {
				TUTRACE((TUTRACE_ERR, "RPROTO: Nonce mismatch\n"));
				buffobj_Rewind(msg);
				return RPROT_ERR_NONCE_MISMATCH;
			}
		}

		/*
		 * advance past the TLV - the total number of bytes to advance is
		 * the size of the TLV header + the length indicated in the header
		 */
		if (!(buffobj_Advance(msg, sizeof(WpsTlvHdr) +
			WpsNtohs((msg->pCurrent+sizeof(uint16)))))) {
			TUTRACE((TUTRACE_ERR, "RPROTO: Didn't find nonce\n"));
			break;
		 }
	}

	buffobj_Rewind(msg);
	return RPROT_ERR_REQD_TLV_MISSING;
}
//Encrypted settings for M7
//ES when M7 is from an enrollee
void CTlvEsM7Enr::parse(BufferObj &theBuf, BufferObj &authKey, bool allocate)
{
    nonce = CTlvNonce(WSC_ID_E_SNONCE2, theBuf, SIZE_128_BITS);

    if(WSC_ID_IDENTITY_PROOF == theBuf.NextType())
        idProof = CTlvIdentityProof(WSC_ID_IDENTITY_PROOF, theBuf, 0, allocate);

	// Skip attributes until the KeyWrapAuthenticator
	while(WSC_ID_KEY_WRAP_AUTH != theBuf.NextType())
    {
        //advance past the TLV
        uint8 *Pos = theBuf.Advance( sizeof(S_WSC_TLV_HEADER) + 
							WscNtohs(*(uint16 *)(theBuf.Pos()+sizeof(uint16))) );
        
        //If Advance returned NULL, it means there's no more data in the
        //buffer. This is an error.
        if(Pos == NULL)
            throw RPROT_ERR_REQD_TLV_MISSING;
    }

	uint8 * startOfAuthenticator = theBuf.Pos();
    keyWrapAuth = CTlvAuthenticator(WSC_ID_KEY_WRAP_AUTH, theBuf, SIZE_64_BITS);

    //validate the mac
    uint8 dataMac[BUF_SIZE_256_BITS];

    //calculate the hmac of the data (data only, not the last auth TLV)
    if(HMAC(EVP_sha256(), authKey.GetBuf(), SIZE_256_BITS, theBuf.GetBuf(),
            startOfAuthenticator - theBuf.GetBuf(), 
            dataMac, NULL) == NULL)
    {
        TUTRACE((TUTRACE_ERR, "RPROTO: HMAC failed\n"));
        throw RPROT_ERR_CRYPTO;
    }

    //compare it against the received hmac
    if(memcmp(dataMac, keyWrapAuth.Value(), SIZE_64_BITS) != 0)
    {
        TUTRACE((TUTRACE_ERR, "RPROTO: HMAC results don't match\n"));
        throw RPROT_ERR_INVALID_VALUE;
    }
}