예제 #1
0
파일: encrypted.c 프로젝트: raoy1990/linux
/*
 * encrypted_init - initialize an encrypted key
 *
 * For a new key, use a random number for both the iv and data
 * itself.  For an old key, decrypt the hex encoded data.
 */
static int encrypted_init(struct encrypted_key_payload *epayload,
			  const char *key_desc, const char *format,
			  const char *master_desc, const char *datalen,
			  const char *hex_encoded_iv)
{
	int ret = 0;

	if (format && !strcmp(format, key_format_ecryptfs)) {
		ret = valid_ecryptfs_desc(key_desc);
		if (ret < 0)
			return ret;

		ecryptfs_fill_auth_tok((struct ecryptfs_auth_tok *)epayload->payload_data,
				       key_desc);
	}

	__ekey_init(epayload, format, master_desc, datalen);
	if (!hex_encoded_iv) {
		get_random_bytes(epayload->iv, ivsize);

		get_random_bytes(epayload->decrypted_data,
				 epayload->decrypted_datalen);
	} else
		ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
	return ret;
}
예제 #2
0
/*
 * encrypted_update - update the master key description
 *
 * Change the master key description for an existing encrypted key.
 * The next read will return an encrypted datablob using the new
 * master key description.
 *
 * On success, return 0. Otherwise return errno.
 */
static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
{
	struct encrypted_key_payload *epayload = key->payload.data[0];
	struct encrypted_key_payload *new_epayload;
	char *buf;
	char *new_master_desc = NULL;
	const char *format = NULL;
	size_t datalen = prep->datalen;
	int ret = 0;

	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
		return -ENOKEY;
	if (datalen <= 0 || datalen > 32767 || !prep->data)
		return -EINVAL;

	buf = kmalloc(datalen + 1, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	buf[datalen] = 0;
	memcpy(buf, prep->data, datalen);
	ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
	if (ret < 0)
		goto out;

	ret = valid_master_desc(new_master_desc, epayload->master_desc);
	if (ret < 0)
		goto out;

	new_epayload = encrypted_key_alloc(key, epayload->format,
					   new_master_desc, epayload->datalen);
	if (IS_ERR(new_epayload)) {
		ret = PTR_ERR(new_epayload);
		goto out;
	}

	__ekey_init(new_epayload, epayload->format, new_master_desc,
		    epayload->datalen);

	memcpy(new_epayload->iv, epayload->iv, ivsize);
	memcpy(new_epayload->payload_data, epayload->payload_data,
	       epayload->payload_datalen);

	rcu_assign_keypointer(key, new_epayload);
	call_rcu(&epayload->rcu, encrypted_rcu_free);
out:
	kfree(buf);
	return ret;
}