Example #1
0
uint8_t custom_command(struct u2f_hid_msg * msg)
{
	struct atecc_response res;
	uint8_t ec;

	if (msg->cid != U2FHID_BROADCAST) return 0;

	switch(msg->pkt.init.cmd)
	{
		case U2F_CUSTOM_GET_RNG:
			if (atecc_send_recv(ATECC_CMD_RNG,ATECC_RNG_P1,ATECC_RNG_P2,
				NULL, 0,
				appdata.tmp,
				sizeof(appdata.tmp), &res) == 0 )
			{
				memmove(msg->pkt.init.payload, res.buf, 32);
				U2FHID_SET_LEN(msg, 32);
				usb_write((uint8_t*)msg, 64);
			}
			else
			{
				U2FHID_SET_LEN(msg, 0);
				usb_write((uint8_t*)msg, 64);
			}

			break;
		case U2F_CUSTOM_SEED_RNG:
			ec = atecc_send_recv(ATECC_CMD_NONCE,ATECC_NONCE_RNG_UPDATE,0,
							msg->pkt.init.payload, 20,
							appdata.tmp,
							sizeof(appdata.tmp), &res);
			U2FHID_SET_LEN(msg, 1);
			msg->pkt.init.payload[0] = ec == 0 ? 1 : 0;
			usb_write((uint8_t*)msg, 64);
			break;
		case U2F_CUSTOM_WIPE_KEYS:

			U2FHID_SET_LEN(msg, 1);
			ec=u2f_wipe_keys();
			msg->pkt.init.payload[0] = ec == 0 ? 1 : 0;
			usb_write((uint8_t*)msg, 64);

			break;

		case U2F_CUSTOM_WINK:

			app_wink(U2F_COLOR_WINK);

			break;

		default:
			return 0;
	}
	return 1;
}
Example #2
0
// Buffers data to a 64 byte buffer before writing it while
// handling U2F HID sequencing
void u2f_hid_writeback(uint8_t * payload, uint16_t len)
{
	struct u2f_hid_msg * r = (struct u2f_hid_response *) _hid_pkt;
	_hid_in_session = 1;
	if (_hid_offset == 0)
	{
		r->cid = hid_layer.current_cid;
		if (!_hid_seq)
		{
			r->pkt.init.cmd = hid_layer.current_cmd;
			U2FHID_SET_LEN(r, hid_layer.res_len);
			_hid_offset = 7;
		}
		else
		{
			r->pkt.cont.seq = _hid_seq - 1;
			_hid_offset = 5;
			if (_hid_seq-1 > 127)
			{
				set_app_error(ERROR_SEQ_EXCEEDED);
				return;
			}
		}
	}
	while(len--)
	{
		_hid_pkt[_hid_offset++] = *payload++;
		hid_layer.bytes_written++;
		if (_hid_offset == HID_PACKET_SIZE)
		{
			_hid_offset = 0;
			_hid_seq++;

			usb_write(_hid_pkt, HID_PACKET_SIZE);
			memset(_hid_pkt, 0, HID_PACKET_SIZE);

			if (len)
			{
				u2f_hid_writeback(payload, len);
				return;
			}
			else break;
		}
	}

}
Example #3
0
uint8_t custom_command(struct u2f_hid_msg * msg)
{
	struct atecc_response res;
	struct u2f_hid_msg * reply = (struct u2f_hid_msg *)appdata.tmp;
	uint8_t ec;

	if (msg->cid != U2FHID_BROADCAST) return 0;

	switch(msg->pkt.init.cmd)
	{
		case U2F_CUSTOM_GET_SERIAL_NUMBER:
			if (atecc_send_recv(ATECC_CMD_READ, ATECC_RW_CONFIG | ATECC_RW_EXT, 0,
				NULL, 0, reply->pkt.init.payload, sizeof(reply->pkt.init.payload), &res) == 0 )
			{
				if (res.len > 15)
					res.len = 15;
				reply->cid = msg->cid;
				reply->pkt.init.cmd = msg->pkt.init.cmd;
				U2FHID_SET_LEN(reply, res.len);
				usb_write((uint8_t*)reply, 64);
			}
			else
			{
				reply->cid = msg->cid;
				reply->pkt.init.cmd = msg->pkt.init.cmd;
				U2FHID_SET_LEN(reply, 0);
				usb_write((uint8_t*)reply, 64);
			}
			break;
		case U2F_CUSTOM_GET_CONFIG:
			if (atecc_send_recv(ATECC_CMD_READ, ATECC_RW_CONFIG | ATECC_RW_EXT,
				(msg->pkt.init.payload[0] << 8) | msg->pkt.init.payload[1], NULL, 0, 
				reply->pkt.init.payload, sizeof(reply->pkt.init.payload), &res) == 0)
			{
				if (res.len > 40)
					res.len = 40;
				reply->cid = msg->cid;
				reply->pkt.init.cmd = msg->pkt.init.cmd;
				U2FHID_SET_LEN(reply, res.len);
				usb_write((uint8_t*)reply, 64);
			}
			else
			{
				U2FHID_SET_LEN(msg, 0);
				usb_write((uint8_t*)msg, 64);
			}
			break;
		case U2F_CUSTOM_INIT_CONFIG:
			atecc_setup_config();
			U2FHID_SET_LEN(msg, 0);
			usb_write((uint8_t*)msg, 64);
			break;
		case U2F_CUSTOM_LOCK_CONFIG:
			if (is_locked(appdata.tmp)) {
				msg->pkt.init.payload[0] = 0xff;
				U2FHID_SET_LEN(msg, 1);
				usb_write((uint8_t*)msg, 64);
			}
			else if (atecc_send_recv(ATECC_CMD_LOCK, ATECC_LOCK_CONFIG,
				(msg->pkt.init.payload[0] << 8) | msg->pkt.init.payload[1], NULL, 0, 
				appdata.tmp, sizeof(appdata.tmp), NULL))
			{
				msg->pkt.init.payload[0] = 0xfe;
				U2FHID_SET_LEN(msg, 1);
				usb_write((uint8_t*)msg, 64);
			}
			else
			{
				msg->pkt.init.payload[0] = 0x00;
				U2FHID_SET_LEN(msg, 1);
				usb_write((uint8_t*)msg, 64);
			}
			break;
		case U2F_CUSTOM_GEN_ATT_KEY:
			if (atecc_send_recv(ATECC_CMD_GENKEY, ATECC_GENKEY_PRIVATE, U2F_ATTESTATION_KEY_SLOT,
				NULL, 0, appdata.tmp, sizeof(appdata.tmp), &res) == 0 && res.len <= 64)
			{
				U2FHID_SET_LEN(msg, res.len - 1);
				memmove(msg->pkt.init.payload, res.buf, res.len - 1);
				usb_write((uint8_t*)msg, 64);
			}
			else
			{
				U2FHID_SET_LEN(msg, 0);
				usb_write((uint8_t*)msg, 64);
			}
			break;
			/*
		case U2F_CUSTOM_GET_RNG:
			if (atecc_send_recv(ATECC_CMD_RNG,ATECC_RNG_P1,ATECC_RNG_P2,
				NULL, 0,
				appdata.tmp,
				sizeof(appdata.tmp), &res) == 0 )
			{
				memmove(msg->pkt.init.payload, res.buf, 32);
				U2FHID_SET_LEN(msg, 32);
				usb_write((uint8_t*)msg, 64);
			}
			else
			{
				U2FHID_SET_LEN(msg, 0);
				usb_write((uint8_t*)msg, 64);
			}

			break;
		case U2F_CUSTOM_SEED_RNG:
			ec = atecc_send_recv(ATECC_CMD_NONCE,ATECC_NONCE_RNG_UPDATE,0,
							msg->pkt.init.payload, 20,
							appdata.tmp,
							sizeof(appdata.tmp), &res);
			U2FHID_SET_LEN(msg, 1);
			msg->pkt.init.payload[0] = ec == 0 ? 1 : 0;
			usb_write((uint8_t*)msg, 64);
			break;
			*/
		case U2F_CUSTOM_WIPE_KEYS:

			U2FHID_SET_LEN(msg, 1);
			ec=u2f_wipe_keys();
			msg->pkt.init.payload[0] = ec == 0 ? 1 : 0;
			usb_write((uint8_t*)msg, 64);

			break;
			
		case U2F_CUSTOM_ENTER_BOOTLOADER:
			USB_Detach();
			enterBootloader();
			break;
		case U2F_CUSTOM_INC_COUNT:
			if (atecc_send_recv(ATECC_CMD_COUNTER,
							ATECC_COUNTER_INC, ATECC_COUNTER0,NULL,0,
							appdata.tmp, sizeof(appdata.tmp), &res) == 0)
			{
				memmove(msg->pkt.init.payload, res.buf, res.len);
				U2FHID_SET_LEN(msg, res.len);
				usb_write((uint8_t*)msg, 64);
			}
			else
			{
				U2FHID_SET_LEN(msg, 0);
				usb_write((uint8_t*)msg, 64);
			}
			break;				
		default:
			return 0;
	}
	return 1;
}