773 lines
18 KiB
C
773 lines
18 KiB
C
/*
|
||
* (C) Copyright 2018 allwinnertech <wangwei@allwinnertech.com>
|
||
*
|
||
* SPDX-License-Identifier: GPL-2.0+
|
||
*/
|
||
|
||
#include <config.h>
|
||
#include <common.h>
|
||
#include <malloc.h>
|
||
//#include "sprite_storage_crypt.h"
|
||
#include <sunxi_board.h>
|
||
#include <sunxi_flash.h>
|
||
#include <memalign.h>
|
||
#include <securestorage.h>
|
||
|
||
int sunxi_secure_storage_erase(const char *item_name);
|
||
int sunxi_secure_storage_erase_data_only(const char *item_name);
|
||
|
||
static unsigned int secure_storage_inited = 0;
|
||
|
||
static unsigned int map_dirty;
|
||
|
||
static inline void set_map_dirty(void)
|
||
{
|
||
map_dirty = 1;
|
||
}
|
||
static inline void clear_map_dirty(void)
|
||
{
|
||
map_dirty = 0;
|
||
}
|
||
static inline int try_map_dirty(void)
|
||
{
|
||
return map_dirty;
|
||
}
|
||
|
||
static struct map_info secure_storage_map = { { 0 } };
|
||
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name : __probe_name_in_map ÔÚsecure storage mapÖвéÕÒÖ¸¶¨Ïî
|
||
*
|
||
*parmeters : buffer :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int __probe_name_in_map(unsigned char *buffer, const char *item_name,
|
||
int *len)
|
||
{
|
||
unsigned char *buf_start = buffer;
|
||
int index = 1;
|
||
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, name, MAP_KEY_NAME_SIZE);
|
||
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, length, MAP_KEY_DATA_SIZE);
|
||
int i, j;
|
||
|
||
while (*buf_start != '\0' && (buf_start - buffer) < SEC_BLK_SIZE) {
|
||
memset(name, 0, 64);
|
||
memset(length, 0, 32);
|
||
i = j = 0;
|
||
while (buf_start[i] != ':' && (buf_start[i] != '\0') &&
|
||
(&buf_start[i] - buffer) < SEC_BLK_SIZE &&
|
||
j < MAP_KEY_NAME_SIZE) {
|
||
name[j] = buf_start[i];
|
||
i++;
|
||
j++;
|
||
}
|
||
|
||
if (j >= MAP_KEY_NAME_SIZE)
|
||
return -1;
|
||
|
||
i++;
|
||
j = 0;
|
||
while ((buf_start[i] != ' ') && (buf_start[i] != '\0') &&
|
||
(&buf_start[i] - buffer) < SEC_BLK_SIZE &&
|
||
j < MAP_KEY_DATA_SIZE) {
|
||
length[j] = buf_start[i];
|
||
i++;
|
||
j++;
|
||
}
|
||
|
||
/* deal dirty data */
|
||
if ((&buf_start[i] - buffer) >= SEC_BLK_SIZE ||
|
||
j >= MAP_KEY_DATA_SIZE) {
|
||
return -1;
|
||
}
|
||
|
||
if (!strcmp(item_name, (const char *)name)) {
|
||
buf_start += strlen(item_name) + 1;
|
||
*len = simple_strtoul((const char *)length, NULL, 10);
|
||
|
||
if (strlen(item_name) ==
|
||
strlen(SECURE_STORAGE_DUMMY_KEY_NAME) &&
|
||
!memcmp(item_name, SECURE_STORAGE_DUMMY_KEY_NAME,
|
||
strlen(SECURE_STORAGE_DUMMY_KEY_NAME)) &&
|
||
*len == 0) {
|
||
/*
|
||
* if *len == 0 it is a actual DUMMY_KEY,
|
||
* a key happen to has same name should have a non-zero len
|
||
*/
|
||
} else {
|
||
pr_msg("name in map %s\n", name);
|
||
return index;
|
||
}
|
||
}
|
||
index++;
|
||
buf_start += strlen((const char *)buf_start) + 1;
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int __fill_name_in_map(unsigned char *buffer, const char *item_name,
|
||
int length)
|
||
{
|
||
unsigned char *buf_start = buffer;
|
||
int index = 1;
|
||
int name_len;
|
||
uint8_t write_back_buf[sizeof(struct map_info)];
|
||
int dummy_key_index = -1;
|
||
unsigned char *dummy_key_start = NULL;
|
||
unsigned char *write_back_start = NULL;
|
||
|
||
while (*buf_start != '\0' && (buf_start - buffer) < SEC_BLK_SIZE) {
|
||
name_len = 0;
|
||
while (buf_start[name_len] != ':' &&
|
||
(&buf_start[name_len] - buffer) < SEC_BLK_SIZE &&
|
||
name_len < MAP_KEY_NAME_SIZE)
|
||
name_len++;
|
||
|
||
/* deal dirty data */
|
||
if ((&buf_start[name_len] - buffer) >= SEC_BLK_SIZE ||
|
||
name_len >= MAP_KEY_NAME_SIZE) {
|
||
pr_msg("__fill_name_in_map: dirty map, memset 0\n");
|
||
memset(buffer, 0x0, SEC_BLK_SIZE);
|
||
buf_start = buffer;
|
||
index = 1;
|
||
break;
|
||
}
|
||
|
||
if (!memcmp((const char *)buf_start, item_name, name_len) &&
|
||
strlen(item_name) == name_len) {
|
||
pr_msg("name in map %s\n", buf_start);
|
||
return index;
|
||
}
|
||
|
||
if (name_len == strlen(SECURE_STORAGE_DUMMY_KEY_NAME) &&
|
||
!memcmp((const char *)buf_start,
|
||
SECURE_STORAGE_DUMMY_KEY_NAME, name_len) &&
|
||
dummy_key_index == -1) {
|
||
/*
|
||
* DUMMY_KEY could be replaced with the input key,
|
||
* but we dont know whether to do so at this point,
|
||
* save relate info first
|
||
*/
|
||
pr_msg("found dummy_key %s\n", buf_start);
|
||
dummy_key_index = index;
|
||
dummy_key_start = buf_start;
|
||
write_back_start = dummy_key_start +
|
||
strlen((const char *)buf_start) + 1;
|
||
memset(write_back_buf, 0, sizeof(write_back_buf));
|
||
memcpy((char *)write_back_buf, write_back_start,
|
||
4096 - (write_back_start - buffer));
|
||
}
|
||
index++;
|
||
buf_start += strlen((const char *)buf_start) + 1;
|
||
}
|
||
if ((index >= 32) && (dummy_key_index == -1))
|
||
return -1;
|
||
|
||
if (dummy_key_index != -1) {
|
||
/*use index reserved by DUMMY_KEY*/
|
||
sprintf((char *)dummy_key_start, "%s:%d", item_name, length);
|
||
write_back_start = dummy_key_start +
|
||
strlen((const char *)dummy_key_start) + 1;
|
||
memcpy(write_back_start, write_back_buf,
|
||
4096 - (write_back_start - buffer));
|
||
return dummy_key_index;
|
||
} else {
|
||
/* add new index */
|
||
sprintf((char *)buf_start, "%s:%d", item_name, length);
|
||
return index;
|
||
}
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
static int __discard_name_in_map(unsigned char *buffer, const char *item_name)
|
||
{
|
||
unsigned char *buf_start = buffer, *last_start;
|
||
int index = 1;
|
||
int name_len;
|
||
uint8_t write_back_buf[sizeof(struct map_info)];
|
||
|
||
while (*buf_start != '\0' && (buf_start - buffer) < SEC_BLK_SIZE) {
|
||
name_len = 0;
|
||
while (buf_start[name_len] != ':' &&
|
||
(&buf_start[name_len] - buffer) < SEC_BLK_SIZE &&
|
||
name_len < MAP_KEY_NAME_SIZE)
|
||
name_len++;
|
||
|
||
/* deal dirty data */
|
||
if ((&buf_start[name_len] - buffer) >= SEC_BLK_SIZE ||
|
||
name_len >= MAP_KEY_NAME_SIZE) {
|
||
return -1;
|
||
}
|
||
|
||
if (!memcmp((const char *)buf_start, item_name, name_len) &&
|
||
strlen(item_name) == name_len) {
|
||
/*
|
||
* replace discarded key with DUMMY_KEY, so following
|
||
* keys do not need to change their index
|
||
*/
|
||
memset(write_back_buf, 0, sizeof(write_back_buf));
|
||
last_start =
|
||
buf_start + strlen((const char *)buf_start) + 1;
|
||
memcpy(write_back_buf, last_start,
|
||
4096 - (last_start - buffer));
|
||
sprintf((char *)buf_start, "%s:%d",
|
||
SECURE_STORAGE_DUMMY_KEY_NAME, 0);
|
||
|
||
last_start =
|
||
buf_start + strlen((const char *)buf_start) + 1;
|
||
memcpy((char *)last_start, (char *)write_back_buf,
|
||
4096 - (last_start - buffer));
|
||
return index;
|
||
}
|
||
index++;
|
||
buf_start += strlen((const char *)buf_start) + 1;
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
int check_secure_storage_map(void *buffer)
|
||
{
|
||
struct map_info *map_buf = (struct map_info *)buffer;
|
||
|
||
if (map_buf->magic != STORE_OBJECT_MAGIC) {
|
||
pr_err("Item0 (Map) magic is bad\n");
|
||
return 2;
|
||
}
|
||
if (map_buf->crc !=
|
||
crc32(0, (void *)map_buf, sizeof(struct map_info) - 4)) {
|
||
pr_err("Item0 (Map) crc is fail [0x%x]\n", map_buf->crc);
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sunxi_secure_storage_init(void)
|
||
{
|
||
int ret;
|
||
|
||
if (!secure_storage_inited) {
|
||
ret = sunxi_secstorage_read(
|
||
0, (unsigned char *)&secure_storage_map, 4096);
|
||
if (ret < 0) {
|
||
pr_err("get secure storage map err\n");
|
||
|
||
return -1;
|
||
}
|
||
|
||
ret = check_secure_storage_map(&secure_storage_map);
|
||
if (ret == -1) {
|
||
if ((secure_storage_map.data[0] == 0xff) ||
|
||
(secure_storage_map.data[0] == 0x0))
|
||
memset(&secure_storage_map, 0, SEC_BLK_SIZE);
|
||
} else if (ret == 2) {
|
||
if ((secure_storage_map.data[0] == 0xff) ||
|
||
(secure_storage_map.data[0] == 0x00)) {
|
||
pr_msg("the secure storage map is empty\n");
|
||
memset(&secure_storage_map, 0, SEC_BLK_SIZE);
|
||
} else {
|
||
/* no things */
|
||
}
|
||
}
|
||
}
|
||
secure_storage_inited = 1;
|
||
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sunxi_secure_storage_exit(void)
|
||
{
|
||
int ret;
|
||
|
||
if (!secure_storage_inited) {
|
||
pr_err("%s err: secure storage has not been inited\n",
|
||
__func__);
|
||
|
||
return -1;
|
||
}
|
||
if (try_map_dirty()) {
|
||
secure_storage_map.magic = STORE_OBJECT_MAGIC;
|
||
secure_storage_map.crc = crc32(0, (void *)&secure_storage_map,
|
||
sizeof(struct map_info) - 4);
|
||
ret = sunxi_secstorage_write(
|
||
0, (unsigned char *)&secure_storage_map, 4096);
|
||
if (ret < 0) {
|
||
pr_err("write secure storage map\n");
|
||
|
||
return -1;
|
||
}
|
||
clear_map_dirty();
|
||
}
|
||
ret = sunxi_secstorage_flush();
|
||
secure_storage_inited = 0;
|
||
|
||
return ret;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sunxi_secure_storage_list(void)
|
||
{
|
||
int ret, index = 1;
|
||
unsigned char *buf_start = (unsigned char *)&secure_storage_map;
|
||
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 4096);
|
||
|
||
if (sunxi_secure_storage_init()) {
|
||
pr_err("%s secure storage init err\n", __func__);
|
||
|
||
return -1;
|
||
}
|
||
|
||
char name[64], length[32];
|
||
int i, j, len;
|
||
|
||
while (*buf_start != '\0') {
|
||
memset(name, 0, 64);
|
||
memset(length, 0, 32);
|
||
i = 0;
|
||
while (buf_start[i] != ':') {
|
||
name[i] = buf_start[i];
|
||
i++;
|
||
}
|
||
i++;
|
||
j = 0;
|
||
while ((buf_start[i] != ' ') && (buf_start[i] != '\0')) {
|
||
length[j] = buf_start[i];
|
||
i++;
|
||
j++;
|
||
}
|
||
|
||
pr_msg("name in map %s\n", name);
|
||
len = simple_strtoul((const char *)length, NULL, 10);
|
||
|
||
if (strlen(name) == strlen(SECURE_STORAGE_DUMMY_KEY_NAME) &&
|
||
!memcmp(name, SECURE_STORAGE_DUMMY_KEY_NAME,
|
||
strlen(SECURE_STORAGE_DUMMY_KEY_NAME)) &&
|
||
len == 0) {
|
||
/*dummy key, not used, goto next key*/
|
||
goto next_key;
|
||
}
|
||
|
||
ret = sunxi_secstorage_read(index, buffer, 4096);
|
||
if (ret < 0) {
|
||
pr_err("get secure storage index %d err\n", index);
|
||
|
||
return -1;
|
||
} else if (ret > 0) {
|
||
pr_msg("the secure storage index %d is empty\n", index);
|
||
|
||
return -1;
|
||
} else {
|
||
pr_force("%d data:\n", index);
|
||
sunxi_dump(buffer, len);
|
||
}
|
||
|
||
next_key:
|
||
index++;
|
||
buf_start += strlen((const char *)buf_start) + 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sunxi_secure_storage_probe(const char *item_name)
|
||
{
|
||
int ret;
|
||
int len;
|
||
|
||
if (!secure_storage_inited) {
|
||
pr_err("%s err: secure storage has not been inited\n",
|
||
__func__);
|
||
|
||
return -1;
|
||
}
|
||
ret = __probe_name_in_map((unsigned char *)&secure_storage_map,
|
||
item_name, &len);
|
||
if (ret < 0) {
|
||
pr_err("no item name %s in the map\n", item_name);
|
||
|
||
return -1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sunxi_secure_storage_read(const char *item_name, char *buffer,
|
||
int buffer_len, int *data_len)
|
||
{
|
||
int ret, index;
|
||
int len_in_store;
|
||
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer_to_sec, 4096);
|
||
|
||
if (!secure_storage_inited) {
|
||
pr_err("%s err: secure storage has not been inited\n",
|
||
__func__);
|
||
|
||
return -1;
|
||
}
|
||
index = __probe_name_in_map((unsigned char *)&secure_storage_map,
|
||
item_name, &len_in_store);
|
||
if (index < 0) {
|
||
pr_msg("no item name %s in the map\n", item_name);
|
||
|
||
return -2;
|
||
}
|
||
memset(buffer_to_sec, 0, 4096);
|
||
ret = sunxi_secstorage_read(index, buffer_to_sec, 4096);
|
||
if (ret < 0) {
|
||
pr_err("read secure storage block %d name %s err\n", index,
|
||
item_name);
|
||
|
||
return -3;
|
||
}
|
||
if (len_in_store > buffer_len) {
|
||
memcpy(buffer, buffer_to_sec, buffer_len);
|
||
} else {
|
||
memcpy(buffer, buffer_to_sec, len_in_store);
|
||
}
|
||
*data_len = len_in_store;
|
||
|
||
return 0;
|
||
}
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
|
||
int sunxi_secure_storage_write(const char *item_name, char *buffer, int length)
|
||
{
|
||
int ret, index;
|
||
int len = 0;
|
||
ALLOC_CACHE_ALIGN_BUFFER(char, tmp_buf, 4096);
|
||
|
||
if (!secure_storage_inited) {
|
||
pr_err("%s err: secure storage has not been inited\n",
|
||
__func__);
|
||
|
||
return -1;
|
||
}
|
||
|
||
index = __probe_name_in_map((unsigned char *)&secure_storage_map,
|
||
item_name, &len);
|
||
if (index < 0) {
|
||
index = __fill_name_in_map((unsigned char *)&secure_storage_map,
|
||
item_name, length);
|
||
if (index < 0) {
|
||
pr_err("write secure storage block %d name %s overrage\n",
|
||
index, item_name);
|
||
return -1;
|
||
}
|
||
} else {
|
||
pr_force("There is the same name in the secure storage, try to erase it\n");
|
||
if (len != length) {
|
||
pr_err("the length is not match with key has store in secure storage\n");
|
||
return -1;
|
||
} else {
|
||
if (sunxi_secure_storage_erase_data_only(item_name) <
|
||
0) {
|
||
pr_err("Erase item %s fail\n", item_name);
|
||
return -1;
|
||
}
|
||
}
|
||
}
|
||
memset(tmp_buf, 0x0, 4096);
|
||
memcpy(tmp_buf, buffer, length);
|
||
ret = sunxi_secstorage_write(index, (unsigned char *)tmp_buf, 4096);
|
||
if (ret < 0) {
|
||
pr_err("write secure storage block %d name %s err\n", index,
|
||
item_name);
|
||
|
||
return -1;
|
||
}
|
||
set_map_dirty();
|
||
pr_force("write secure storage: %d ok\n", index);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
|
||
int sunxi_secure_storage_erase_data_only(const char *item_name)
|
||
{
|
||
int ret, index, len;
|
||
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 4096);
|
||
|
||
if (!secure_storage_inited) {
|
||
pr_err("%s err: secure storage has not been inited\n",
|
||
__func__);
|
||
|
||
return -1;
|
||
}
|
||
index = __probe_name_in_map((unsigned char *)&secure_storage_map,
|
||
item_name, &len);
|
||
if (index < 0) {
|
||
pr_err("no item name %s in the map\n", item_name);
|
||
|
||
return -2;
|
||
}
|
||
memset(buffer, 0xff, 4096);
|
||
ret = sunxi_secstorage_write(index, buffer, 4096);
|
||
if (ret < 0) {
|
||
pr_err("erase secure storage block %d name %s err\n", index,
|
||
item_name);
|
||
|
||
return -1;
|
||
}
|
||
set_map_dirty();
|
||
pr_force("erase secure storage: %d data only ok\n", index);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
************************************************************************************************************
|
||
*
|
||
* function
|
||
*
|
||
* name :
|
||
*
|
||
* parmeters :
|
||
*
|
||
* return :
|
||
*
|
||
* note :
|
||
*
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
|
||
int sunxi_secure_storage_erase(const char *item_name)
|
||
{
|
||
int ret, index;
|
||
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 4096);
|
||
|
||
if (!secure_storage_inited) {
|
||
pr_err("%s err: secure storage has not been inited\n",
|
||
__func__);
|
||
|
||
return -1;
|
||
}
|
||
index = __discard_name_in_map((unsigned char *)&secure_storage_map,
|
||
item_name);
|
||
if (index < 0) {
|
||
pr_err("no item name %s in the map\n", item_name);
|
||
|
||
return -2;
|
||
}
|
||
memset(buffer, 0xff, 4096);
|
||
ret = sunxi_secstorage_write(index, buffer, 4096);
|
||
if (ret < 0) {
|
||
pr_err("erase secure storage block %d name %s err\n", index,
|
||
item_name);
|
||
|
||
return -1;
|
||
}
|
||
set_map_dirty();
|
||
pr_force("erase secure storage: %d ok\n", index);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
************************************************************************************************************
|
||
* function
|
||
* erase all the secure storage data
|
||
* name :
|
||
* parmeters :
|
||
* return :
|
||
* note :
|
||
*
|
||
************************************************************************************************************
|
||
*/
|
||
int sunxi_secure_storage_erase_all(void)
|
||
{
|
||
int ret;
|
||
if (!secure_storage_inited) {
|
||
sunxi_secure_storage_init();
|
||
}
|
||
|
||
memset(&secure_storage_map, 0x00, 4096);
|
||
ret = sunxi_secstorage_write(0, (unsigned char *)&secure_storage_map,
|
||
4096);
|
||
if (ret < 0) {
|
||
pr_err("erase secure storage block 0 err\n");
|
||
|
||
return -1;
|
||
}
|
||
pr_force("erase secure storage: 0 ok\n");
|
||
|
||
return 0;
|
||
}
|
||
|
||
int sunxi_secure_storage_write_or_read(const char *item_name, char *buffer,
|
||
int length, int dir)
|
||
{
|
||
int ret = 0;
|
||
int data_len;
|
||
ret = sunxi_secure_storage_init();
|
||
if (ret < 0) {
|
||
printf("secure storage init err\n");
|
||
return -1;
|
||
}
|
||
|
||
if (dir) {
|
||
ret = sunxi_secure_object_read(item_name, buffer, length,
|
||
&data_len);
|
||
if (ret < 0) {
|
||
sunxi_secure_storage_exit();
|
||
printf("erase secure storage failed\n");
|
||
ret = -1;
|
||
}
|
||
} else {
|
||
ret = sunxi_secure_object_write(item_name, buffer, length);
|
||
if (ret < 0) {
|
||
sunxi_secure_storage_exit();
|
||
printf("erase secure storage failed\n");
|
||
ret = -1;
|
||
}
|
||
}
|
||
|
||
sunxi_secure_storage_exit();
|
||
return ret;
|
||
}
|