示例#1
0
uint16_t enc_signed_write_cmd(uint16_t handle, const uint8_t *value,
					size_t vlen, struct bt_crypto *crypto,
					const uint8_t csrk[16],
					uint32_t sign_cnt,
					uint8_t *pdu, size_t len)
{
	const uint16_t hdr_len = sizeof(pdu[0]) + sizeof(handle);
	const uint16_t min_len =  hdr_len + ATT_SIGNATURE_LEN;

	if (pdu == NULL)
		return 0;

	if (vlen > len - min_len)
		vlen = len - min_len;

	pdu[0] = ATT_OP_SIGNED_WRITE_CMD;
	put_le16(handle, &pdu[1]);

	if (vlen > 0)
		memcpy(&pdu[hdr_len], value, vlen);

	if (!bt_crypto_sign_att(crypto, csrk, pdu, hdr_len + vlen, sign_cnt,
							&pdu[hdr_len + vlen]))
		return 0;

	return min_len + vlen;
}
示例#2
0
static bool encode_pdu(struct bt_att *att, struct att_send_op *op,
					const void *pdu, uint16_t length)
{
	uint16_t pdu_len = 1;
	struct sign_info *sign = att->local_sign;
	uint32_t sign_cnt;

	if (sign && (op->opcode & ATT_OP_SIGNED_MASK))
		pdu_len += BT_ATT_SIGNATURE_LEN;

	if (length && pdu)
		pdu_len += length;

	if (pdu_len > att->mtu)
		return false;

	op->len = pdu_len;
	op->pdu = malloc(op->len);
	if (!op->pdu)
		return false;

	((uint8_t *) op->pdu)[0] = op->opcode;
	if (pdu_len > 1)
		memcpy(op->pdu + 1, pdu, length);

	if (!sign || !(op->opcode & ATT_OP_SIGNED_MASK) || !att->crypto)
		return true;

	if (!sign->counter(&sign_cnt, sign->user_data))
		goto fail;

	if ((bt_crypto_sign_att(att->crypto, sign->key, op->pdu, 1 + length,
				sign_cnt, &((uint8_t *) op->pdu)[1 + length])))
		return true;

	util_debug(att->debug_callback, att->debug_data,
					"ATT unable to generate signature");

fail:
	free(op->pdu);
	return false;
}
示例#3
0
static bool handle_signed(struct bt_att *att, uint8_t opcode, uint8_t *pdu,
								ssize_t pdu_len)
{
	uint8_t *signature;
	uint32_t sign_cnt;
	struct sign_info *sign;

	/* Check if there is enough data for a signature */
	if (pdu_len < 2 + BT_ATT_SIGNATURE_LEN)
		goto fail;

	sign = att->remote_sign;
	if (!sign)
		goto fail;

	signature = pdu + (pdu_len - BT_ATT_SIGNATURE_LEN);
	sign_cnt = get_le32(signature);

	/* Validate counter */
	if (!sign->counter(&sign_cnt, sign->user_data))
		goto fail;

	/* Generate signature and verify it */
	if (!bt_crypto_sign_att(att->crypto, sign->key, pdu,
				pdu_len - BT_ATT_SIGNATURE_LEN, sign_cnt,
				signature))
		goto fail;

	return true;

fail:
	util_debug(att->debug_callback, att->debug_data,
			"ATT failed to verify signature: 0x%02x", opcode);

	return false;
}