예제 #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;
}
예제 #2
0
// bad if this gets interrupted
int8_t u2f_new_keypair(uint8_t * handle, uint8_t * pubkey)
{
	struct atecc_response res;
	struct key_handle k;
	uint8_t keyslot = key_store.num_issued;
	if (keyslot > U2F_NUM_KEYS-1)
	{
		//app_wink(U2F_DEFAULT_COLOR_WINK_OUT_OF_SPACE);
		return -1;
	}
	//watchdog();
	atecc_send_recv(ATECC_CMD_GENKEY,
			ATECC_GENKEY_PRIVATE, keyslot, NULL, 0,
			appdata.tmp, sizeof(appdata.tmp), &res);

	memmove(pubkey, res.buf, 64);

	eeprom_read(U2F_KEY_ADDR(keyslot), (uint8_t* )&k, U2F_KEY_HANDLE_SIZE);
	if (k.index-1 != keyslot)
	{

		k.index = keyslot;
		set_app_error(ERROR_BAD_KEY_STORE);
	}
	memmove(handle, &k, U2F_KEY_HANDLE_SIZE);
	key_store.num_issued++;
	flush_key_store();

	return 0;
}
예제 #3
0
void u2f_sha256_start()
{
	shaoffset = 0;
	atecc_send_recv(ATECC_CMD_SHA,
			ATECC_SHA_START, 0,NULL,0,
			appdata.tmp, sizeof(appdata.tmp), NULL);
}
예제 #4
0
uint32_t u2f_count()
{
	struct atecc_response res;
	atecc_send_recv(ATECC_CMD_COUNTER,
			ATECC_COUNTER_INC, ATECC_COUNTER0,NULL,0,
			appdata.tmp, sizeof(appdata.tmp), &res);
	return *(uint32_t*)res.buf;
}
예제 #5
0
void u2f_init()
{
	int8_t i,ec;
	uint8_t * clear = 0;
	struct atecc_response res;
	
	if (is_locked(appdata.tmp)) {	
		eeprom_read(U2F_EEPROM_CONFIG, (uint8_t* )&key_store, sizeof(struct key_storage_header));

		// initialize key handles
		if (key_store.num_keys != U2F_NUM_KEYS)
		{
			//watchdog();
	
			for (i=0; i < U2F_NUM_KEYS; i++)
			{
				//watchdog();
				ec = atecc_send_recv(ATECC_CMD_RNG,ATECC_RNG_P1,ATECC_RNG_P2,
								NULL, 0,
								appdata.tmp,
								sizeof(appdata.tmp), &res);
				if (ec != 0)
				{
					//u2f_printb("atecc_send_recv failed ",2,i,-ec);
	
					// erase eeprom
					//eeprom_erase(U2F_EEPROM_CONFIG);
	
					// erase ram
					//for (i=0; i<0x400;i++)
					//{
					//	*(clear++) = 0x0;
					//}
					// reset
					//reboot();
					return;
				}
				res.buf[0] = i+1;

				eeprom_write(U2F_KEYS_ADDR + i * U2F_KEY_HANDLE_SIZE,
							 res.buf, U2F_KEY_HANDLE_SIZE);
			}

			key_store.num_keys = U2F_NUM_KEYS;
			key_store.valid_keys = 0;
			key_store.num_issued = 0;
			flush_key_store();
		}
	}
}
예제 #6
0
void u2f_sha256_update(uint8_t * buf, uint8_t len)
{
	uint8_t i = 0;
	//watchdog();
	while(len--)
	{
		shabuf[shaoffset++] = *buf++;
		if (shaoffset == 64)
		{
			atecc_send_recv(ATECC_CMD_SHA,
					ATECC_SHA_UPDATE, 64,shabuf,64,
					appdata.tmp, sizeof(appdata.tmp), NULL);
			shaoffset = 0;
		}
	}
}
예제 #7
0
int8_t u2f_ecdsa_sign(uint8_t * dest, uint8_t * handle)
{
	struct atecc_response res;
	struct key_handle k;
	uint16_t keyslot = (uint16_t)((struct key_handle *)handle)->index;
	//watchdog();
	if (keyslot > U2F_NUM_KEYS)
	{
		return -1;
	}
	if (keyslot == 0)
	{
		keyslot = U2F_ATTESTATION_KEY_SLOT;
	}
	else
	{
		keyslot--;
	}

	atecc_send_recv(ATECC_CMD_SIGN,
			ATECC_SIGN_EXTERNAL, keyslot, NULL, 0,
			appdata.tmp, sizeof(appdata.tmp), &res);

	if (keyslot != U2F_ATTESTATION_KEY_SLOT)
	{
		eeprom_read(U2F_KEY_ADDR(keyslot), (uint8_t* )&k, U2F_KEY_HANDLE_SIZE);

		if (key_same((struct key_handle *)handle, &k) != 0)
		{
			return -1;
		}
	}

	memmove(dest, res.buf, 64);

	return 0;
}
예제 #8
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;
}
예제 #9
0
void u2f_sha256_finish()
{
	atecc_send_recv(ATECC_CMD_SHA,
			ATECC_SHA_END, shaoffset,shabuf,shaoffset,
			shabuf, sizeof(shabuf), &res_digest);
}