Esempio n. 1
0
static int dek_on_user_added(dek_arg_on_user_added *evt) {
	int userid = evt->userid;
	int key_arr_idx = PERSONA_KEY_ARR_IDX(userid);

	/*
	 * TODO : lock needed
	 */

	if (!dek_is_persona(userid)) {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -EFAULT;
	}

	if((evt->SDPK_Rpub.len > KEK_MAX_LEN) ||
			(evt->SDPK_Dpub.len > KEK_MAX_LEN)) {
		DEK_LOGE("Invalid args\n");
		DEK_LOGE("SDPK_Rpub.len : %d\n", evt->SDPK_Rpub.len);
		DEK_LOGE("SDPK_Dpub.len : %d\n", evt->SDPK_Dpub.len);
		return -EINVAL;
	}

	memcpy(SDPK_Rpub[key_arr_idx].buf, evt->SDPK_Rpub.buf, evt->SDPK_Rpub.len);
	SDPK_Rpub[key_arr_idx].len = evt->SDPK_Rpub.len;
	memcpy(SDPK_Dpub[key_arr_idx].buf, evt->SDPK_Dpub.buf, evt->SDPK_Dpub.len);
	SDPK_Dpub[key_arr_idx].len = evt->SDPK_Dpub.len;

#if DEK_DEBUG
	dump_all_keys(key_arr_idx);
#endif
	return 0;
}
int ecryptfs_sdp_convert_dek(struct dentry *dentry) {
	int rc = 0;
	struct inode *inode = dentry->d_inode;
	struct ecryptfs_crypt_stat *crypt_stat =
			&ecryptfs_inode_to_private(inode)->crypt_stat;
	dek_t DEK;

	rc = dek_decrypt_dek_efs(crypt_stat->userid, &crypt_stat->sdp_dek, &DEK);
	if (rc < 0) {
		DEK_LOGE("Error converting dek [DEC]; rc = [%d]\n", rc);
		goto out;
	}

	rc = dek_encrypt_dek_efs(crypt_stat->userid, &DEK,  &crypt_stat->sdp_dek);
	if (rc < 0) {
		DEK_LOGE("Error converting dek [ENC]; rc = [%d]\n", rc);
		goto out;
	}

	rc = ecryptfs_update_crypt_flag(dentry, 1);
	if (rc < 0) {
		DEK_LOGE("Error converting dek [FLAG]; rc = [%d]\n", rc);
		goto out;
	}
out:
	memset(&DEK, 0, sizeof(dek_t));
	return rc;
}
static int ecryptfs_update_crypt_flag(struct dentry *dentry, int is_sensitive)
{
	int rc = 0;
	struct inode *inode;
	struct inode *lower_inode;
	struct ecryptfs_crypt_stat *crypt_stat;
	u32 tmp_flags;

	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
	if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED))
		ecryptfs_init_crypt_stat(crypt_stat);
	inode = dentry->d_inode;
	lower_inode = ecryptfs_inode_to_lower(inode);

	mutex_lock(&crypt_stat->cs_mutex);
	rc = ecryptfs_get_lower_file(dentry, inode);
	if (rc) {
		mutex_unlock(&crypt_stat->cs_mutex);
		DEK_LOGE("ecryptfs_get_lower_file rc=%d\n", rc);
		goto out;
	}

	tmp_flags = crypt_stat->flags;
	if (is_sensitive) {
		crypt_stat->flags |= ECRYPTFS_DEK_IS_SENSITIVE;
		/*
		* Set sensirive for all the pages in the inode 
		*/
		set_sensitive_mapping_pages(inode->i_mapping, 0, -1);
	}
	else{
		crypt_stat->flags &= ~ECRYPTFS_DEK_IS_SENSITIVE;
	}

	rc = ecryptfs_write_metadata(dentry, inode);
	if (rc) {
		crypt_stat->flags = tmp_flags;
		mutex_unlock(&crypt_stat->cs_mutex);
		DEK_LOGE("ecryptfs_write_metadata rc=%d\n", rc);
		goto out;
	}

	rc = ecryptfs_write_inode_size_to_metadata(inode);
	if (rc) {
		mutex_unlock(&crypt_stat->cs_mutex);
		DEK_LOGE("Problem with "
				"ecryptfs_write_inode_size_to_metadata; "
				"rc = [%d]\n", rc);
		goto out;
	}

	ecryptfs_put_lower_file(inode);
	mutex_unlock(&crypt_stat->cs_mutex);
out:
	fsstack_copy_attr_all(inode, lower_inode);
	return rc;
}
Esempio n. 4
0
static int dek_encrypt_dek(int userid, dek_t *plainDek, dek_t *encDek) {
	int ret = 0;
	int key_arr_idx = PERSONA_KEY_ARR_IDX(userid);

	if (!dek_is_persona(userid)) {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -EFAULT;
	}
#if DEK_DEBUG
	DEK_LOGD("plainDek from user: "******"aes encrypt failed\n");
			dek_add_to_log(userid, "aes encrypt failed");
			encDek->len = 0;
		} else {
			encDek->len = plainDek->len;
			encDek->type = DEK_TYPE_AES_ENC;
		}
	} else {
#ifdef CONFIG_PUB_CRYPTO
		/*
		 * Do an asymmetric crypto
		 */
		if(SDPK_Dpub[key_arr_idx].len > 0) {
			ret = dh_encryptDEK(plainDek, encDek, &SDPK_Dpub[key_arr_idx]);
		}else{
			DEK_LOGE("SDPK_Dpub for id: %d\n", userid);
			dek_add_to_log(userid, "encrypt failed, no SDPK_Dpub");
			return -EIO;
		}
#else
		DEK_LOGE("pub crypto not supported : %d\n", userid);
		dek_add_to_log(userid, "encrypt failed, no key");
		return -EOPNOTSUPP;
#endif
	}

	if (encDek->len <= 0 || encDek->len > DEK_MAXLEN) {
		DEK_LOGE("dek_encrypt_dek, incorrect len=%d\n", encDek->len);
		zero_out((char *)encDek, sizeof(dek_t));
		return -EFAULT;
	}
#if DEK_DEBUG
	else {
		DEK_LOGD("encDek to user: ");
		dump(encDek->buf, encDek->len);
	}
