957 lines
22 KiB
C
Executable File
957 lines
22 KiB
C
Executable File
/*
|
|
* (C) Copyright 2007-2013
|
|
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
|
* Jerry Wang <wangflord@allwinnertech.com>
|
|
*
|
|
* See file CREDITS for list of people who contributed to this
|
|
* project.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* 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.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*/
|
|
#include <config.h>
|
|
#include <common.h>
|
|
#include <malloc.h>
|
|
#include "sprite_storage_crypt.h"
|
|
|
|
extern int nand_secure_storage_read( int item, unsigned char *buf, unsigned int len);
|
|
extern int nand_secure_storage_write(int item, unsigned char *buf, unsigned int len);
|
|
|
|
extern int sunxi_flash_mmc_secread( int item, unsigned char *buf, unsigned int len);
|
|
extern int sunxi_flash_mmc_secread_backup( int item, unsigned char *buf, unsigned int len);
|
|
extern int sunxi_flash_mmc_secwrite( int item, unsigned char *buf, unsigned int len);
|
|
|
|
extern int sunxi_sprite_mmc_secwrite(int item ,unsigned char *buf,unsigned int nblock);
|
|
extern int sunxi_sprite_mmc_secread(int item ,unsigned char *buf,unsigned int nblock);
|
|
extern int sunxi_sprite_mmc_secread_backup(int item ,unsigned char *buf,unsigned int nblock);
|
|
|
|
int sunxi_secure_storage_erase(const char *item_name);
|
|
int sunxi_secure_storage_erase_data_only(const char *item_name);
|
|
|
|
//static unsigned char secure_storage_map[4096] = {0};
|
|
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 unsigned char _inner_buffer[4096+64]; /*align temp buffer*/
|
|
|
|
#define SEC_BLK_SIZE (4096)
|
|
struct map_info{
|
|
unsigned char data[SEC_BLK_SIZE - sizeof(int)*2];
|
|
unsigned int magic;
|
|
unsigned int crc;
|
|
}secure_storage_map;
|
|
|
|
static int check_secure_storage_key(char *buffer)
|
|
{
|
|
store_object_t *obj = (store_object_t *)buffer;
|
|
|
|
if( obj->magic != STORE_OBJECT_MAGIC ){
|
|
printf("Input object magic fail [0x%x]\n", obj->magic);
|
|
return -1 ;
|
|
}
|
|
|
|
if( obj->crc != crc32( 0 , (void *)obj, sizeof(*obj)-4 ) ){
|
|
printf("Input object crc fail [0x%x]\n", obj->crc);
|
|
return -1 ;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int check_secure_storage_map(char *buffer)
|
|
{
|
|
struct map_info *map_buf = (struct map_info *)buffer;
|
|
|
|
if (map_buf->magic != STORE_OBJECT_MAGIC)
|
|
{
|
|
printf("Item0 (Map) magic is bad\n");
|
|
return 2;
|
|
}
|
|
if (map_buf->crc != crc32( 0 , (void *)map_buf, sizeof(struct map_info)-4 ))
|
|
{
|
|
printf("Item0 (Map) crc is fail [0x%x]\n", map_buf->crc);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int mmc_secure_storage_read_key(int item, unsigned char *buf, unsigned int len)
|
|
{
|
|
unsigned char * align ;
|
|
unsigned int blkcnt;
|
|
int ret ,workmode;
|
|
|
|
if(((unsigned int)buf%32)){
|
|
align = (unsigned char *)(((unsigned int)_inner_buffer + 0x20)&(~0x1f)) ;
|
|
memset(align,0,4096);
|
|
}else {
|
|
align = buf ;
|
|
}
|
|
|
|
blkcnt = (len+511)/512 ;
|
|
|
|
workmode = uboot_spare_head.boot_data.work_mode;
|
|
if(workmode == WORK_MODE_BOOT || workmode == WORK_MODE_SPRITE_RECOVERY)
|
|
{
|
|
ret = (sunxi_flash_mmc_secread(item, align, blkcnt) == blkcnt) ? 0 : -1;
|
|
}
|
|
else if ((workmode & WORK_MODE_PRODUCT) || (workmode == 0x30))
|
|
{
|
|
ret = sunxi_sprite_mmc_secread(item, align, blkcnt);
|
|
}
|
|
else
|
|
{
|
|
printf("workmode=%d is err\n", workmode);
|
|
return -1;
|
|
}
|
|
if (!ret)
|
|
{
|
|
/*check copy 0 */
|
|
if (!check_secure_storage_key((char *)align)){
|
|
printf("the secure storage item%d copy0 is good\n",item);
|
|
goto ok ; /*copy 0 pass*/
|
|
}
|
|
printf("the secure storage item%d copy0 is bad\n", item);
|
|
}
|
|
|
|
// read backup
|
|
memset(align, 0x0, len);
|
|
printf("read item%d copy1\n", item);
|
|
if(workmode == WORK_MODE_BOOT || workmode == WORK_MODE_SPRITE_RECOVERY)
|
|
{
|
|
ret = (sunxi_flash_mmc_secread_backup(item, align, blkcnt) == blkcnt) ? 0 : -1;
|
|
}
|
|
else if ((workmode & WORK_MODE_PRODUCT) || (workmode == 0x30))
|
|
{
|
|
ret = sunxi_sprite_mmc_secread_backup(item, align, blkcnt);
|
|
}
|
|
else
|
|
{
|
|
printf("workmode=%d is err\n", workmode);
|
|
return -1;
|
|
}
|
|
if (!ret)
|
|
{
|
|
/*check copy 1 */
|
|
if (!check_secure_storage_key((char *)align)){
|
|
printf("the secure storage item%d copy1 is good\n",item);
|
|
goto ok ; /*copy 1 pass*/
|
|
}
|
|
printf("the secure storage item%d copy1 is bad\n", item);
|
|
}
|
|
|
|
printf("sunxi_secstorage_read fail\n");
|
|
return -1;
|
|
|
|
ok:
|
|
if(((unsigned int)buf%32))
|
|
memcpy(buf,align,len);
|
|
return 0 ;
|
|
}
|
|
|
|
static int mmc_secure_storage_read_map(int item, unsigned char *buf, unsigned int len)
|
|
{
|
|
int have_map_copy0 ;
|
|
unsigned char * align ;
|
|
unsigned int blkcnt;
|
|
int ret ,workmode;
|
|
char * map_copy0_buf;
|
|
|
|
if(((unsigned int)buf%32)){
|
|
align = (unsigned char *)(((unsigned int)_inner_buffer + 0x20)&(~0x1f)) ;
|
|
memset(align,0,4096);
|
|
}else {
|
|
align = buf ;
|
|
}
|
|
|
|
blkcnt = (len+511)/512 ;
|
|
|
|
map_copy0_buf=(char *)malloc(blkcnt*512);
|
|
if(!map_copy0_buf){
|
|
printf("out of memory\n");
|
|
return -1 ;
|
|
}
|
|
|
|
printf("read item%d copy0\n", item);
|
|
workmode = uboot_spare_head.boot_data.work_mode;
|
|
if(workmode == WORK_MODE_BOOT || workmode == WORK_MODE_SPRITE_RECOVERY)
|
|
{
|
|
ret = (sunxi_flash_mmc_secread(item, align, blkcnt) == blkcnt) ? 0 : -1;
|
|
}
|
|
else if ((workmode & WORK_MODE_PRODUCT) || (workmode == 0x30))
|
|
{
|
|
ret = sunxi_sprite_mmc_secread(item, align, blkcnt);
|
|
}
|
|
else
|
|
{
|
|
printf("workmode=%d is err\n", workmode);
|
|
return -1;
|
|
}
|
|
if (!ret)
|
|
{
|
|
/*read ok*/
|
|
ret = check_secure_storage_map((char *)align);
|
|
if (ret == 0)
|
|
{
|
|
printf("the secure storage item0 copy0 is good\n");
|
|
goto ok ; /*copy 0 pass*/
|
|
}else if (ret == 2){
|
|
memcpy(map_copy0_buf, align, len);
|
|
have_map_copy0 = 1;
|
|
printf("the secure storage item0 copy0 is bad\n");
|
|
}else
|
|
printf("the secure storage item0 copy 0 crc fail, the data is bad\n");
|
|
}
|
|
|
|
// read backup
|
|
memset(align, 0x0, len);
|
|
printf("read item%d copy1\n", item);
|
|
if(workmode == WORK_MODE_BOOT || workmode == WORK_MODE_SPRITE_RECOVERY)
|
|
{
|
|
ret = (sunxi_flash_mmc_secread(item, align, blkcnt) == blkcnt) ? 0 : -1;
|
|
}
|
|
else if ((workmode & WORK_MODE_PRODUCT) || (workmode == 0x30))
|
|
{
|
|
ret = sunxi_sprite_mmc_secread(item, align, blkcnt);
|
|
}
|
|
else
|
|
{
|
|
printf("workmode=%d is err\n", workmode);
|
|
return -1;
|
|
}
|
|
if (!ret)
|
|
{
|
|
ret = check_secure_storage_map((char *)align);
|
|
if (ret == 0){
|
|
printf("the secure storage item0 copy1 is good\n");
|
|
goto ok ;
|
|
}else if (ret == 2){
|
|
if (have_map_copy0 && !memcmp(map_copy0_buf, align, len))
|
|
{
|
|
printf("the secure storage item0 copy0 == copy1, the data is good\n");
|
|
goto ok ; /*copy have no magic and crc*/
|
|
}
|
|
else
|
|
{
|
|
printf("the secure storage item0 copy0 != copy1, the data is bad\n");
|
|
free(map_copy0_buf);
|
|
return -1;
|
|
}
|
|
}else{
|
|
printf("the secure storage item0 copy 1 crc fail, the data is bad\n");
|
|
free(map_copy0_buf);
|
|
return -1;
|
|
}
|
|
}
|
|
printf("unknown error happen in item 0 read\n");
|
|
free(map_copy0_buf);
|
|
return -1 ;
|
|
|
|
ok:
|
|
if(((unsigned int)buf%32))
|
|
memcpy(buf,align,len);
|
|
free(map_copy0_buf);
|
|
return 0 ;
|
|
}
|
|
|
|
/*
|
|
************************************************************************************************************
|
|
*
|
|
* function
|
|
*
|
|
* name :
|
|
*
|
|
* parmeters :
|
|
*
|
|
* return :
|
|
*
|
|
* note :
|
|
*
|
|
*
|
|
************************************************************************************************************
|
|
*/
|
|
int sunxi_secstorage_read(int item, unsigned char *buf, unsigned int len)
|
|
{
|
|
|
|
if(!uboot_spare_head.boot_data.storage_type)
|
|
return nand_secure_storage_read(item, buf, len);
|
|
else{
|
|
if (item == 0)
|
|
return mmc_secure_storage_read_map(item, buf, len);
|
|
else
|
|
return mmc_secure_storage_read_key(item, buf, len);
|
|
}
|
|
}
|
|
/*
|
|
************************************************************************************************************
|
|
*
|
|
* function
|
|
*
|
|
* name :
|
|
*
|
|
* parmeters :
|
|
*
|
|
* return :
|
|
*
|
|
* note :
|
|
*
|
|
*
|
|
************************************************************************************************************
|
|
*/
|
|
int sunxi_secstorage_write(int item, unsigned char *buf, unsigned int len)
|
|
{
|
|
unsigned char * align ;
|
|
unsigned int blkcnt;
|
|
int workmode;
|
|
|
|
if(!uboot_spare_head.boot_data.storage_type)
|
|
return nand_secure_storage_write(item, buf, len);
|
|
else{
|
|
if(((unsigned int)buf%32)){ // input buf not align
|
|
align = (unsigned char *)(((unsigned int)_inner_buffer + 0x20)&(~0x1f)) ;
|
|
memcpy(align, buf, len);
|
|
}else
|
|
align=buf;
|
|
|
|
blkcnt = (len+511)/512 ;
|
|
workmode = uboot_spare_head.boot_data.work_mode;
|
|
if(workmode == WORK_MODE_BOOT || workmode == WORK_MODE_SPRITE_RECOVERY)
|
|
{
|
|
return (sunxi_flash_mmc_secwrite(item, align, blkcnt) == blkcnt) ? 0 : -1;
|
|
}
|
|
else if((workmode & WORK_MODE_PRODUCT) || (workmode == 0x30))
|
|
{
|
|
return sunxi_sprite_mmc_secwrite(item, align, blkcnt);
|
|
}
|
|
else
|
|
{
|
|
printf("workmode=%d is err\n", workmode);
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
************************************************************************************************************
|
|
*
|
|
* function
|
|
*
|
|
* name :
|
|
*
|
|
* parmeters :
|
|
*
|
|
* 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;
|
|
char name[64], length[32];
|
|
int i,j;
|
|
|
|
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++;
|
|
}
|
|
|
|
if(!strcmp(item_name, (const char *)name))
|
|
{
|
|
buf_start += strlen(item_name) + 1;
|
|
*len = simple_strtoul((const char *)length, NULL, 10);
|
|
printf("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;
|
|
|
|
while(*buf_start != '\0')
|
|
{
|
|
|
|
name_len = 0;
|
|
while(buf_start[name_len] != ':')
|
|
name_len ++;
|
|
if(!memcmp((const char *)buf_start, item_name, name_len))
|
|
{
|
|
printf("name in map %s\n", buf_start);
|
|
return index;
|
|
}
|
|
index ++;
|
|
buf_start += strlen((const char *)buf_start) + 1;
|
|
}
|
|
if(index >= 32)
|
|
return -1;
|
|
|
|
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;
|
|
|
|
while(*buf_start != '\0')
|
|
{
|
|
|
|
name_len = 0;
|
|
while(buf_start[name_len] != ':')
|
|
name_len ++;
|
|
if(!memcmp((const char *)buf_start, item_name, name_len))
|
|
{
|
|
last_start = buf_start + strlen((const char *)buf_start) + 1;
|
|
if(*last_start == '\0')
|
|
{
|
|
memset(buf_start, 0, strlen((const char *)buf_start));
|
|
}
|
|
else
|
|
{
|
|
memcpy(buf_start, last_start, 4096 - (last_start - buffer));
|
|
}
|
|
|
|
return index;
|
|
}
|
|
index ++;
|
|
buf_start += strlen((const char *)buf_start) + 1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
************************************************************************************************************
|
|
*
|
|
* 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)
|
|
{
|
|
printf("get secure storage map err\n");
|
|
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
if((secure_storage_map.data[0] == 0xff) || (secure_storage_map.data[0] == 0x0))
|
|
{
|
|
printf("the secure storage map is empty\n");
|
|
memset(&secure_storage_map, 0, 4096);
|
|
}
|
|
}
|
|
}
|
|
secure_storage_inited = 1;
|
|
|
|
return 0;
|
|
}
|
|
/*
|
|
************************************************************************************************************
|
|
*
|
|
* function
|
|
*
|
|
* name :
|
|
*
|
|
* parmeters :
|
|
*
|
|
* return :
|
|
*
|
|
* note :
|
|
*
|
|
*
|
|
************************************************************************************************************
|
|
*/
|
|
int sunxi_secure_storage_exit(void)
|
|
{
|
|
int ret;
|
|
|
|
if(!secure_storage_inited)
|
|
{
|
|
printf("%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)
|
|
{
|
|
printf("write secure storage map\n");
|
|
|
|
return -1;
|
|
}
|
|
clear_map_dirty();
|
|
}
|
|
secure_storage_inited = 0;
|
|
|
|
return 0;
|
|
}
|
|
/*
|
|
************************************************************************************************************
|
|
*
|
|
* function
|
|
*
|
|
* name :
|
|
*
|
|
* parmeters :
|
|
*
|
|
* return :
|
|
*
|
|
* note :
|
|
*
|
|
*
|
|
************************************************************************************************************
|
|
*/
|
|
int sunxi_secure_storage_list(void)
|
|
{
|
|
int ret, index = 1;
|
|
unsigned char *buf_start = (unsigned char *)&secure_storage_map;
|
|
unsigned char buffer[4096];
|
|
|
|
if(sunxi_secure_storage_init())
|
|
{
|
|
printf("%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++;
|
|
}
|
|
|
|
printf("name in map %s\n", name);
|
|
len = simple_strtoul((const char *)length, NULL, 10);
|
|
|
|
ret = sunxi_secstorage_read(index, buffer, 4096);
|
|
if(ret < 0)
|
|
{
|
|
printf("get secure storage index %d err\n", index);
|
|
|
|
return -1;
|
|
}
|
|
else if(ret > 0)
|
|
{
|
|
printf("the secure storage index %d is empty\n", index);
|
|
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
printf("%d data:\n", index);
|
|
sunxi_dump(buffer, len);
|
|
}
|
|
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)
|
|
{
|
|
printf("%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)
|
|
{
|
|
printf("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;
|
|
unsigned char buffer_to_sec[4096];
|
|
|
|
if(!secure_storage_inited)
|
|
{
|
|
printf("%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)
|
|
{
|
|
printf("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)
|
|
{
|
|
printf("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;
|
|
char tmp_buf[4096];
|
|
|
|
if(!secure_storage_inited)
|
|
{
|
|
printf("%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)
|
|
{
|
|
printf("write secure storage block %d name %s overrage\n", index, item_name);
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("There is the same name in the secure storage, try to erase it\n");
|
|
if(len != length)
|
|
{
|
|
printf("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 )
|
|
{
|
|
printf("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)
|
|
{
|
|
printf("write secure storage block %d name %s err\n", index, item_name);
|
|
|
|
return -1;
|
|
}
|
|
set_map_dirty();
|
|
printf("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;
|
|
unsigned char buffer[4096];
|
|
|
|
if(!secure_storage_inited)
|
|
{
|
|
printf("%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)
|
|
{
|
|
printf("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)
|
|
{
|
|
printf("erase secure storage block %d name %s err\n", index, item_name);
|
|
|
|
return -1;
|
|
}
|
|
set_map_dirty();
|
|
printf("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;
|
|
unsigned char buffer[4096];
|
|
|
|
if(!secure_storage_inited)
|
|
{
|
|
printf("%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)
|
|
{
|
|
printf("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)
|
|
{
|
|
printf("erase secure storage block %d name %s err\n", index, item_name);
|
|
|
|
return -1;
|
|
}
|
|
set_map_dirty();
|
|
printf("erase secure storage: %d ok\n", index);
|
|
|
|
return 0;
|
|
}
|
|
/*
|
|
************************************************************************************************************
|
|
*
|
|
* function
|
|
*
|
|
* name :
|
|
*
|
|
* parmeters :
|
|
*
|
|
* return :
|
|
*
|
|
* note :
|
|
*
|
|
*
|
|
************************************************************************************************************
|
|
*/
|
|
|
|
int sunxi_secure_storage_erase_all(void)
|
|
{
|
|
int ret;
|
|
|
|
if(!secure_storage_inited)
|
|
{
|
|
printf("%s err: secure storage has not been inited\n", __func__);
|
|
|
|
return -1;
|
|
}
|
|
memset(&secure_storage_map, 0xff, 4096);
|
|
ret = sunxi_secstorage_write(0, (unsigned char *)&secure_storage_map, 4096);
|
|
if(ret<0)
|
|
{
|
|
printf("erase secure storage block 0 err\n");
|
|
|
|
return -1;
|
|
}
|
|
printf("erase secure storage: 0 ok\n");
|
|
|
|
return 0;
|
|
}
|