Ejemplo n.º 1
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));
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
static uint32
ap_eap_sm_create_pkt(char * dataBuffer, int dataLen, uint8 eapCode)
{
	eapol_header_t *eapolHdr = (eapol_header_t *)apEapState->msg_to_send;
	WpsEapHdr *wpsEapHdr;
	int LF_bytes = EAP_WPS_LF_OFFSET;

	/* Shift EAP_WPS_LF_OFFSET */
	if (dataLen < apEapState->eap_frag_threshold) {
		eapolHdr = (eapol_header_t *)&apEapState->msg_to_send[EAP_WPS_LF_OFFSET];
		LF_bytes = 0;
	}

	/* Construct EAP header */
	wpsEapHdr = (WpsEapHdr *)eapolHdr->body;

	wpsEapHdr->code = eapCode;
	wpsEapHdr->id = apEapState->eap_id;
	wpsEapHdr->length = WpsHtons(sizeof(WpsEapHdr) + dataLen);
	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);

	if (dataBuffer) {
		if (dataBuffer[WPS_MSGTYPE_OFFSET] >= WPS_ID_MESSAGE_M1 &&
			dataBuffer[WPS_MSGTYPE_OFFSET] <= WPS_ID_MESSAGE_M8) {
			wpsEapHdr->opcode = WPS_MSG;
		}
		else if (dataBuffer[WPS_MSGTYPE_OFFSET] == WPS_ID_MESSAGE_ACK) {
			wpsEapHdr->opcode = WPS_ACK;
		}
		else if (dataBuffer[WPS_MSGTYPE_OFFSET] == WPS_ID_MESSAGE_NACK) {
			wpsEapHdr->opcode = WPS_NACK;
		}
		else if (dataBuffer[WPS_MSGTYPE_OFFSET] == WPS_ID_MESSAGE_DONE) {
			wpsEapHdr->opcode = WPS_Done;
		}
		else {
			TUTRACE((TUTRACE_ERR, "Unknown Message Type code %d; "
				"Not sending msg\n", dataBuffer[WPS_MSGTYPE_OFFSET]));
			return TREAP_ERR_SENDRECV;
		}

		/* record the out message id, we don't save fragmented sent_msg_id */
		apEapState->sent_msg_id = dataBuffer[WPS_MSGTYPE_OFFSET];
		if (apEapState->sent_msg_id == WPS_ID_MESSAGE_M2)
			apEapState->flags |= AP_EAP_SM_M2_SENT;

		/* TBD: Flags are always set to zero for now, if message is too big */
		/*
		 * fragmentation must be done here and flags will have some bits set
		 * and message length field is added
		 */
		/* Default flags are set to zero, let ap_eap_sm_sendEap to handle it */
		wpsEapHdr->flags = 0;

		/* in case we passed this buffer to the protocol, do not copy :-) */
		if (dataBuffer - LF_bytes != (char *)(wpsEapHdr + 1))
			memcpy((char *)wpsEapHdr + sizeof(WpsEapHdr) + LF_bytes,
				dataBuffer, dataLen);
	}

	return WPS_SUCCESS;
}
Ejemplo n.º 6
0
uint32
reg_proto_generate_prebuild_dhkeypair(DH **DHKeyPair, BufferObj *pubKey,
	uint8 *prebuild_privkey)
{
	BIGNUM *pub_key = NULL, *priv_key = NULL;
	BN_CTX *ctx = NULL;
	BN_MONT_CTX *mont;
	uint8 temp[SIZE_PUB_KEY];
	uint32 g = 0;
	uint32 ret = RPROT_ERR_CRYPTO;


	*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 */
	ctx = BN_CTX_new();
	if (ctx == NULL)
		goto err;

	priv_key = BN_new();
	if (priv_key == NULL)
		goto err;

	pub_key = BN_new();
	if (pub_key == NULL)
		goto err;

	if (!BN_bin2bn(prebuild_privkey, SIZE_PUB_KEY, priv_key))
		goto err;

	if ((*DHKeyPair)->flags & DH_FLAG_CACHE_MONT_P) {
		if (((*DHKeyPair)->method_mont_p = BN_MONT_CTX_new()) != NULL)
			if (!BN_MONT_CTX_set((BN_MONT_CTX *)(*DHKeyPair)->method_mont_p,
			                     (*DHKeyPair)->p, ctx))
				goto err;
	}
	mont = (BN_MONT_CTX *)(*DHKeyPair)->method_mont_p;

	if ((*DHKeyPair)->g->top == 1) {
		BN_ULONG A = (*DHKeyPair)->g->d[0];
		if (!BN_mod_exp_mont_word(pub_key, A, priv_key, (*DHKeyPair)->p, ctx, mont))
			goto err;
	} else
		if (!BN_mod_exp_mont(pub_key, (*DHKeyPair)->g, priv_key, (*DHKeyPair)->p,
			ctx, mont))
			goto err;

	(*DHKeyPair)->pub_key = pub_key;
	(*DHKeyPair)->priv_key = priv_key;
	if (BN_num_bytes((*DHKeyPair)->pub_key) == 0)
		goto err;

	/* 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"));
		goto err;
	}

	buffobj_Append(pubKey, SIZE_PUB_KEY, temp);

	ret = WPS_SUCCESS;

err:
	if ((pub_key != NULL) && ((*DHKeyPair)->pub_key == NULL))
		BN_free(pub_key);
	if ((priv_key != NULL) && ((*DHKeyPair)->priv_key == NULL))
		BN_free(priv_key);
	if (ctx)
		BN_CTX_free(ctx);

	return ret;
}