#endif

	return ret;
}
int ecryptfs_get_sdp_dek(unsigned char *sig, int *sig_len, struct ecryptfs_crypt_stat *crypt_stat) 
{
	int rc = 0;
	if(crypt_stat != NULL && (crypt_stat->flags & ECRYPTFS_DEK_SDP_ENABLED)) {
		if((crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE)) {
			dek_t DEK;

#if ECRYPTFS_DEK_DEBUG
			DEK_LOGD("get_sdp_dek: sensitive, dek type: %d\n", crypt_stat->sdp_dek.type);
			ecryptfs_dumpkey(crypt_stat->userid, "sdp_dek:", crypt_stat->sdp_dek.buf, crypt_stat->sdp_dek.len);
#endif
			if (crypt_stat->sdp_dek.type != DEK_TYPE_PLAIN) {
				rc = dek_decrypt_dek_efs(crypt_stat->userid, &crypt_stat->sdp_dek, &DEK);
			} else {
				DEK_LOGE("Error, DEK already plaintext");
				rc = -1;
			}
			if (rc < 0) {
				DEK_LOGE("Error decypting dek; rc = [%d]\n", rc);
				rc = -1;
				/*
				 * TODO : olic.moon
				 * When we return -1 here, ECRYPTFS_ENCRYPTED is somehow gone
				 * later. then it occurs error while updating EDEK
				 */
				rc = 0;
				memset(&DEK, 0, sizeof(dek_t));
				goto out;
			}
#if ECRYPTFS_DEK_DEBUG
			ecryptfs_dumpkey(crypt_stat->userid, "decrypted:", DEK.buf, DEK.len);
			DEK_LOGD("decrypted key size is %d\n", DEK.len);
#endif
			memcpy(sig, DEK.buf, DEK.len);
			(*sig_len) = DEK.len;
			memset(&DEK, 0, sizeof(dek_t));
		} else {
#if ECRYPTFS_DEK_DEBUG
			DEK_LOGD("file is not sensitive\n");
#endif
		}
	}
out:
	if(!rc)
		sdp_mm_set_process_sensitive(current->pid);

	return rc;
}
Esempio n. 6
0
static int dek_on_user_removed(dek_arg_on_user_removed *evt) {
	int userid = evt->userid;
	int key_arr_idx;

	/*
	 * TODO : lock needed
	 */

	if (!dek_is_persona(userid)) {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -EFAULT;
	}
	key_arr_idx = PERSONA_KEY_ARR_IDX(userid);

	zero_out((char *)&SDPK_sym[key_arr_idx], sizeof(kek_t));
	zero_out((char *)&SDPK_Rpub[key_arr_idx], sizeof(kek_t));
	zero_out((char *)&SDPK_Rpri[key_arr_idx], sizeof(kek_t));
	zero_out((char *)&SDPK_Dpub[key_arr_idx], sizeof(kek_t));
	zero_out((char *)&SDPK_Dpri[key_arr_idx], sizeof(kek_t));
    zero_out((char *)&SDPK_EDpub[key_arr_idx], sizeof(kek_t));
    zero_out((char *)&SDPK_EDpri[key_arr_idx], sizeof(kek_t));

#ifdef CONFIG_SDP_KEY_DUMP
    if(get_sdp_sysfs_key_dump()) {
        dump_all_keys(key_arr_idx);
    }
#endif

	dek_aes_key_free(sdp_tfm[key_arr_idx]);
	sdp_tfm[key_arr_idx] = NULL;

	return 0;
}
Esempio n. 7
0
static int dek_is_persona(int userid) {
	if ((userid < 100) || (userid > 100+SDP_MAX_USERS-1)) {
		DEK_LOGE("invalid persona id: %d\n", userid);
		dek_add_to_log(userid, "Invalid persona id");
		return 0;
	}
	return 1;
}
Esempio n. 8
0
static long dek_ioctl_kek(struct file *file,
		unsigned int cmd, unsigned long arg)
{
	unsigned int minor;
	if(!is_container_app() && !is_root()) {
		DEK_LOGE("Current process can't access kek device\n");
		DEK_LOGE("Current process info :: "
				"uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u "
				"fsuid=%u fsgid=%u\n",
				current_uid(), current_gid(), current_euid(),
				current_egid(), current_suid(), current_sgid(),
				current_fsuid(), current_fsgid());
		dek_add_to_log(000, "Access denied to kek device");
		return -EACCES;
	}

	minor = iminor(file->f_path.dentry->d_inode);
	return dek_do_ioctl_kek(minor, cmd, arg);
}
Esempio n. 9
0
int dek_is_persona_locked(int userid) {
	int key_arr_idx = PERSONA_KEY_ARR_IDX(userid);
	if (dek_is_persona(userid)) {
		if (sdp_tfm[key_arr_idx] != NULL) {
			return 0;
		} else {
			return 1;
		}
	} else {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -1;
	}
}
Esempio n. 10
0
static int zero_out(char *buf, unsigned int len) {
	char zero = 0;
	int retry_cnt = 3;
	int i;

	retry:
	if(retry_cnt > 0) {
		memset((void *)buf, zero, len);
		for (i = 0; i < len; ++i) {
			zero |= buf[i];
			if (zero) {
				DEK_LOGE("the memory was not properly zeroed\n");
				retry_cnt--;
				goto retry;
			}
		}
	} else {
		DEK_LOGE("FATAL : can't zero out!!\n");
		return -1;
	}

	return 0;
}
Esempio n. 11
0
static int dek_on_boot(dek_arg_on_boot *evt) {
	int ret = 0;
	int userid = evt->userid;
	int key_arr_idx;

	/*
	 * TODO : lock needed
	 */

	if (!dek_is_persona(userid)) {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -EFAULT;
	}
	key_arr_idx = PERSONA_KEY_ARR_IDX(userid);

	if((evt->SDPK_Rpub.len > KEK_MAX_LEN) ||
	        (evt->SDPK_Dpub.len > KEK_MAX_LEN) ||
	        (evt->SDPK_EDpub.len > KEK_MAX_LEN)) {
	    DEK_LOGE("Invalid args\n");
	    DEK_LOGE("SDPK_Rpub.len : %d\n", evt->SDPK_Rpub.len);
	    DEK_LOGE("SDPK_Dpub.len : %d\n", evt->SDPK_Dpub.len);
	    DEK_LOGE("SDPK_EDpub.len : %d\n", evt->SDPK_EDpub.len);
	    return -EINVAL;
	}

    copy_kek(&SDPK_Rpub[key_arr_idx], &evt->SDPK_Rpub, KEK_TYPE_RSA_PUB);
    copy_kek(&SDPK_Dpub[key_arr_idx], &evt->SDPK_Dpub, KEK_TYPE_DH_PUB);
    copy_kek(&SDPK_EDpub[key_arr_idx], &evt->SDPK_EDpub, KEK_TYPE_ECDH256_PUB);

#ifdef CONFIG_SDP_KEY_DUMP
    if(get_sdp_sysfs_key_dump()) {
        dump_all_keys(key_arr_idx);
    }
#endif

	return ret;
}
Esempio n. 12
0
static ssize_t dek_read_log(struct file *file, char __user *buffer, size_t len, loff_t *off)
{
	int ret = 0;
	struct log_struct *tmp = NULL;
	char log_buf[256];
	int log_buf_len;

	// build error
	//DEK_LOGD("dek_read_log, len=%d, off=%ld, log_count=%d\n",
	//		len, (long int)*off, log_count);

	if (list_empty(&log_buffer.list)) {
		DEK_LOGD("process %i (%s) going to sleep\n",
				current->pid, current->comm);
		flag = 0;
		wait_event_interruptible(wq, flag != 0);

	}
	flag = 0;

	spin_lock(&log_buffer.list_lock);
	if (!list_empty(&log_buffer.list)) {
		tmp = list_first_entry(&log_buffer.list, struct log_struct, list);
		if (tmp != NULL) {
			memcpy(&log_buf, tmp->buf, tmp->len);
			log_buf_len = tmp->len;
			list_del(&tmp->list);
			kfree(tmp);
			log_count--;
			spin_unlock(&log_buffer.list_lock);

			ret = copy_to_user(buffer, log_buf, log_buf_len);
			if (ret) {
				DEK_LOGE("dek_read_log, copy_to_user fail, ret=%d, len=%d\n",
						ret, log_buf_len);
				return -EFAULT;
			}
			len = log_buf_len;
			*off = log_buf_len;

		} else {
			DEK_LOGD("dek_read_log, tmp == null\n");
			len = 0;
			spin_unlock(&log_buffer.list_lock);
		}
	} else {
Esempio n. 13
0
/**
 * ecryptfs_interpose
 * @lower_dentry: Existing dentry in the lower filesystem
 * @dentry: ecryptfs' dentry
 * @sb: ecryptfs's super_block
 *
 * Interposes upper and lower dentries.
 *
 * Returns zero on success; non-zero otherwise
 */
static int ecryptfs_interpose(struct dentry *lower_dentry,
			      struct dentry *dentry, struct super_block *sb)
{
	struct inode *inode = ecryptfs_get_inode(lower_dentry->d_inode, sb);

	if (IS_ERR(inode))
		return PTR_ERR(inode);

	d_instantiate(dentry, inode);
	if(d_unhashed(dentry))
		d_rehash(dentry);

#ifdef CONFIG_SDP
	if(S_ISDIR(inode->i_mode) && dentry) {
		if(IS_UNDER_ROOT(dentry)) {
			struct ecryptfs_mount_crypt_stat *mount_crypt_stat  =
					&ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat;
			int engineid;
			printk("Creating a directoy under root directory of current partition.\n");

			if(is_chamber_directory(mount_crypt_stat, dentry->d_name.name, &engineid)) {
				printk("This is a chamber directory engine[%d]\n", engineid);
				set_chamber_flag(engineid, inode);
			}
		} else if(IS_SENSITIVE_DENTRY(dentry->d_parent)) {
			/*
			 * When parent directory is sensitive
			 */
			struct ecryptfs_crypt_stat *crypt_stat =
					&ecryptfs_inode_to_private(inode)->crypt_stat;
			struct ecryptfs_crypt_stat *parent_crypt_stat =
					&ecryptfs_inode_to_private(dentry->d_parent->d_inode)->crypt_stat;

			//TODO : remove this log
			DEK_LOGE("Parent %s[id:%d] is sensitive. so this directory is sensitive too\n",
					dentry->d_parent->d_name.name, parent_crypt_stat->engine_id);
			crypt_stat->flags |= ECRYPTFS_DEK_IS_SENSITIVE;
			crypt_stat->engine_id = parent_crypt_stat->engine_id;
		}
	}
#endif

	return 0;
}
Esempio n. 14
0
static int dek_on_device_unlocked(dek_arg_on_device_unlocked *evt) {
	int userid = evt->userid;
	int key_arr_idx;

	/*
	 * TODO : lock needed
	 */

	if (!dek_is_persona(userid)) {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -EFAULT;
	}
	key_arr_idx = PERSONA_KEY_ARR_IDX(userid);

	if((evt->SDPK_sym.len > KEK_MAX_LEN) ||
            (evt->SDPK_Rpri.len > KEK_MAX_LEN) ||
            (evt->SDPK_Dpri.len > KEK_MAX_LEN) ||
			(evt->SDPK_EDpri.len > KEK_MAX_LEN)) {
		DEK_LOGE("%s Invalid args\n", __func__);
		DEK_LOGE("SDPK_sym.len : %d\n", evt->SDPK_sym.len);
		DEK_LOGE("SDPK_Rpri.len : %d\n", evt->SDPK_Rpri.len);
        DEK_LOGE("SDPK_Dpri.len : %d\n", evt->SDPK_Dpri.len);
        DEK_LOGE("SDPK_EDpri.len : %d\n", evt->SDPK_EDpri.len);
		return -EINVAL;
	}

    copy_kek(&SDPK_Rpri[key_arr_idx], &evt->SDPK_Rpri, KEK_TYPE_RSA_PRIV);
    copy_kek(&SDPK_Dpri[key_arr_idx], &evt->SDPK_Dpri, KEK_TYPE_DH_PRIV);
    copy_kek(&SDPK_EDpri[key_arr_idx], &evt->SDPK_EDpri, KEK_TYPE_ECDH256_PRIV);
    copy_kek(&SDPK_sym[key_arr_idx], &evt->SDPK_sym, KEK_TYPE_SYM);

	sdp_tfm[key_arr_idx] = dek_aes_key_setup(evt->SDPK_sym.buf, evt->SDPK_sym.len);
	if (IS_ERR(sdp_tfm[key_arr_idx])) {
		DEK_LOGE("error setting up key\n");
		dek_add_to_log(evt->userid, "error setting up key");
		sdp_tfm[key_arr_idx] = NULL;
	}

#ifdef CONFIG_SDP_KEY_DUMP
	if(get_sdp_sysfs_key_dump()) {
	    dump_all_keys(key_arr_idx);
	}
#endif

	return 0;
}
Esempio n. 15
0
int dek_generate_dek(int userid, dek_t *newDek) {
	if (!dek_is_persona(userid)) {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -EFAULT;
	}

	newDek->len = DEK_LEN;
	get_random_bytes(newDek->buf, newDek->len);

	if (newDek->len <= 0 || newDek->len > DEK_LEN) {
		zero_out((char *)newDek, sizeof(dek_t));
		return -EFAULT;
	}
#if DEK_DEBUG
	else {
		DEK_LOGD("DEK: ");
		dek_dump(newDek->buf, newDek->len);
	}
#endif

	return 0;
}
Esempio n. 16
0
static int dek_on_device_locked(dek_arg_on_device_locked *evt) {
	int userid = evt->userid;
	int key_arr_idx = PERSONA_KEY_ARR_IDX(userid);

	if (!dek_is_persona(userid)) {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -EFAULT;
	}

	dek_aes_key_free(sdp_tfm[key_arr_idx]);
	sdp_tfm[key_arr_idx] = NULL;

	zero_out((char *)&SDPK_sym[key_arr_idx], sizeof(kek_t));
	zero_out((char *)&SDPK_Rpri[key_arr_idx], sizeof(kek_t));
	zero_out((char *)&SDPK_Dpri[key_arr_idx], sizeof(kek_t));

	ecryptfs_mm_drop_cache(userid);
#if DEK_DEBUG
	dump_all_keys(key_arr_idx);
#endif

	return 0;
}
Esempio n. 17
0
int parse_dek_packet(char *data,
		struct ecryptfs_crypt_stat *crypt_stat,
		size_t *packet_size) {
	int rc = 0;
	char temp_comm[PKG_NAME_SIZE]; //test
	int temp_euid;

	(*packet_size) = 0;

	if (data[(*packet_size)++] != ECRYPTFS_DEK_PACKET_TYPE) {
		DEK_LOGE("First byte != 0x%.2x; invalid packet\n",
				ECRYPTFS_DEK_PACKET_TYPE);
		rc = -EINVAL;
	}

	memcpy(temp_comm, &data[*packet_size], PKG_NAME_SIZE);
	(*packet_size) += PKG_NAME_SIZE;

	temp_euid = get_unaligned_be32(data + *packet_size);
	(*packet_size) += 4;

	if (crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) {
		crypt_stat->sdp_dek.type = get_unaligned_be32(data + *packet_size);
		(*packet_size) += 4;
		crypt_stat->sdp_dek.len = get_unaligned_be32(data + *packet_size);
		(*packet_size) += 4;
		memcpy(crypt_stat->sdp_dek.buf, &data[*packet_size], crypt_stat->sdp_dek.len);
		(*packet_size) += crypt_stat->sdp_dek.len;
	}
	
#if ECRYPTFS_DEK_DEBUG
	DEK_LOGD("%s() : comm : %s [euid:%d]\n",
		__func__, temp_comm, temp_euid);
#endif
	return rc;
}
static int ecryptfs_sdp_set_sensitive(struct dentry *dentry) {
	int rc = 0;
	struct inode *inode = dentry->d_inode;
	struct ecryptfs_crypt_stat *crypt_stat =
			&ecryptfs_inode_to_private(inode)->crypt_stat;
	dek_t DEK;

	memcpy(DEK.buf, crypt_stat->key, crypt_stat->key_size);
	DEK.len = crypt_stat->key_size;
	DEK.type = DEK_TYPE_PLAIN;

	rc = dek_encrypt_dek_efs(crypt_stat->userid, &DEK,  &crypt_stat->sdp_dek);
	if (rc < 0) {
		DEK_LOGE("Error encrypting dek; rc = [%d]\n", rc);
		memset(&crypt_stat->sdp_dek, 0, sizeof(dek_t));
		goto out;
	}
	memset(crypt_stat->key, 0, crypt_stat->key_size);
	crypt_stat->flags &= ~(ECRYPTFS_KEY_SET);
	ecryptfs_update_crypt_flag(dentry, 1);
out:
	memset(&DEK, 0, sizeof(dek_t));
	return rc;
}
Esempio n. 19
0
static int dek_on_device_unlocked(dek_arg_on_device_unlocked *evt) {
	int userid = evt->userid;
	int key_arr_idx = PERSONA_KEY_ARR_IDX(userid);

	/*
	 * TODO : lock needed
	 */

	if (!dek_is_persona(userid)) {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -EFAULT;
	}

	if((evt->SDPK_sym.len > KEK_MAX_LEN) ||
			(evt->SDPK_Rpri.len > KEK_MAX_LEN) ||
			(evt->SDPK_Dpri.len > KEK_MAX_LEN)) {
		DEK_LOGE("%s Invalid args\n", __func__);
		DEK_LOGE("SDPK_Rpub.len : %d\n", evt->SDPK_sym.len);
		DEK_LOGE("SDPK_Dpub.len : %d\n", evt->SDPK_Rpri.len);
		DEK_LOGE("SDPK_Dpub.len : %d\n", evt->SDPK_Dpri.len);
		return -EINVAL;
	}

	memcpy(SDPK_sym[key_arr_idx].buf, evt->SDPK_sym.buf, evt->SDPK_sym.len);
	SDPK_sym[key_arr_idx].len = evt->SDPK_sym.len;
	memcpy(SDPK_Rpri[key_arr_idx].buf, evt->SDPK_Rpri.buf, evt->SDPK_Rpri.len);
	SDPK_Rpri[key_arr_idx].len = evt->SDPK_Rpri.len;
	memcpy(SDPK_Dpri[key_arr_idx].buf, evt->SDPK_Dpri.buf, evt->SDPK_Dpri.len);
	SDPK_Dpri[key_arr_idx].len = evt->SDPK_Dpri.len;

	sdp_tfm[key_arr_idx] = dek_aes_key_setup(evt->SDPK_sym.buf, evt->SDPK_sym.len);
	if (IS_ERR(sdp_tfm[key_arr_idx])) {
		DEK_LOGE("error setting up key\n");
		dek_add_to_log(evt->userid, "error setting up key");
		sdp_tfm[key_arr_idx] = NULL;
	}

#if DEK_DEBUG
	dump_all_keys(key_arr_idx);
#endif

	return 0;
}
Esempio n. 20
0
static int dek_decrypt_dek(int userid, dek_t *encDek, dek_t *plainDek) {
	int key_arr_idx = PERSONA_KEY_ARR_IDX(userid);

	if (!dek_is_persona(userid)) {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -EFAULT;
	}
#if DEK_DEBUG
	DEK_LOGD("encDek from user: "******"aes decrypt failed\n");
				dek_add_to_log(userid, "aes decrypt failed");
				plainDek->len = 0;
			} else {
				plainDek->len = encDek->len;
				plainDek->type = DEK_TYPE_PLAIN;
			}
		} else {
			DEK_LOGE("no SDPK_sym key for id: %d\n", userid);
			dek_add_to_log(userid, "decrypt failed, persona locked");
			return -EIO;
		}
	} else if (encDek->type == DEK_TYPE_RSA_ENC) {
		DEK_LOGE("Not supported key type: %d\n", encDek->type);
		dek_add_to_log(userid, "decrypt failed, RSA type not supported");
		return -EFAULT;
	} else if (encDek->type == DEK_TYPE_DH_ENC) {
#ifdef CONFIG_PUB_CRYPTO
		if(SDPK_Dpri[key_arr_idx].len > 0) {
			if(dh_decryptEDEK(encDek, plainDek, &SDPK_Dpri[key_arr_idx])){
			    DEK_LOGE("dh_decryptEDEK failed");
				return -1;
			}
		}else{
			DEK_LOGE("SDPK_Dpri for id: %d\n", userid);
			dek_add_to_log(userid, "encrypt failed, no SDPK_Dpri");
			return -EIO;
		}
#else
		DEK_LOGE("Not supported key type: %d\n", encDek->type);
		dek_add_to_log(userid, "decrypt failed, DH type not supported");
		return -EOPNOTSUPP;
#endif
	} else {
		DEK_LOGE("Unsupported decrypt key type: %d\n", encDek->type);
		dek_add_to_log(userid, "decrypt failed, unsupported key type");
		return -EFAULT;
	}

	if (plainDek->len <= 0 || plainDek->len > DEK_LEN) {
		DEK_LOGE("dek_decrypt_dek, incorrect len=%d\n", plainDek->len);
		zero_out((char *)plainDek, sizeof(dek_t));
		return -EFAULT;
	} else {
#if DEK_DEBUG
		DEK_LOGD("plainDek to user: ");
		dump(plainDek->buf, plainDek->len);
#endif
	}
	return 0;
}
Esempio n. 21
0
static int dek_decrypt_dek(int userid, dek_t *encDek, dek_t *plainDek) {
	int key_arr_idx;
	int dek_type = encDek->type;

	if (!dek_is_persona(userid)) {
		DEK_LOGE("%s invalid userid %d\n", __func__, userid);
		return -EFAULT;
	}
	key_arr_idx = PERSONA_KEY_ARR_IDX(userid);
#if DEK_DEBUG
	DEK_LOGD("encDek from user: "******"aes decrypt failed\n");
                dek_add_to_log(userid, "aes decrypt failed");
                plainDek->len = 0;
            } else {
                plainDek->len = encDek->len;
                plainDek->type = DEK_TYPE_PLAIN;
            }
        } else {
            DEK_LOGE("no SDPK_sym key for id: %d\n", userid);
            dek_add_to_log(userid, "decrypt failed, persona locked");
            return -EIO;
        }
        return 0;
	}
	case DEK_TYPE_RSA_ENC:
	{
#ifdef CONFIG_PUB_CRYPTO
        if(SDPK_Rpri[key_arr_idx].len > 0) {
            if(rsa_decryptByPair(encDek, plainDek, &SDPK_Rpri[key_arr_idx])){
                DEK_LOGE("rsa_decryptByPair failed");
                return -1;
            }
        }else{
            DEK_LOGE("SDPK_Rpri for id: %d\n", userid);
            dek_add_to_log(userid, "encrypt failed, no SDPK_Rpri");
            return -EIO;
        }
#else
        DEK_LOGE("Not supported key type: %d\n", encDek->type);
        dek_add_to_log(userid, "decrypt failed, DH type not supported");
        return -EOPNOTSUPP;
#endif
        return 0;
	}
	case DEK_TYPE_DH_ENC:
	{
#ifdef CONFIG_PUB_CRYPTO
        if(SDPK_Dpri[key_arr_idx].len > 0) {
            if(dh_decryptEDEK(encDek, plainDek, &SDPK_Dpri[key_arr_idx])){
                DEK_LOGE("dh_decryptEDEK failed");
                return -1;
            }
        }else{
            DEK_LOGE("SDPK_Dpri for id: %d\n", userid);
            dek_add_to_log(userid, "encrypt failed, no SDPK_Dpri");
            return -EIO;
        }
#else
        DEK_LOGE("Not supported key type: %d\n", encDek->type);
        dek_add_to_log(userid, "decrypt failed, DH type not supported");
        return -EOPNOTSUPP;
#endif
        return 0;
	}
	case DEK_TYPE_ECDH256_ENC:
	{
#ifdef CONFIG_PUB_CRYPTO
#if DEK_DEBUG
	    printk("DEK_TYPE_ECDH256_ENC encDek:"); dek_dump(encDek->buf, encDek->len);
#endif
        if(SDPK_EDpri[key_arr_idx].len > 0) {
            if(ecdh_decryptEDEK(encDek, plainDek, &SDPK_EDpri[key_arr_idx])){
                DEK_LOGE("ecdh_decryptEDEK failed");
                return -1;
            }
        }else{
            DEK_LOGE("SDPK_EDpri for id: %d\n", userid);
            dek_add_to_log(userid, "encrypt failed, no SDPK_EDpri");
            return -EIO;
        }
#else
        DEK_LOGE("Not supported key type: %d\n", encDek->type);
        dek_add_to_log(userid, "decrypt failed, ECDH type not supported");
        return -EOPNOTSUPP;
#endif
        return 0;
	}
	default:
	{
        DEK_LOGE("Unsupported edek type: %d\n", encDek->type);
        dek_add_to_log(userid, "decrypt failed, unsupported key type");
        return -EFAULT;
	}
	}
}
Esempio n. 22
0
static int ecryptfs_update_crypt_flag(struct dentry *dentry, int is_sensitive)
{
	int rc = 0;
	struct dentry *lower_dentry;
	struct inode *inode;
	struct inode *lower_inode;
	struct ecryptfs_crypt_stat *crypt_stat;
	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;

	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
	if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED))
		ecryptfs_init_crypt_stat(crypt_stat);
	inode = dentry->d_inode;
	lower_inode = ecryptfs_inode_to_lower(inode);
	lower_dentry = ecryptfs_dentry_to_lower(dentry);

	mutex_lock(&crypt_stat->cs_mutex);

	mount_crypt_stat = &ecryptfs_superblock_to_private(
			dentry->d_sb)->mount_crypt_stat;
	rc = ecryptfs_get_lower_file(dentry, inode);
	if (rc) {
		mutex_unlock(&crypt_stat->cs_mutex);
		DEK_LOGE("ecryptfs_get_lower_file rc=%d\n", rc);
		goto out;
	}

	if (is_sensitive) {
		crypt_stat->flags |= ECRYPTFS_DEK_IS_SENSITIVE;
		/*
		* Set sensirive for all the pages in the inode 
		*/
		set_sensitive_mapping_pages(inode->i_mapping, 0, -1);
	}
	else{
		crypt_stat->flags &= ~ECRYPTFS_DEK_IS_SENSITIVE;
	}

	rc = ecryptfs_write_metadata(dentry, inode);
	if (rc) {
		if (!(mount_crypt_stat->flags
				& ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
			rc = -EIO;
			DEK_LOGE("Either the lower file "
					"is not in a valid eCryptfs format, "
					"or the key could not be retrieved. "
					"Plaintext passthrough mode is not "
					"enabled; returning -EIO\n");
			mutex_unlock(&crypt_stat->cs_mutex);
			DEK_LOGD("ecryptfs_write_metadata rc=%d\n", rc);
			goto out;
		}
		rc = 0;
		crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
				| ECRYPTFS_ENCRYPTED);
	}

	rc = ecryptfs_write_inode_size_to_metadata(inode);
	if (rc) {
		mutex_unlock(&crypt_stat->cs_mutex);
		DEK_LOGE("Problem with "
				"ecryptfs_write_inode_size_to_metadata; "
				"rc = [%d]\n", rc);
		goto out;
	}

	ecryptfs_put_lower_file(inode);

	mutex_unlock(&crypt_stat->cs_mutex);

