blob: 26fbb7e02c45cf6dc973b1ae91f0053fddc4e3c2 [file] [log] [blame]
/*
* Copyright (C) 2013 Intel Finland Oy
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <linux/kernel.h>
#include <linux/compat.h>
#include <linux/compiler.h>
#include <linux/uaccess.h>
#include <linux/printk.h>
#include "sep_compat_ioctl.h"
#include "dx_driver_abi.h"
#include "dx_dev_defs.h"
#include "sepapp.h"
typedef int sep_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
static int compat_sep_ioctl_get_ver_major(struct file *filp, unsigned int cmd,
unsigned long arg)
{
return sep_ioctl(filp, cmd, arg);
}
static int compat_sep_ioctl_get_ver_minor(struct file *filp, unsigned int cmd,
unsigned long arg)
{
return sep_ioctl(filp, cmd, arg);
}
static int compat_sep_ioctl_get_sym_cipher_ctx_size(struct file *filp,
unsigned int cmd,
unsigned long arg)
{
return sep_ioctl(filp, cmd, arg);
}
static int compat_sep_ioctl_get_auth_enc_ctx_size(struct file *filp,
unsigned int cmd,
unsigned long arg)
{
return sep_ioctl(filp, cmd, arg);
}
static int compat_sep_ioctl_get_mac_ctx_size(struct file *filp,
unsigned int cmd,
unsigned long arg)
{
return sep_ioctl(filp, cmd, arg);
}
static int compat_sep_ioctl_get_hash_ctx_size(struct file *filp,
unsigned int cmd,
unsigned long arg)
{
return sep_ioctl(filp, cmd, arg);
}
#pragma pack(push)
#pragma pack(4)
struct sym_cipher_init_params_32 {
u32 context_buf; /*[in] */
struct dxdi_sym_cipher_props props; /*[in] */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_sym_cipher_init(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct sym_cipher_init_params_32 init_32;
struct dxdi_sym_cipher_init_params __user *init_params;
int ret;
if (copy_from_user(&init_32, (void __user *)arg, sizeof(init_32)))
return -EFAULT;
init_params = compat_alloc_user_space(sizeof(*init_params));
if (!access_ok(VERIFY_WRITE, init_params, sizeof(*init_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)init_32.context_buf,
&init_params->context_buf)
|| copy_to_user(&init_params->props, &init_32.props,
sizeof(init_32.props)))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)init_params);
if (__get_user(init_32.error_info, &init_params->error_info))
return -EFAULT;
if (put_user(init_32.error_info,
&((struct sym_cipher_init_params_32 *)arg)->error_info))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct auth_enc_init_params_32 {
u32 context_buf; /*[in] */
struct dxdi_auth_enc_props props; /*[in] */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_auth_enc_init(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct auth_enc_init_params_32 up32;
struct dxdi_auth_enc_init_params __user *init_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
init_params = compat_alloc_user_space(sizeof(*init_params));
if (!access_ok(VERIFY_WRITE, init_params, sizeof(*init_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&init_params->context_buf)
|| copy_to_user(&init_params->props, &up32.props,
sizeof(up32.props)))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)init_params);
if (__get_user(up32.error_info, &init_params->error_info))
return -EFAULT;
if (put_user(up32.error_info,
&((struct auth_enc_init_params_32 *)arg)->error_info))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct mac_init_params_32 {
u32 context_buf; /*[in] */
struct dxdi_mac_props props; /*[in] */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_mac_init(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct mac_init_params_32 up32;
struct dxdi_mac_init_params __user *init_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
init_params = compat_alloc_user_space(sizeof(*init_params));
if (!access_ok(VERIFY_WRITE, init_params, sizeof(*init_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&init_params->context_buf)
|| copy_to_user(&init_params->props, &up32.props,
sizeof(up32.props)))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)init_params);
if (__get_user(up32.error_info, &init_params->error_info))
return -EFAULT;
if (put_user(up32.error_info,
&((struct mac_init_params_32 *)arg)->error_info))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct hash_init_params_32 {
u32 context_buf; /*[in] */
enum dxdi_hash_type hash_type; /*[in] */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_hash_init(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct hash_init_params_32 up32;
struct dxdi_hash_init_params __user *init_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
init_params = compat_alloc_user_space(sizeof(*init_params));
if (!access_ok(VERIFY_WRITE, init_params, sizeof(*init_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&init_params->context_buf)
|| __put_user(up32.hash_type, &init_params->hash_type))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)init_params);
if (__get_user(up32.error_info, &init_params->error_info))
return -EFAULT;
if (put_user(up32.error_info,
&((struct hash_init_params_32 *)arg)->error_info))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct process_dblk_params_32 {
u32 context_buf; /*[in] */
u32 data_in; /*[in] */
u32 data_out; /*[in] */
enum dxdi_data_block_type data_block_type; /*[in] */
u32 data_in_size; /*[in] */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_proc_dblk(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct process_dblk_params_32 up32;
struct dxdi_process_dblk_params __user *dblk_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
dblk_params = compat_alloc_user_space(sizeof(*dblk_params));
if (!access_ok(VERIFY_WRITE, dblk_params, sizeof(*dblk_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&dblk_params->context_buf)
|| __put_user((void __user *)(unsigned long)up32.data_in,
&dblk_params->data_in)
|| __put_user((void __user *)(unsigned long)up32.data_out,
&dblk_params->data_out)
|| __put_user(up32.data_block_type, &dblk_params->data_block_type)
|| __put_user(up32.data_in_size, &dblk_params->data_in_size))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)dblk_params);
if (__get_user(up32.error_info, &dblk_params->error_info))
return -EFAULT;
if (put_user(up32.error_info,
&((struct process_dblk_params_32 *)arg)->error_info))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct fin_process_params_32 {
u32 context_buf; /*[in] */
u32 data_in; /*[in] */
u32 data_out; /*[in] */
u32 data_in_size; /*[in] (octets) */
u8 digest_or_mac[DXDI_DIGEST_SIZE_MAX]; /*[out] */
u8 digest_or_mac_size; /*[out] (octets) */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_fin_proc(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct fin_process_params_32 up32;
struct dxdi_fin_process_params __user *fin_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
fin_params = compat_alloc_user_space(sizeof(*fin_params));
if (!access_ok(VERIFY_WRITE, fin_params, sizeof(*fin_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&fin_params->context_buf)
|| __put_user((void __user *)(unsigned long)up32.data_in,
&fin_params->data_in)
|| __put_user((void __user *)(unsigned long)up32.data_out,
&fin_params->data_out)
|| __put_user(up32.data_in_size, &fin_params->data_in_size))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)fin_params);
if (copy_from_user(up32.digest_or_mac, fin_params->digest_or_mac,
DXDI_DIGEST_SIZE_MAX)
|| __get_user(up32.digest_or_mac_size,
&fin_params->digest_or_mac_size)
|| __get_user(up32.error_info, &fin_params->error_info))
return -EFAULT;
if (copy_to_user((void __user *)arg, &up32, sizeof(up32)))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct combined_init_params_32 {
struct dxdi_combined_props props; /*[in] */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_combined_init(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct combined_init_params_32 up32;
struct dxdi_combined_init_params __user *init_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
init_params = compat_alloc_user_space(sizeof(*init_params));
if (!access_ok(VERIFY_WRITE, init_params, sizeof(*init_params)))
return -EFAULT;
if (copy_to_user(&init_params->props, &up32.props, sizeof(up32.props)))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)init_params);
if (__get_user(up32.error_info, &init_params->error_info))
return -EFAULT;
if (put_user(up32.error_info,
&((struct combined_init_params_32 *)arg)->error_info))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct combined_proc_dblk_params_32 {
struct dxdi_combined_props props; /*[in] */
u32 data_in; /*[in] */
u32 data_out; /*[out] */
u32 data_in_size; /*[in] (octets) */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_combined_proc_dblk(struct file *filp,
unsigned int cmd,
unsigned long arg)
{
struct combined_proc_dblk_params_32 up32;
struct dxdi_combined_proc_dblk_params __user *blk_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
blk_params = compat_alloc_user_space(sizeof(*blk_params));
if (!access_ok(VERIFY_WRITE, blk_params, sizeof(*blk_params)))
return -EFAULT;
if (copy_to_user(&blk_params->props, &up32.props,
sizeof(up32.props))
|| __put_user((void __user *)(unsigned long)up32.data_in,
&blk_params->data_in)
|| __put_user((void __user *)(unsigned long)up32.data_out,
&blk_params->data_out)
|| __put_user(up32.data_in_size, &blk_params->data_in_size))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)blk_params);
if (__get_user(up32.error_info, &blk_params->error_info))
return -EFAULT;
if (put_user(up32.error_info,
&((struct combined_proc_dblk_params_32 *)arg)->error_info))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct combined_proc_params_32 {
struct dxdi_combined_props props; /*[in] */
u32 data_in; /*[in] */
u32 data_out; /*[out] */
u32 data_in_size; /*[in] (octets) */
u8 auth_data[DXDI_DIGEST_SIZE_MAX]; /*[out] */
u8 auth_data_size; /*[out] (octets) */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_combined_fin_proc(struct file *filp,
unsigned int cmd,
unsigned long arg)
{
struct combined_proc_params_32 up32;
struct dxdi_combined_proc_params __user *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (copy_to_user(&user_params->props, &up32.props,
sizeof(up32.props))
|| __put_user((void __user *)(unsigned long)up32.data_in,
&user_params->data_in)
|| __put_user((void __user *)(unsigned long)up32.data_out,
&user_params->data_out)
|| __put_user(up32.data_in_size, &user_params->data_in_size))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (copy_from_user(up32.auth_data, user_params->auth_data,
DXDI_DIGEST_SIZE_MAX)
|| __get_user(up32.auth_data_size,
&user_params->auth_data_size)
|| __get_user(up32.error_info, &user_params->error_info))
return -EFAULT;
if (copy_to_user((void __user *)arg, &up32, sizeof(up32)))
return -EFAULT;
return ret;
}
static int compat_sep_ioctl_combined_proc(struct file *filp,
unsigned int cmd, unsigned long arg)
{
return compat_sep_ioctl_combined_fin_proc(filp, cmd, arg);
}
#pragma pack(push)
#pragma pack(4)
struct sym_cipher_proc_params_32 {
u32 context_buf; /*[in] */
struct dxdi_sym_cipher_props props; /*[in] */
u32 data_in; /*[in] */
u32 data_out; /*[in] */
u32 data_in_size; /*[in] (octets) */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_sym_cipher_proc(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct sym_cipher_proc_params_32 up32;
struct dxdi_sym_cipher_proc_params __user *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&user_params->context_buf)
|| copy_to_user(&user_params->props, &up32.props,
sizeof(up32.props))
|| __put_user((void __user *)(unsigned long)up32.data_in,
&user_params->data_in)
|| __put_user((void __user *)(unsigned long)up32.data_out,
&user_params->data_out)
|| __put_user(up32.data_in_size, &user_params->data_in_size))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (__get_user(up32.error_info, &user_params->error_info))
return -EFAULT;
if (put_user(up32.error_info,
&((struct sym_cipher_proc_params_32 *)arg)->error_info))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct auth_enc_proc_params_32 {
u32 context_buf; /*[in] */
struct dxdi_auth_enc_props props; /*[in] */
u32 adata; /*[in] */
u32 text_data; /*[in] */
u32 data_out; /*[in] */
u8 tag[DXDI_DIGEST_SIZE_MAX]; /*[out] */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_auth_enc_proc(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct auth_enc_proc_params_32 up32;
struct dxdi_auth_enc_proc_params __user *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&user_params->context_buf)
|| copy_to_user(&user_params->props, &up32.props,
sizeof(up32.props))
|| __put_user((void __user *)(unsigned long)up32.adata,
&user_params->adata)
|| __put_user((void __user *)(unsigned long)up32.text_data,
&user_params->text_data)
|| __put_user((void __user *)(unsigned long)up32.data_out,
&user_params->data_out))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (copy_from_user(up32.tag, user_params->tag,
DXDI_DIGEST_SIZE_MAX)
|| __get_user(up32.error_info, &user_params->error_info))
return -EFAULT;
if (copy_to_user((void __user *)arg, &up32, sizeof(up32)))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct mac_proc_params_32 {
u32 context_buf; /*[in] */
struct dxdi_mac_props props; /*[in] */
u32 data_in; /*[in] */
u32 data_in_size; /*[in] (octets) */
u8 mac[DXDI_DIGEST_SIZE_MAX]; /*[out] */
u8 mac_size; /*[out] (octets) */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_mac_proc(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct mac_proc_params_32 up32;
struct dxdi_mac_proc_params __user *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&user_params->context_buf)
|| copy_to_user(&user_params->props, &up32.props,
sizeof(up32.props))
|| __put_user((void __user *)(unsigned long)up32.data_in,
&user_params->data_in)
|| __put_user(up32.data_in_size, &user_params->data_in_size))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (copy_from_user(up32.mac, user_params->mac, DXDI_DIGEST_SIZE_MAX)
|| __get_user(up32.mac_size, &user_params->mac_size)
|| __get_user(up32.error_info, &user_params->error_info))
return -EFAULT;
if (copy_to_user((void __user *)arg, &up32, sizeof(up32)))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct hash_proc_params_32 {
u32 context_buf; /*[in] */
enum dxdi_hash_type hash_type; /*[in] */
u32 data_in; /*[in] */
u32 data_in_size; /*[in] (octets) */
u8 digest[DXDI_DIGEST_SIZE_MAX]; /*[out] */
u8 digest_size; /*[out] (octets) */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_hash_proc(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct hash_proc_params_32 up32;
struct dxdi_hash_proc_params __user *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&user_params->context_buf)
|| __put_user(up32.hash_type, &user_params->hash_type)
|| __put_user((void __user *)(unsigned long)up32.data_in,
&user_params->data_in)
|| __put_user(up32.data_in_size, &user_params->data_in_size))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (copy_from_user(up32.digest, user_params->digest,
DXDI_DIGEST_SIZE_MAX)
|| __get_user(up32.digest_size, &user_params->digest_size)
|| __get_user(up32.error_info, &user_params->error_info))
return -EFAULT;
if (copy_to_user((void __user *)arg, &up32, sizeof(up32)))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct sep_rpc_params_32 {
u16 agent_id; /*[in] */
u16 func_id; /*[in] */
struct dxdi_memref mem_refs[SEP_RPC_MAX_MEMREF_PER_FUNC]; /*[in] */
u32 rpc_params_size; /*[in] */
u32 rpc_params; /*[in] */
/* rpc_params to be copied into kernel DMA buffer */
enum seprpc_retcode error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_sep_rpc(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct sep_rpc_params_32 up32;
struct dxdi_sep_rpc_params __user *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (__put_user(up32.agent_id, &user_params->agent_id)
|| __put_user(up32.func_id, &user_params->func_id)
|| copy_to_user(user_params->mem_refs, up32.mem_refs,
sizeof(struct dxdi_memref)
* SEP_RPC_MAX_MEMREF_PER_FUNC)
|| __put_user(up32.rpc_params_size, &user_params->rpc_params_size)
|| __put_user((void __user *)(unsigned long)up32.rpc_params,
&user_params->rpc_params))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (ret)
return ret;
if (__get_user(up32.error_info, &user_params->error_info))
return -EFAULT;
if (put_user(up32.error_info,
&((struct sep_rpc_params_32 *)arg)->error_info))
return -EFAULT;
return 0;
}
#pragma pack(push)
#pragma pack(4)
struct register_mem4dma_params_32 {
struct dxdi_memref memref; /*[in] */
int memref_id; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_register_mem4dma(struct file *filp,
unsigned int cmd,
unsigned long arg)
{
struct register_mem4dma_params_32 up32;
struct dxdi_register_mem4dma_params __user *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (copy_to_user(&user_params->memref, &up32.memref,
sizeof(struct dxdi_memref)))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (ret)
return ret;
if (__get_user(up32.memref_id, &user_params->memref_id))
return -EFAULT;
if (copy_to_user((void __user *)arg, &up32, sizeof(up32)))
return -EFAULT;
return ret;
}
#pragma pack(push)
#pragma pack(4)
struct alloc_mem4dma_params_32 {
u32 size; /*[in] */
int memref_id; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_alloc_mem4dma(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct alloc_mem4dma_params_32 up32;
struct dxdi_alloc_mem4dma_params __user *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (__put_user(up32.size, &user_params->size))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (__get_user(up32.memref_id, &user_params->memref_id))
return -EFAULT;
if (copy_to_user((void __user *)arg, &up32, sizeof(up32)))
return -EFAULT;
return 0;
}
#pragma pack(push)
#pragma pack(4)
struct free_mem4dma_params_32 {
int memref_id; /*[in] */
};
#pragma pack(pop)
static int compat_sep_ioctl_free_mem4dma(struct file *filp, unsigned int cmd,
unsigned long arg)
{
return sep_ioctl(filp, cmd, arg);
}
#pragma pack(push)
#pragma pack(4)
struct aes_iv_params_32 {
u32 context_buf; /*[in] */
u8 iv_ptr[DXDI_AES_IV_SIZE]; /*[in]/[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_set_iv(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct aes_iv_params_32 up32;
struct dxdi_aes_iv_params *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&user_params->context_buf)
|| __copy_to_user(user_params->iv_ptr, up32.iv_ptr,
DXDI_AES_IV_SIZE))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
return ret;
}
static int compat_sep_ioctl_get_iv(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct aes_iv_params_32 up32;
struct dxdi_aes_iv_params *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (__put_user((void __user *)(unsigned long)up32.context_buf,
&user_params->context_buf)
|| __copy_to_user(&user_params->iv_ptr, &up32.iv_ptr,
DXDI_AES_IV_SIZE))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (ret)
return ret;
if (__copy_from_user(up32.iv_ptr, user_params->iv_ptr,
DXDI_AES_IV_SIZE))
return -EFAULT;
if (copy_to_user((void __user *)arg, &up32, sizeof(up32)))
return -EFAULT;
return 0;
}
#pragma pack(push)
#pragma pack(4)
struct sepapp_session_open_params_32 {
u8 app_uuid[DXDI_SEPAPP_UUID_SIZE]; /*[in] */
u32 auth_method; /*[in] */
u32 auth_data[3]; /*[in] */
struct dxdi_sepapp_params app_auth_data; /*[in/out] */
int session_id; /*[out] */
enum dxdi_sep_module sep_ret_origin; /*[out] */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_sepapp_session_open(struct file *filp,
unsigned int cmd,
unsigned long arg)
{
struct sepapp_session_open_params_32 up32;
struct dxdi_sepapp_session_open_params __user *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (copy_to_user(&user_params->app_uuid[0], &up32.app_uuid[0],
DXDI_SEPAPP_UUID_SIZE)
|| __put_user(up32.auth_method, &user_params->auth_method)
|| copy_to_user(user_params->auth_data, &up32.auth_data,
3 * sizeof(u32))
|| copy_to_user(&user_params->app_auth_data, &up32.app_auth_data,
sizeof(struct dxdi_sepapp_params)))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (ret)
return ret;
if (__copy_from_user(&up32.app_auth_data, &user_params->app_auth_data,
sizeof(struct dxdi_sepapp_params))
|| __get_user(up32.session_id, &user_params->session_id)
|| __get_user(up32.sep_ret_origin, &user_params->sep_ret_origin)
|| __get_user(up32.error_info, &user_params->error_info))
return -EFAULT;
if (copy_to_user((void __user *)arg, &up32, sizeof(up32)))
return -EFAULT;
return 0;
}
#pragma pack(push)
#pragma pack(4)
struct sepapp_session_close_params_32 {
int session_id; /*[in] */
};
#pragma pack(pop)
static int compat_sep_ioctl_sepapp_session_close(struct file *filp,
unsigned int cmd,
unsigned long arg)
{
return sep_ioctl(filp, cmd, arg);
}
#pragma pack(push)
#pragma pack(4)
struct sepapp_command_invoke_params_32 {
int session_id; /*[in] */
u32 command_id; /*[in] */
struct dxdi_sepapp_params command_params; /*[in/out] */
enum dxdi_sep_module sep_ret_origin; /*[out] */
u32 error_info; /*[out] */
};
#pragma pack(pop)
static int compat_sep_ioctl_sepapp_command_invoke(struct file *filp,
unsigned int cmd,
unsigned long arg)
{
struct sepapp_command_invoke_params_32 up32;
struct dxdi_sepapp_command_invoke_params __user *user_params;
int ret;
if (copy_from_user(&up32, (void __user *)arg, sizeof(up32)))
return -EFAULT;
user_params = compat_alloc_user_space(sizeof(*user_params));
if (!access_ok(VERIFY_WRITE, user_params, sizeof(*user_params)))
return -EFAULT;
if (__put_user(up32.session_id, &user_params->session_id)
|| __put_user(up32.command_id, &user_params->command_id)
|| copy_to_user(&user_params->command_params,
&up32.command_params,
sizeof(struct dxdi_sepapp_params)))
return -EFAULT;
ret = sep_ioctl(filp, cmd, (unsigned long)user_params);
if (__get_user(up32.sep_ret_origin, &user_params->sep_ret_origin)
|| __copy_from_user(&up32.command_params,
&user_params->command_params,
sizeof(struct dxdi_sepapp_params))
|| __get_user(up32.error_info, &user_params->error_info))
return -EFAULT;
if (copy_to_user((void __user *)arg, &up32, sizeof(up32)))
return -EFAULT;
return 0;
}
static sep_ioctl_compat_t *sep_compat_ioctls[] = {
/* Version info. commands */
[DXDI_IOC_NR_GET_VER_MAJOR] = compat_sep_ioctl_get_ver_major,
[DXDI_IOC_NR_GET_VER_MINOR] = compat_sep_ioctl_get_ver_minor,
/* Context size queries */
[DXDI_IOC_NR_GET_SYMCIPHER_CTX_SIZE] = compat_sep_ioctl_get_sym_cipher_ctx_size,
[DXDI_IOC_NR_GET_AUTH_ENC_CTX_SIZE] = compat_sep_ioctl_get_auth_enc_ctx_size,
[DXDI_IOC_NR_GET_MAC_CTX_SIZE] = compat_sep_ioctl_get_mac_ctx_size,
[DXDI_IOC_NR_GET_HASH_CTX_SIZE] = compat_sep_ioctl_get_hash_ctx_size,
/* Init context commands */
[DXDI_IOC_NR_SYMCIPHER_INIT] = compat_sep_ioctl_sym_cipher_init,
[DXDI_IOC_NR_AUTH_ENC_INIT] = compat_sep_ioctl_auth_enc_init,
[DXDI_IOC_NR_MAC_INIT] = compat_sep_ioctl_mac_init,
[DXDI_IOC_NR_HASH_INIT] = compat_sep_ioctl_hash_init,
/* Processing commands */
[DXDI_IOC_NR_PROC_DBLK] = compat_sep_ioctl_proc_dblk,
[DXDI_IOC_NR_FIN_PROC] = compat_sep_ioctl_fin_proc,
/* "Integrated" processing operations */
[DXDI_IOC_NR_SYMCIPHER_PROC] = compat_sep_ioctl_sym_cipher_proc,
[DXDI_IOC_NR_AUTH_ENC_PROC] = compat_sep_ioctl_auth_enc_proc,
[DXDI_IOC_NR_MAC_PROC] = compat_sep_ioctl_mac_proc,
[DXDI_IOC_NR_HASH_PROC] = compat_sep_ioctl_hash_proc,
/* SeP RPC */
[DXDI_IOC_NR_SEP_RPC] = compat_sep_ioctl_sep_rpc,
/* Memory registration */
[DXDI_IOC_NR_REGISTER_MEM4DMA] = compat_sep_ioctl_register_mem4dma,
[DXDI_IOC_NR_ALLOC_MEM4DMA] = compat_sep_ioctl_alloc_mem4dma,
[DXDI_IOC_NR_FREE_MEM4DMA] = compat_sep_ioctl_free_mem4dma,
/* SeP Applets API */
[DXDI_IOC_NR_SEPAPP_SESSION_OPEN] = compat_sep_ioctl_sepapp_session_open,
[DXDI_IOC_NR_SEPAPP_SESSION_CLOSE] = compat_sep_ioctl_sepapp_session_close,
[DXDI_IOC_NR_SEPAPP_COMMAND_INVOKE] = compat_sep_ioctl_sepapp_command_invoke,
/* Combined mode */
[DXDI_IOC_NR_COMBINED_INIT] = compat_sep_ioctl_combined_init,
[DXDI_IOC_NR_COMBINED_PROC_DBLK] = compat_sep_ioctl_combined_proc_dblk,
[DXDI_IOC_NR_COMBINED_PROC_FIN] = compat_sep_ioctl_combined_fin_proc,
[DXDI_IOC_NR_COMBINED_PROC] = compat_sep_ioctl_combined_proc,
/* AES IV set/get API */
[DXDI_IOC_NR_SET_IV] = compat_sep_ioctl_set_iv,
[DXDI_IOC_NR_GET_IV] = compat_sep_ioctl_get_iv,
};
long sep_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned int nr = _IOC_NR(cmd);
sep_ioctl_compat_t *callback = NULL;
int ret;
pr_debug("Calling the IOCTL compat %d\n", nr);
if (nr < ARRAY_SIZE(sep_compat_ioctls))
callback = sep_compat_ioctls[nr];
if (callback != NULL)
ret = (*callback) (filp, cmd, arg);
else
ret = sep_ioctl(filp, cmd, arg);
return ret;
}