117 lines
2.6 KiB
C
117 lines
2.6 KiB
C
|
/*
|
||
|
* Interface for TEE Driver
|
||
|
*
|
||
|
* Copyright (C) 2016 Samsung Electronics, Inc.
|
||
|
* Egor Uleyskiy, <e.uleyskiy@samsung.com>
|
||
|
*
|
||
|
* This software is licensed under the terms of the GNU General Public
|
||
|
* License version 2, as published by the Free Software Foundation, and
|
||
|
* may be copied, distributed, and modified under those terms.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*/
|
||
|
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/slab.h>
|
||
|
#include <crypto/hash_info.h>
|
||
|
#include "five_tee_interface.h"
|
||
|
#include "five_tee_api.h"
|
||
|
|
||
|
static struct five_tee_driver_fns *g_tee_driver_fn;
|
||
|
static char is_registered;
|
||
|
static DECLARE_RWSEM(usage_lock);
|
||
|
|
||
|
int register_five_tee_driver(
|
||
|
struct five_tee_driver_fns *tee_driver_fns)
|
||
|
{
|
||
|
int rc = 0;
|
||
|
|
||
|
if (!tee_driver_fns)
|
||
|
return -EINVAL;
|
||
|
|
||
|
down_write(&usage_lock);
|
||
|
if (is_registered) {
|
||
|
rc = -EACCES;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
g_tee_driver_fn = kmalloc(sizeof(*g_tee_driver_fn), GFP_KERNEL);
|
||
|
if (!g_tee_driver_fn) {
|
||
|
rc = -ENOMEM;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
g_tee_driver_fn->verify_hmac = tee_driver_fns->verify_hmac;
|
||
|
g_tee_driver_fn->sign_hmac = tee_driver_fns->sign_hmac;
|
||
|
is_registered = 1;
|
||
|
|
||
|
exit:
|
||
|
up_write(&usage_lock);
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(register_five_tee_driver);
|
||
|
|
||
|
void unregister_five_tee_driver(void)
|
||
|
{
|
||
|
down_write(&usage_lock);
|
||
|
if (is_registered) {
|
||
|
kfree(g_tee_driver_fn);
|
||
|
g_tee_driver_fn = NULL;
|
||
|
is_registered = 0;
|
||
|
}
|
||
|
up_write(&usage_lock);
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(unregister_five_tee_driver);
|
||
|
|
||
|
int verify_hash(enum hash_algo algo, const void *hash, size_t hash_len,
|
||
|
const void *label, size_t label_len,
|
||
|
const void *signature, size_t signature_len)
|
||
|
{
|
||
|
int rc = -ENODEV;
|
||
|
struct tee_iovec args = {
|
||
|
.algo = algo,
|
||
|
.hash = hash,
|
||
|
.hash_len = hash_len,
|
||
|
.label = label,
|
||
|
.label_len = label_len,
|
||
|
.signature = (void *)signature,
|
||
|
.signature_len = signature_len
|
||
|
};
|
||
|
|
||
|
down_read(&usage_lock);
|
||
|
if (is_registered)
|
||
|
rc = g_tee_driver_fn->verify_hmac(&args);
|
||
|
up_read(&usage_lock);
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int sign_hash(enum hash_algo algo, const void *hash, size_t hash_len,
|
||
|
const void *label, size_t label_len,
|
||
|
void *signature, size_t *signature_len)
|
||
|
{
|
||
|
int rc = -ENODEV;
|
||
|
struct tee_iovec args = {
|
||
|
.algo = algo,
|
||
|
.hash = hash,
|
||
|
.hash_len = hash_len,
|
||
|
.label = label,
|
||
|
.label_len = label_len,
|
||
|
.signature = signature,
|
||
|
.signature_len = *signature_len
|
||
|
};
|
||
|
|
||
|
down_read(&usage_lock);
|
||
|
if (is_registered)
|
||
|
rc = g_tee_driver_fn->sign_hmac(&args);
|
||
|
up_read(&usage_lock);
|
||
|
|
||
|
*signature_len = args.signature_len;
|
||
|
|
||
|
return rc;
|
||
|
}
|