out:
	fsstack_copy_attr_all(inode, lower_inode);
	return rc;
}
Esempio n. 23
0
long ecryptfs_do_sdp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
	char filename[NAME_MAX+1] = {0};
	void __user *ubuf = (void __user *)arg;
	struct dentry *ecryptfs_dentry = file->f_path.dentry;
	struct inode *inode = ecryptfs_dentry->d_inode;
	struct ecryptfs_crypt_stat *crypt_stat =
			&ecryptfs_inode_to_private(inode)->crypt_stat;
	struct dentry *fp_dentry =
			ecryptfs_inode_to_private(inode)->lower_file->f_dentry;
	if (fp_dentry->d_name.len <= NAME_MAX)
			memcpy(filename, fp_dentry->d_name.name,
					fp_dentry->d_name.len + 1);

	DEK_LOGD("ecryptfs_do_sdp_ioctl\n");

	if (!(crypt_stat->flags & ECRYPTFS_DEK_SDP_ENABLED)) {
		DEK_LOGE("SDP not enabled, skip sdp ioctl\n");
		return -ENOTTY;
	}

	switch (cmd) {
	case ECRYPTFS_IOCTL_GET_SDP_INFO: {
		dek_arg_get_sdp_info req;

		DEK_LOGD("ECRYPTFS_IOCTL_GET_SDP_INFO\n");
	
		memset(&req, 0, sizeof(dek_arg_get_sdp_info));
		if(copy_from_user(&req, ubuf, sizeof(req))) {
			DEK_LOGE("can't copy from user\n");
			return -EFAULT;
		} else {
			mutex_lock(&crypt_stat->cs_mutex);
			if (crypt_stat->flags & ECRYPTFS_DEK_SDP_ENABLED) {
				req.sdp_enabled = 1;
			} else {
				req.sdp_enabled = 0;
			}
			if (crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) {
				req.is_sensitive = 1;
			} else {
				req.is_sensitive = 0;
			}
			req.type = crypt_stat->sdp_dek.type;
			mutex_unlock(&crypt_stat->cs_mutex);
		}
		if(copy_to_user(ubuf, &req, sizeof(req))) {
			DEK_LOGE("can't copy to user\n");
			return -EFAULT;
		}

		break;
		}
	case ECRYPTFS_IOCTL_GET_FEK: {
		dek_arg_get_fek req;

		DEK_LOGD("ECRYPTFS_IOCTL_GET_FEK\n");
	
		if (crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) {
			DEK_LOGE("don't return FEK of sensitive file\n");
			return -EFAULT;
		}

		memset(&req, 0, sizeof(dek_arg_get_fek));
		if(copy_from_user(&req, ubuf, sizeof(req))) {
			DEK_LOGE("can't copy from user\n");
			memset(&req, 0, sizeof(dek_arg_get_fek));
			return -EFAULT;
		} else {
			mutex_lock(&crypt_stat->cs_mutex);
			memcpy(req.dek.buf, crypt_stat->key, crypt_stat->key_size);
			req.dek.len = crypt_stat->key_size;
			req.dek.type = DEK_TYPE_PLAIN;
			mutex_unlock(&crypt_stat->cs_mutex);
		}
		if(copy_to_user(ubuf, &req, sizeof(req))) {
			DEK_LOGE("can't copy to user\n");
			memset(&req, 0, sizeof(dek_arg_get_fek));
			return -EFAULT;
		}
		memset(&req, 0, sizeof(dek_arg_get_fek));
		break;
		}

	case ECRYPTFS_IOCTL_GET_EFEK: {
		dek_arg_get_efek req;

		DEK_LOGD("ECRYPTFS_IOCTL_GET_EFEK\n");
	
		memset(&req, 0, sizeof(dek_arg_get_efek));
		if(copy_from_user(&req, ubuf, sizeof(req))) {
			DEK_LOGE("can't copy from user\n");
			memset(&req, 0, sizeof(dek_arg_get_efek));
			return -EFAULT;
		} else {
			mutex_lock(&crypt_stat->cs_mutex);
			memcpy(req.dek.buf, crypt_stat->sdp_dek.buf, crypt_stat->sdp_dek.len);
			req.dek.len = crypt_stat->sdp_dek.len;
			req.dek.type = crypt_stat->sdp_dek.type;
			mutex_unlock(&crypt_stat->cs_mutex);
		}
		if(copy_to_user(ubuf, &req, sizeof(req))) {
			DEK_LOGE("can't copy to user\n");
			memset(&req, 0, sizeof(dek_arg_get_efek));
			return -EFAULT;
		}
		memset(&req, 0, sizeof(dek_arg_get_efek));
		break;
		}

	case ECRYPTFS_IOCTL_SET_EFEK: {
		dek_arg_set_efek req;

		DEK_LOGD("ECRYPTFS_IOCTL_SET_EFEK\n");
	
		memset(&req, 0, sizeof(dek_arg_set_efek));
		if(copy_from_user(&req, ubuf, sizeof(req))) {
			DEK_LOGE("can't copy from user\n");
			memset(&req, 0, sizeof(dek_arg_set_efek));
			return -EFAULT;
		} else {
			if(req.dek.len > DEK_MAXLEN) {
				DEK_LOGE("ECRYPTFS_IOCTL_SET_EFEK invalid EFEK len %d\n",
						req.dek.len);
				return -EINVAL;
			}

			if (req.dek.type != DEK_TYPE_PLAIN) {
				mutex_lock(&crypt_stat->cs_mutex);
				memcpy(crypt_stat->sdp_dek.buf, req.dek.buf, req.dek.len);
				crypt_stat->sdp_dek.len = req.dek.len;
				crypt_stat->sdp_dek.type = req.dek.type;
				memset(crypt_stat->key, 0, crypt_stat->key_size);
				crypt_stat->flags &= ~(ECRYPTFS_KEY_SET);
				mutex_unlock(&crypt_stat->cs_mutex);
				ecryptfs_update_crypt_flag(ecryptfs_dentry, 1);
			} else {
				DEK_LOGE("failed to set EFEK\n");
				memset(&req, 0, sizeof(dek_arg_set_efek));
				return -EFAULT;
			}
		}
		memset(&req, 0, sizeof(dek_arg_set_efek));
		break;
		}
	default: {
		return -EINVAL;
		break;
		}

	}
	return 0;
}
Esempio n. 24
0
static long dek_do_ioctl_evt(unsigned int minor, unsigned int cmd,
		unsigned long arg) {
	long ret = 0;
	void __user *ubuf = (void __user *)arg;
	void *cleanup = NULL;
	unsigned int size;

	switch (cmd) {
	/*
	 * Event while booting.
	 *
	 * This event comes per persona, the driver is responsible to
	 * verify things good whether it's compromised.
	 */
	case DEK_ON_BOOT: {
		dek_arg_on_boot *evt = kzalloc(sizeof(dek_arg_on_boot), GFP_KERNEL);
		
		DEK_LOGD("DEK_ON_BOOT\n");

		if (evt == NULL) {
			ret = -ENOMEM;
			goto err;
		}		
		cleanup = evt;
		size = sizeof(dek_arg_on_boot);

		if(copy_from_user(evt, ubuf, size)) {
			DEK_LOGE("can't copy from user evt\n");
			ret = -EFAULT;
			goto err;
		}
		ret = dek_on_boot(evt);
		if (ret < 0) {
			dek_add_to_log(evt->userid, "Boot failed");
			goto err;
		}
		dek_add_to_log(evt->userid, "Booted");
		break;
	}
	/*
	 * Event when device is locked.
	 *
	 * Nullify private key which prevents decryption.
	 */
	case DEK_ON_DEVICE_LOCKED: {
		dek_arg_on_device_locked *evt = kzalloc(sizeof(dek_arg_on_device_locked), GFP_KERNEL);
		
		DEK_LOGD("DEK_ON_DEVICE_LOCKED\n");
		if (evt == NULL) {
			ret = -ENOMEM;
			goto err;
		}		
		cleanup = evt;
		size = sizeof(dek_arg_on_device_locked);

		if(copy_from_user(evt, ubuf, size)) {
			DEK_LOGE("can't copy from user evt\n");
			ret = -EFAULT;
			goto err;
		}
		ret = dek_on_device_locked(evt);
		if (ret < 0) {
			dek_add_to_log(evt->userid, "Lock failed");
			goto err;
		}
		dek_add_to_log(evt->userid, "Locked");
		break;
	}
	/*
	 * Event when device unlocked.
	 *
	 * Read private key and decrypt with user password.
	 */
	case DEK_ON_DEVICE_UNLOCKED: {
		dek_arg_on_device_unlocked *evt = kzalloc(sizeof(dek_arg_on_device_unlocked), GFP_KERNEL);

		DEK_LOGD("DEK_ON_DEVICE_UNLOCKED\n");
		if (evt == NULL) {
			ret = -ENOMEM;
			goto err;
		}		
		cleanup = evt;
		size = sizeof(dek_arg_on_device_unlocked);

		if(copy_from_user(evt, ubuf, size)) {
			DEK_LOGE("can't copy from user evt\n");
			ret = -EFAULT;
			goto err;
		}
		ret = dek_on_device_unlocked(evt);
		if (ret < 0) {
			dek_add_to_log(evt->userid, "Unlock failed");
			goto err;
		}
		dek_add_to_log(evt->userid, "Unlocked");
		break;
	}
	/*
	 * Event when new user(persona) added.
	 *
	 * Generate RSA public key and encrypt private key with given
	 * password. Also pub-key and encryped priv-key have to be stored
	 * in a file system.
	 */
	case DEK_ON_USER_ADDED: {
		dek_arg_on_user_added *evt = kzalloc(sizeof(dek_arg_on_user_added), GFP_KERNEL);

		DEK_LOGD("DEK_ON_USER_ADDED\n");
		if (evt == NULL) {
			ret = -ENOMEM;
			goto err;
		}		
		cleanup = evt;
		size = sizeof(dek_arg_on_user_added);

		if(copy_from_user(evt, ubuf, size)) {
			DEK_LOGE("can't copy from user evt\n");
			ret = -EFAULT;
			goto err;
		}
		ret = dek_on_user_added(evt);
		if (ret < 0) {
			dek_add_to_log(evt->userid, "Add user failed");
			goto err;
		}
		dek_add_to_log(evt->userid, "Added user");
		break;
	}
	/*
	 * Event when user is removed.
	 *
	 * Remove pub-key file & encrypted priv-key file.
	 */
	case DEK_ON_USER_REMOVED: {
		dek_arg_on_user_removed *evt = kzalloc(sizeof(dek_arg_on_user_removed), GFP_KERNEL);
		
		DEK_LOGD("DEK_ON_USER_REMOVED\n");
		if (evt == NULL) {
			ret = -ENOMEM;
			goto err;
		}		
		cleanup = evt;
		size = sizeof(dek_arg_on_user_removed);

		if(copy_from_user(evt, ubuf, size)) {
			DEK_LOGE("can't copy from user evt\n");
			ret = -EFAULT;
			goto err;
		}
		ret = dek_on_user_removed(evt);
		if (ret < 0) {
			dek_add_to_log(evt->userid, "Remove user failed");
			goto err;
		}
		dek_add_to_log(evt->userid, "Removed user");
		break;
	}
	/*
	 * Event when password changed.
	 *
	 * Encrypt SDPK_Rpri with new password and store it.
	 */
	case DEK_ON_CHANGE_PASSWORD: {
		DEK_LOGD("DEK_ON_CHANGE_PASSWORD << deprecated. SKIP\n");
		ret = 0;
		dek_add_to_log(0, "Changed password << deprecated");
		break;
	}

	case DEK_DISK_CACHE_CLEANUP: {
		dek_arg_disk_cache_cleanup *evt = kzalloc(sizeof(dek_arg_disk_cache_cleanup), GFP_KERNEL);

		DEK_LOGD("DEK_DISK_CACHE_CLEANUP\n");
		if (evt == NULL) {
			ret = -ENOMEM;
			goto err;
		}
		cleanup = evt;
		size = sizeof(dek_arg_on_user_removed);

		if(copy_from_user(evt, ubuf, size)) {
			DEK_LOGE("can't copy from user evt\n");
			ret = -EFAULT;
			goto err;
		}
		if (!dek_is_persona(evt->userid)) {
			DEK_LOGE("%s invalid userid %d\n", __func__, evt->userid);
			ret = -EFAULT;
			goto err;
		}

		ecryptfs_mm_drop_cache(evt->userid);
		ret = 0;
		dek_add_to_log(evt->userid, "Disk cache clean up");
		break;
	}
	default:
		DEK_LOGE("%s case default\n", __func__);
		ret = -EINVAL;
		break;
	}

err:
	if (cleanup) {
		zero_out((char *)cleanup, size);
		kfree(cleanup);
	}
	return ret;
}
Esempio n. 25
0
static long dek_do_ioctl_req(unsigned int minor, unsigned int cmd,
		unsigned long arg) {
	long ret = 0;
	void __user *ubuf = (void __user *)arg;

	switch (cmd) {
    case DEK_IS_KEK_AVAIL: {
        dek_arg_is_kek_avail req;

        DEK_LOGD("DEK_IS_KEK_AVAIL\n");

        memset(&req, 0, sizeof(dek_arg_is_kek_avail));
        if(copy_from_user(&req, ubuf, sizeof(req))) {
            DEK_LOGE("can't copy from user\n");
            ret = -EFAULT;
            goto err;
        }

        req.ret = is_kek_available(req.userid, req.kek_type);
        if(req.ret < 0) {
            DEK_LOGE("is_kek_available(id:%d, kek:%d) error\n",
                    req.userid, req.kek_type);
            ret = -ENOENT;
            goto err;
        }

        if(copy_to_user(ubuf, &req, sizeof(req))) {
            DEK_LOGE("can't copy to user req\n");
            zero_out((char *)&req, sizeof(dek_arg_is_kek_avail));
            ret = -EFAULT;
            goto err;
        }

        ret = 0;
    }
    break;
	/*
	 * Request to generate DEK.
	 * Generate DEK and return to the user
	 */
	case DEK_GENERATE_DEK: {
		dek_arg_generate_dek req;

		DEK_LOGD("DEK_GENERATE_DEK\n");

		memset(&req, 0, sizeof(dek_arg_generate_dek));
		if(copy_from_user(&req, ubuf, sizeof(req))) {
			DEK_LOGE("can't copy from user req\n");
			ret = -EFAULT;
			goto err;
		}
		dek_generate_dek(req.userid, &req.dek);
		if(copy_to_user(ubuf, &req, sizeof(req))) {
			DEK_LOGE("can't copy to user req\n");
			zero_out((char *)&req, sizeof(dek_arg_generate_dek));
			ret = -EFAULT;
			goto err;
		}
		zero_out((char *)&req, sizeof(dek_arg_generate_dek));
		break;
	}
	/*
	 * Request to encrypt given DEK.
	 *
	 * encrypt dek and return to the user
	 */
	case DEK_ENCRYPT_DEK: {
		dek_arg_encrypt_dek req;

		DEK_LOGD("DEK_ENCRYPT_DEK\n");

		memset(&req, 0, sizeof(dek_arg_encrypt_dek));
		if(copy_from_user(&req, ubuf, sizeof(req))) {
			DEK_LOGE("can't copy from user req\n");
			zero_out((char *)&req, sizeof(dek_arg_encrypt_dek));
			ret = -EFAULT;
			goto err;
		}
		ret = dek_encrypt_dek(req.userid,
				&req.plain_dek, &req.enc_dek);
		if (ret < 0) {
			zero_out((char *)&req, sizeof(dek_arg_encrypt_dek));
			goto err;
		}
		if(copy_to_user(ubuf, &req, sizeof(req))) {
			DEK_LOGE("can't copy to user req\n");
			zero_out((char *)&req, sizeof(dek_arg_encrypt_dek));
			ret = -EFAULT;
			goto err;
		}
		zero_out((char *)&req, sizeof(dek_arg_encrypt_dek));
		break;
	}
	/*
	 * Request to decrypt given DEK.
	 *
	 * Decrypt dek and return to the user.
	 * When device is locked, private key is not available, so
	 * the driver must return EPERM or some kind of error.
	 */
	case DEK_DECRYPT_DEK: {
		dek_arg_decrypt_dek req;

		DEK_LOGD("DEK_DECRYPT_DEK\n");

		memset(&req, 0, sizeof(dek_arg_decrypt_dek));
		if(copy_from_user(&req, ubuf, sizeof(req))) {
			DEK_LOGE("can't copy from user req\n");
			zero_out((char *)&req, sizeof(dek_arg_decrypt_dek));
			ret = -EFAULT;
			goto err;
		}
		ret = dek_decrypt_dek(req.userid,
				&req.enc_dek, &req.plain_dek);
		if (ret < 0) {
			zero_out((char *)&req, sizeof(dek_arg_decrypt_dek));
			goto err;
		}
		if(copy_to_user(ubuf, &req, sizeof(req))) {
			DEK_LOGE("can't copy to user req\n");
			zero_out((char *)&req, sizeof(dek_arg_decrypt_dek));
			ret = -EFAULT;
			goto err;
		}
		zero_out((char *)&req, sizeof(dek_arg_decrypt_dek));
		break;
	}

	default:
		DEK_LOGE("%s case default\n", __func__);
		ret = -EINVAL;
		break;
	}

	return ret;
err:
	return ret;
}
Esempio n. 26
0
static long dek_do_ioctl_kek(unsigned int minor, unsigned int cmd,
		unsigned long arg) {
	long ret = 0;
	void __user *ubuf = (void __user *)arg;

	switch (cmd) {
	case DEK_GET_KEK: {
		dek_arg_get_kek req;
		int requested_type = 0;
		int userid;
		int key_arr_idx;

		DEK_LOGD("DEK_GET_KEK\n");

		memset(&req, 0, sizeof(dek_arg_get_kek));
		if(copy_from_user(&req, ubuf, sizeof(req))) {
			DEK_LOGE("can't copy from user kek\n");
			ret = -EFAULT;
			goto err;
		}

		userid = req.userid;
		if (!dek_is_persona(userid)) {
			DEK_LOGE("%s invalid userid %d\n", __func__, userid);
			return -EFAULT;
		}
		key_arr_idx = PERSONA_KEY_ARR_IDX(userid);

		requested_type = req.kek_type;
		req.key.len = 0;
		req.key.type = -1;

		switch(requested_type) {
		case KEK_TYPE_SYM:
			if (SDPK_sym[key_arr_idx].len > 0) {
                copy_kek(&req.key, &SDPK_sym[key_arr_idx], KEK_TYPE_SYM);
				DEK_LOGD("SDPK_sym len : %d\n", req.key.len);
			}else{
				DEK_LOGE("SDPK_sym not-available\n");
				ret = -EIO;
				goto err;
			}
			break;
		case KEK_TYPE_RSA_PUB:
			if (SDPK_Rpub[key_arr_idx].len > 0) {
                copy_kek(&req.key, &SDPK_Rpub[key_arr_idx], KEK_TYPE_RSA_PUB);
				DEK_LOGD("SDPK_Rpub len : %d\n", req.key.len);
			} else {
				DEK_LOGE("SDPK_Rpub not-available\n");
				ret = -EIO;
				goto err;
			}
			break;
		case KEK_TYPE_RSA_PRIV:
#ifdef CONFIG_SDP_IOCTL_PRIV
			if (SDPK_Rpri[key_arr_idx].len > 0) {
                copy_kek(&req.key, &SDPK_Rpri[key_arr_idx], KEK_TYPE_RSA_PRIV);
				DEK_LOGD("SDPK_Rpri len : %d\n", req.key.len);
			} else {
				DEK_LOGE("SDPK_Rpri not-available\n");
				ret = -EIO;
				goto err;
			}
#else
			DEK_LOGE("SDPK_Rpri not exposed\n");
			ret = -EOPNOTSUPP;
			goto err;
#endif
			break;
		case KEK_TYPE_DH_PUB:
			if (SDPK_Dpub[key_arr_idx].len > 0) {
                copy_kek(&req.key, &SDPK_Dpub[key_arr_idx], KEK_TYPE_DH_PUB);
				DEK_LOGD("SDPK_Dpub len : %d\n", req.key.len);
			} else {
				DEK_LOGE("SDPK_Dpub not-available\n");
				ret = -EIO;
				goto err;
			}

			break;
		case KEK_TYPE_DH_PRIV:
#ifdef CONFIG_SDP_IOCTL_PRIV
			if (SDPK_Dpri[key_arr_idx].len > 0) {
                copy_kek(&req.key, &SDPK_Dpri[key_arr_idx], KEK_TYPE_DH_PRIV);
				DEK_LOGD("SDPK_Dpri len : %d\n", req.key.len);
			} else {
				DEK_LOGE("SDPK_Dpri not-available\n");
				ret = -EIO;
				goto err;
			}
#else
			DEK_LOGE("SDPK_Dpri not exposed\n");
			ret = -EOPNOTSUPP;
			goto err;
#endif
			break;
        case KEK_TYPE_ECDH256_PUB:
            if (SDPK_EDpub[key_arr_idx].len > 0) {
                copy_kek(&req.key, &SDPK_EDpub[key_arr_idx], KEK_TYPE_ECDH256_PUB);
                DEK_LOGD("SDPK_EDpub len : %d\n", req.key.len);
            } else {
                DEK_LOGE("SDPK_EDpub not-available\n");
                ret = -EIO;
                goto err;
            }

            break;
        case KEK_TYPE_ECDH256_PRIV:
#ifdef CONFIG_SDP_IOCTL_PRIV
            if (SDPK_EDpri[key_arr_idx].len > 0) {
                copy_kek(&req.key, &SDPK_EDpub[key_arr_idx], KEK_TYPE_ECDH256_PRIV);
                DEK_LOGD("SDPK_EDpri len : %d\n", req.key.len);
            } else {
                DEK_LOGE("SDPK_EDpri not-available\n");
                ret = -EIO;
                goto err;
            }
#else
            DEK_LOGE("SDPK_EDpri not exposed\n");
            ret = -EOPNOTSUPP;
            goto err;
#endif
            break;
		default:
			DEK_LOGE("invalid key type\n");
			ret = -EINVAL;
			goto err;
			break;
		}

		if(copy_to_user(ubuf, &req, sizeof(req))) {
			DEK_LOGE("can't copy to user kek\n");
			zero_out((char *)&req, sizeof(dek_arg_get_kek));
			ret = -EFAULT;
			goto err;
		}
		zero_out((char *)&req, sizeof(dek_arg_get_kek));
		break;
	}
	default:
		DEK_LOGE("%s case default\n", __func__);
		ret = -EINVAL;
		break;
	}

	return ret;
err:
	return ret;
}