blob: 9f15987f9116a2c152fd78c082b130ef44e18409 [file] [log] [blame]
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/mtd/mtd.h>
#include <linux/amlogic/aml_rsv.h>
#include <linux/amlogic/key_manage.h>
static struct meson_rsv_info_t *meson_rsv_key;
/*
* This function reads the u-boot keys.
*/
s32 amlnf_key_read(u8 *buf, u32 len, u32 *actual_length)
{
struct meson_rsv_info_t *aml_key = meson_rsv_key;
u8 *key_ptr = NULL;
u32 keysize = 0;
if (!meson_rsv_key) {
pr_info("%s(): amlnf key not ready yet!",
__func__);
return -EFAULT;
}
keysize = aml_key->size;
*actual_length = keysize;
if (len > keysize) {
/*
*No return here! keep consistent, should memset zero
*for the rest.
*/
pr_info("%s read key len exceed,len 0x%x,keysize 0x%x\n",
__func__, len, keysize);
memset(buf + keysize, 0, len - keysize);
}
key_ptr = kzalloc(aml_key->size, GFP_KERNEL);
if (!key_ptr)
return -ENOMEM;
meson_rsv_key_read(key_ptr, keysize);
memcpy(buf, key_ptr, min_t(int, keysize, len));
kfree(key_ptr);
return 0;
}
/*
* This function write the keys.
*/
s32 amlnf_key_write(u8 *buf, u32 len, u32 *actual_length)
{
struct meson_rsv_info_t *aml_key = meson_rsv_key;
/*struct mtd_info *mtd = aml_chip->mtd;*/
u8 *key_ptr = NULL;
u32 keysize = 0;
int error = 0;
if (!meson_rsv_key) {
pr_info("%s(): amlnf key not ready yet!",
__func__);
return -EFAULT;
}
keysize = aml_key->size;
*actual_length = keysize;
if (len > keysize) {
/*
*No return here! keep consistent, should memset zero
*for the rest.
*/
pr_info("%s write key len exceed,len 0x%x,keysize 0x%x\n",
__func__, len, keysize);
memset(buf + keysize, 0, len - keysize);
}
key_ptr = kzalloc(aml_key->size, GFP_KERNEL);
if (!key_ptr)
return -ENOMEM;
memcpy(key_ptr, buf, keysize);
error = meson_rsv_key_write(key_ptr, len);
kfree(key_ptr);
return error;
}
int amlnf_key_erase(void)
{
int ret = 0;
if (!meson_rsv_key) {
pr_info("%s amlnf not ready yet!\n", __func__);
return -1;
}
return ret;
}
int meson_rsv_register_unifykey(struct meson_rsv_info_t *key)
{
int ret = 0;
struct unifykey_type *uk_type;
uk_type = kzalloc(sizeof(*uk_type), GFP_KERNEL);
if (!uk_type)
return -ENOMEM;
uk_type->ops = kzalloc(sizeof(*uk_type->ops), GFP_KERNEL);
if (!uk_type->ops) {
ret = -ENOMEM;
goto exit;
}
/* avoid null */
meson_rsv_key = key;
/**need test**/
uk_type->storage_type = UNIFYKEY_STORAGE_TYPE_NAND;
/*
* pr_info("%s key func read: 0x%px, write: 0x%px\n",
* __func__, amlnf_key_read, amlnf_key_write);
*/
uk_type->ops->read = amlnf_key_read;
uk_type->ops->write = amlnf_key_write;
/*
*pr_info("%s key func read: 0x%px, write: 0x%px\n",
*__func__, uk_type->ops->read, uk_type->ops->write);
*/
ret = register_unifykey_types(uk_type);
kfree(uk_type->ops);
exit:
kfree(uk_type);
return ret;
}