Esempio n. 1
0
static int16_t u2f_version()
{
	const char version[] = "U2F_V2";
	u2f_hid_set_len(2 + sizeof(version)-1);
	u2f_response_writeback(version, sizeof(version)-1);
	return U2F_SW_NO_ERROR;
}
Esempio n. 2
0
static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t control)
{

	uint8_t up = 1;
	uint32_t count;
	if (u2f_load_key(req->kh) != 0)
	{
		u2f_hid_set_len(2);
		return U2F_SW_WRONG_DATA;
	}
	else if (control == U2F_AUTHENTICATE_CHECK)
	{
		u2f_hid_set_len(2);
		return U2F_SW_CONDITIONS_NOT_SATISFIED;
	}

	if (u2f_get_user_feedback())
	{
		u2f_hid_set_len(2);
		return U2F_SW_CONDITIONS_NOT_SATISFIED;
	}

	count = u2f_count();

    u2f_sha256_start();
    u2f_sha256_update(req->app,32);
    u2f_sha256_update(&up,1);
    u2f_sha256_update((uint8_t *)&count,4);
    u2f_sha256_update(req->chal,32);

    u2f_sha256_finish();

    if (u2f_ecdsa_sign((uint8_t*)req, req->kh) == -1)
	{
    	return U2F_SW_WRONG_DATA;
	}

    u2f_hid_set_len(7 + get_signature_length((uint8_t*)req));

    u2f_response_writeback(&up,1);
    u2f_response_writeback((uint8_t *)&count,4);
    dump_signature_der((uint8_t*)req);

	return U2F_SW_NO_ERROR;
}
Esempio n. 3
0
static int16_t u2f_register(struct u2f_register_request * req)
{
    uint8_t i[] = {0x0,U2F_EC_FMT_UNCOMPRESSED};

    uint8_t key_handle[U2F_KEY_HANDLE_SIZE];
    uint8_t pubkey[64];


    const uint16_t attest_size = u2f_attestation_cert_size();

    if (u2f_get_user_feedback())
    {
        return U2F_SW_CONDITIONS_NOT_SATISFIED;
    }

    if ( u2f_new_keypair(key_handle, pubkey) == -1)
    {
    	return U2F_SW_CONDITIONS_NOT_SATISFIED;
    }

    u2f_sha256_start();
    u2f_sha256_update(i,1);
    u2f_sha256_update(req->app,32);

    u2f_sha256_update(req->chal,32);

    u2f_sha256_update(key_handle,U2F_KEY_HANDLE_SIZE);
    u2f_sha256_update(i+1,1);
    u2f_sha256_update(pubkey,64);
    u2f_sha256_finish();
    
    if (u2f_ecdsa_sign((uint8_t*)req, U2F_ATTESTATION_HANDLE) == -1)
	{
    	return U2F_SW_WRONG_DATA;
	}

    u2f_hid_set_len(69 + get_signature_length((uint8_t*)req) + U2F_KEY_HANDLE_SIZE + u2f_attestation_cert_size());
    i[0] = 0x5;
    u2f_response_writeback(i,2);
    u2f_response_writeback(pubkey,64);
    i[0] = U2F_KEY_HANDLE_SIZE;
    u2f_response_writeback(i,1);
    u2f_response_writeback(key_handle,U2F_KEY_HANDLE_SIZE);

    u2f_response_writeback_progmem(u2f_get_attestation_cert(),u2f_attestation_cert_size());

    dump_signature_der((uint8_t*)req);


    return U2F_SW_NO_ERROR;
}
Esempio n. 4
0
static void hid_u2f_parse(struct u2f_hid_msg* req)
{

	uint16_t len = 0;
	uint8_t secs;
	struct u2f_hid_init_response * init_res = appdata.tmp;

	switch(hid_layer.current_cmd)
	{
		case U2FHID_INIT:
			if (U2FHID_LEN(req) != 8)
			{
				stamp_error(hid_layer.current_cid, ERR_INVALID_LEN);
				goto fail;
			}
			u2f_hid_set_len(17);

			if (hid_layer.current_cid == 0)
			{
				u2f_prints("out of cid's\r\n");
				set_app_error(ERROR_OUT_OF_CIDS);
				goto fail;
			}

			init_res->cid = get_new_cid();
			init_res->version_id = 1;
			init_res->version_major = 1;
			init_res->version_minor = 0;
			init_res->version_build = 0;
			init_res->cflags = 0;

			// write back the same data nonce
			u2f_hid_writeback(req->pkt.init.payload, 8);
			u2f_hid_writeback((uint8_t *)init_res, 9);
			u2f_hid_flush();
			hid_layer.current_cid = init_res->cid;

			break;
		case U2FHID_MSG:

			if (U2FHID_LEN(req) < 4)
			{
				stamp_error(hid_layer.current_cid, ERR_INVALID_LEN);
				u2f_prints("invalid len msg\r\n");
				goto fail;
			}
			// buffer 2 payloads (120 bytes) to get full U2F message
			// assuming key handle is < 45 bytes
			//		7 bytes for apdu header
			//		7 + 66 bytes + key handle for authenticate message
			//      7 + 64 for register message
			if (hid_layer.bytes_buffered == 0)
			{
				start_buffering(req);
				if (hid_layer.bytes_buffered >= U2FHID_LEN(req))
				{
					u2f_request((struct u2f_request_apdu *)hid_layer.buffer);
				}
			}
			else
			{
				buffer_request(req);
				if (hid_layer.bytes_buffered >= hid_layer.req_len)
				{
					u2f_request((struct u2f_request_apdu *)hid_layer.buffer);
				}
			}


			break;
		case U2FHID_PING:

			//u2f_prints("U2F PING\r\n");

			if (!u2f_hid_busy())
			{
				u2f_hid_set_len(U2FHID_LEN(req));
				u2f_hid_writeback(req->pkt.init.payload, MIN(hid_layer.res_len, U2FHID_INIT_PAYLOAD_SIZE));
			}
			else
			{
				u2f_hid_writeback(req->pkt.cont.payload, MIN(hid_layer.res_len - hid_layer.bytes_written, U2FHID_CONT_PAYLOAD_SIZE));
			}

			if (hid_layer.res_len == hid_layer.bytes_written) u2f_hid_flush();
			break;

		case U2FHID_WINK:
			if (U2FHID_LEN(req) != 0)
			{
				// this one is safe
				stamp_error(hid_layer.current_cid, ERR_INVALID_LEN);
			}
			u2f_hid_set_len(0);
			u2f_hid_writeback(NULL, 0);
			u2f_hid_flush();
			app_wink(U2F_COLOR_WINK);
			break;
		case U2FHID_LOCK:

			secs = req->pkt.init.payload[0];
			if (secs > 10)
			{
				stamp_error(hid_layer.current_cid, ERR_INVALID_PAR);
			}
			else
			{
				_hid_lock_cid = hid_layer.current_cid;
				_hid_lockt = get_ms() + 1000 * secs;
				u2f_hid_set_len(0);
				u2f_hid_writeback(NULL, 0);
				u2f_hid_flush();
			}

			break;
		default:
			set_app_error(ERROR_HID_INVALID_CMD);
			stamp_error(hid_layer.current_cid, ERR_INVALID_CMD);
	}

	return;

	fail:
		u2f_prints("U2F HID FAIL\r\n");
	return;
}
Esempio n. 5
0
// return 0 if finished
// return 1 if expecting more cont packets
static uint8_t hid_u2f_parse(struct u2f_hid_msg* req)
{
	uint16_t len = 0;
	uint8_t secs;
	struct u2f_hid_init_response * init_res = appdata.tmp;

	switch(hid_layer.current_cmd)
	{
		case U2FHID_INIT:
			if (U2FHID_LEN(req) != 8)
			{
				stamp_error(hid_layer.current_cid, ERR_INVALID_LEN);
				goto fail;
			}
			u2f_hid_set_len(17);


			if (hid_layer.current_cid == U2FHID_BROADCAST)
			{
				if (hid_layer.current_cid == 0)
				{
					set_app_error(ERROR_OUT_OF_CIDS);
					goto fail;
				}
				init_res->cid = get_new_cid();
			}
			else
			{
				init_res->cid = hid_layer.current_cid;
			}
			init_res->version_id = 2;
			init_res->version_major = 2;
			init_res->version_minor = 0;
			init_res->version_build = 0;

#ifdef U2F_SUPPORT_WINK && CAPABILITY_LOCK
			init_res->cflags = CAPABILITY_WINK | CAPABILITY_LOCK;
#elif U2F_SUPPORT_WINK
			init_res->cflags = CAPABILITY_WINK;
#elif CAPABILITY_LOCK
			init_res->cflags = CAPABILITY_LOCK;
#else
			init_res->cflags = 0;
#endif

			// write back the same data nonce
			u2f_hid_writeback(req->pkt.init.payload, 8);
			u2f_hid_writeback((uint8_t *)init_res, 9);
			u2f_hid_flush();

			hid_layer.current_cid = init_res->cid;



			break;
		case U2FHID_MSG:

			if (U2FHID_LEN(req) < 4)
			{
				stamp_error(hid_layer.current_cid, ERR_INVALID_LEN);
				goto fail;
			}
			// buffer 2 payloads (120 bytes) to get full U2F message
			// assuming key handle is < 45 bytes
			//		7 bytes for apdu header
			//		7 + 66 bytes + key handle for authenticate message
			//      7 + 64 for register message
			if (hid_layer.bytes_buffered == 0)
			{
				start_buffering(req);
				if (hid_layer.bytes_buffered >= U2FHID_LEN(req))
				{
					u2f_request((struct u2f_request_apdu *)hid_layer.buffer);
				}
			}
			else
			{
				buffer_request(req);
				if (hid_layer.bytes_buffered >= hid_layer.req_len)
				{
					u2f_request((struct u2f_request_apdu *)hid_layer.buffer);
				}
			}


			break;
		case U2FHID_PING:


			if (hid_layer.bytes_buffered == 0)
			{
				start_buffering(req);
				u2f_hid_set_len(U2FHID_LEN(req));
				if (hid_layer.bytes_buffered >= U2FHID_LEN(req))
				{
					u2f_hid_writeback(hid_layer.buffer,hid_layer.bytes_buffered);
					u2f_hid_flush();
				}
				else
				{
					return 1;
				}
			}
			else
			{
				if (hid_layer.bytes_buffered + U2FHID_CONT_PAYLOAD_SIZE > BUFFER_SIZE)
				{
					u2f_hid_writeback(hid_layer.buffer,hid_layer.bytes_buffered);
					hid_layer.bytes_buffered = 0;

				}

				buffer_request(req);
				if (hid_layer.bytes_buffered + hid_layer.bytes_written >= hid_layer.req_len)
				{
					u2f_hid_writeback(hid_layer.buffer,hid_layer.bytes_buffered);
					u2f_hid_flush();
				}
				else
				{
					return 1;
				}
			}


			break;
#ifdef U2F_SUPPORT_WINK
		case U2FHID_WINK:
			if (U2FHID_LEN(req) != 0)
			{
				// this one is safe
				stamp_error(hid_layer.current_cid, ERR_INVALID_LEN);
			}
			u2f_hid_set_len(0);
			u2f_hid_writeback(NULL, 0);
			u2f_hid_flush();
			app_wink(U2F_COLOR_WINK);
			break;
#endif
#ifdef U2F_SUPPORT_HID_LOCK
		case U2FHID_LOCK:

			secs = req->pkt.init.payload[0];
			if (secs > 10)
			{
				stamp_error(hid_layer.current_cid, ERR_INVALID_PAR);
			}
			else
			{
				if (secs)
				{
					_hid_lock_cid = hid_layer.current_cid;
					_hid_lockt = get_ms() + 1000 * secs;

				}
				else
				{
					_hid_lockt = get_ms();
					_hid_lock_cid = 0;
				}
				hid_layer.current_cmd = U2FHID_LOCK;
				u2f_hid_set_len(0);
				u2f_hid_writeback(NULL, 0);
				u2f_hid_flush();
			}
			break;
#endif
		default:
			set_app_error(ERROR_HID_INVALID_CMD);
			stamp_error(hid_layer.current_cid, ERR_INVALID_CMD);
			u2f_printb("invalid cmd: ",1,hid_layer.current_cmd);
	}

	return u2f_hid_busy();

	fail:
		u2f_prints("U2F HID FAIL\r\n");
	return 0;
}
Esempio n. 6
0
void set_response_length(uint16_t len)
{
	u2f_hid_set_len(len);
}