Example #1
0
static void process_start(TPM_ALG_ID alg, int handle, void *response_body,
			  size_t *response_size)
{
	uint8_t *response = response_body;
	struct test_context *new_context;

	if (find_context(handle)) {
		*response = EXC_HASH_DUPLICATED_HANDLE;
		*response_size = 1;
		return;
	}

	if (!hash_test_db.max_contexts) {
		/* Check how many contexts could possible fit. */
		hash_test_db.max_contexts = shared_mem_size() /
			sizeof(struct test_context);
	}

	if (!hash_test_db.contexts)
		shared_mem_acquire(shared_mem_size(),
				   (char **)&hash_test_db.contexts);

	if (!hash_test_db.contexts ||
	    (hash_test_db.current_context_count == hash_test_db.max_contexts)) {
		*response = EXC_HASH_TOO_MANY_HANDLES;
		*response_size = 1;
		return;
	}

	new_context = hash_test_db.contexts +
		hash_test_db.current_context_count++;
	new_context->context_handle = handle;
	_cpri__StartHash(alg, 0, &new_context->hstate);
}
static int read_and_hash_chunk(int offset, int size)
{
	char *buf;
	int rv;

	if (size == 0)
		return EC_SUCCESS;

	rv = shared_mem_acquire(size, &buf);
	if (rv == EC_ERROR_BUSY) {
		/* Couldn't update hash right now; try again later */
		hook_call_deferred(vboot_hash_next_chunk, WORK_INTERVAL_US);
		return rv;
	} else if (rv != EC_SUCCESS) {
		vboot_hash_abort();
		return rv;
	}

	rv = flash_read(offset, size, buf);
	if (rv == EC_SUCCESS)
		SHA256_update(&ctx, (const uint8_t *)buf, size);
	else
		vboot_hash_abort();

	shared_mem_release(buf);
	return rv;
}
void check_rw_signature(void)
{
	struct sha256_ctx ctx;
	int good, res;
	uint8_t *hash;
	uint32_t *rsa_workbuf;

	/* Only the Read-Only firmware needs to do the signature check */
	if (system_get_image_copy() != SYSTEM_IMAGE_RO)
		return;

	/* Check if we have a RW firmware flashed */
	if (*rw_rst == 0xffffffff)
		return;

	CPRINTS("Verifying RW image...");

	/* Large buffer for RSA computation : could be re-use afterwards... */
	res = shared_mem_acquire(3 * RSANUMBYTES, (char **)&rsa_workbuf);
	if (res) {
		CPRINTS("No memory for RW verification");
		return;
	}

	/* SHA-256 Hash of the RW firmware */
	/* TODO(crosbug.com/p/44803): Do we have to hash the whole region? */
	SHA256_init(&ctx);
	SHA256_update(&ctx, (void *)CONFIG_PROGRAM_MEMORY_BASE
		      + CONFIG_RW_MEM_OFF,
		      CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE);
	hash = SHA256_final(&ctx);

	good = rsa_verify((const struct rsa_public_key *)CONFIG_RO_PUBKEY_ADDR,
			  (const uint8_t *)CONFIG_RW_SIG_ADDR,
			  hash, rsa_workbuf);
	if (good) {
		CPRINTS("RW image verified");
		/* Jump to the RW firmware */
		system_run_image_copy(SYSTEM_IMAGE_RW);
	} else {
		CPRINTS("RSA verify FAILED");
		pd_log_event(PD_EVENT_ACC_RW_FAIL, 0, 0, NULL);
		/* RW firmware is invalid : do not jump there */
		if (system_is_locked())
			system_disable_jump();
	}
	shared_mem_release(rsa_workbuf);
}
Example #4
0
static int command_flash_write(int argc, char **argv)
{
	int offset = -1;
	int size = CONFIG_FLASH_ERASE_SIZE;
	int rv;
	char *data;
	int i;

	if (flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW)
		return EC_ERROR_ACCESS_DENIED;

	rv = parse_offset_size(argc, argv, 1, &offset, &size);
	if (rv)
		return rv;

	if (size > shared_mem_size())
		size = shared_mem_size();

	/* Acquire the shared memory buffer */
	rv = shared_mem_acquire(size, &data);
	if (rv) {
		ccputs("Can't get shared mem\n");
		return rv;
	}

	/* Fill the data buffer with a pattern */
	for (i = 0; i < size; i++)
		data[i] = i;

	ccprintf("Writing %d bytes to 0x%x...\n",
		 size, offset, offset);
	rv = flash_write(offset, size, data);

	/* Free the buffer */
	shared_mem_release(data);

	return rv;
}
static int command_host_command(int argc, char **argv)
{
	struct host_cmd_handler_args args;
	char *cmd_params;
	enum ec_status res;
	char *e;
	int rv;

	/* Use shared memory for command params space */
	if (shared_mem_acquire(EC_PROTO2_MAX_PARAM_SIZE, &cmd_params)) {
		ccputs("Can't acquire shared memory buffer.\n");
		return EC_ERROR_UNKNOWN;
	}

	/* Assume no version or params unless proven otherwise */
	args.version = 0;
	args.params_size = 0;
	args.params = cmd_params;

	if (argc < 2) {
		shared_mem_release(cmd_params);
		return EC_ERROR_PARAM_COUNT;
	}

	args.command = strtoi(argv[1], &e, 0);
	if (*e) {
		shared_mem_release(cmd_params);
		return EC_ERROR_PARAM1;
	}

	if (argc > 2) {
		args.version = strtoi(argv[2], &e, 0);
		if (*e) {
			shared_mem_release(cmd_params);
			return EC_ERROR_PARAM2;
		}
	}

	if (argc > 3) {
		rv = parse_params(argv[3], cmd_params);
		if (rv < 0) {
			shared_mem_release(cmd_params);
			return EC_ERROR_PARAM3;
		}
		args.params_size = rv;
	}

	args.response = cmd_params;
	args.response_max = EC_PROTO2_MAX_PARAM_SIZE;
	args.response_size = 0;

	res = host_command_process(&args);

	if (res != EC_RES_SUCCESS)
		ccprintf("Command returned %d\n", res);
	else if (args.response_size)
		ccprintf("Response: %.*h\n", args.response_size, cmd_params);
	else
		ccprintf("Command succeeded; no response.\n");

	shared_mem_release(cmd_params);
	return EC_SUCCESS;
}