/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
int sunxi_secure_storage_list(void)
{
	int ret, index = 1;
	unsigned char *buf_start = 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;
}
예제 #2
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
int do_read_from_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
#ifdef CONFIG_SUNXI_SECURE_STORAGE
	if(argc == 1)
	{
		return sunxi_secure_storage_list();
	}
	if(argc == 2)
	{
		char buffer[4096];
		int ret, data_len;

		memset(buffer, 0, 4096);
		ret = sunxi_secure_storage_init();
		if(ret < 0)
		{
			printf("%s secure storage init err\n", __func__);

			return -1;
		}
		ret = sunxi_secure_object_read(argv[1], buffer, 4096, &data_len);
		if(ret < 0)
		{
			printf("private data %s is not exist\n", argv[1]);

			return -1;
		}
		printf("private data:\n");
		sunxi_dump(buffer, strlen((const char *)buffer));

		return 0;
	}
#endif
	return -1;
}
예제 #3
0
int smc_load_sst_test(void)
{
	char buffer[4096],
		 en_buffer[4096];
	unsigned int retLen  ;
	store_object_t *so ;
	int ret ;

	/*call to encrypt data */
	ret = sunxi_secure_storage_read("Widevine", buffer, 4096, (int *)&retLen);
	if(ret <0 ){
		printf("read Widevine secure object fail\n");
		return -1 ;
	}

	printf("Widevine data: \n");
	sunxi_dump(buffer, retLen);

	so = (store_object_t *)buffer;
	printf("so name %s\n",so->name);
	ret = smc_load_sst_encrypt("Widevine",
			(char *)so->data,so->actual_len, 
			en_buffer, &retLen);
	if(ret <0){
		printf("smc load sst encrypt fail\n");
		return -1 ;
	}

	printf("Encrypt Widevine data: \n");
	sunxi_dump(en_buffer, retLen);

	memcpy(so->data, en_buffer, retLen);
	so->actual_len = retLen;
	so->re_encrypt = STORE_REENCRYPT_MAGIC;
	so->crc = crc32( 0 , (void *)so, sizeof(*so)-4 ); 

	printf("so name %s\n",so->name);
	/*call to decrypt data to secure memory*/
	ret = smc_load_sst_decrypt(so->name, (char *)so->data,so->actual_len);
	if(ret <0){
		printf("smc_load sst decrypt fail\n");
		return -1 ;
	}
	return 0 ;

}
예제 #4
0
static int sunxi_secure_object_list(void)
{
	int ret, index = 1;
	unsigned char *buf_start = _inner_buffer;
	unsigned char  buffer[4096];
	int retLen;

	if(sunxi_secure_storage_init())
	{
		printf("%s secure storage init err\n", __func__);

		return -1;
	}
	
	if( sunxi_secstorage_read( 0 , _inner_buffer,4096  )<0){
		printf("read map fail\n");
		return -1 ;
	}

	char  name[64], length[32];
	int   i,j, len;

	printf("Map: \n");
	sunxi_dump(_inner_buffer,0x100 );

	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++;
		}

		len = simple_strtoul((const char *)length, NULL, 10);
		printf("name in map %s, len 0x%x\n", name,len);
		memset(buffer, 0, 4096);

		if( !strncmp("key_burned_flag", name, strlen("key_burned_flag") ))
			ret = sunxi_secure_storage_read(name, (void *)buffer,4096, &retLen);
		else
			ret = sunxi_secure_object_read(name, (void *)buffer, 4096, &retLen);
		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, retLen);
		}
		index ++;
		buf_start += strlen((const char *)buf_start) + 1;
	}

	return 0;
}
예제 #5
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
static int sunxi_pburn_state_loop(void  *buffer)
{
	static struct umass_bbb_cbw_t  *cbw;
	static struct umass_bbb_csw_t  csw;
	static uint pburn_flash_start = 0;
	//static uint pburn_flash_sectors = 0;
	int    ret;
	sunxi_ubuf_t *sunxi_ubuf = (sunxi_ubuf_t *)buffer;

	switch(sunxi_usb_pburn_status)
	{
		case SUNXI_USB_PBURN_IDLE:
			if(sunxi_ubuf->rx_ready_for_data == 1)
			{
				sunxi_usb_pburn_status = SUNXI_USB_PBURN_SETUP;
			}

			break;

		case SUNXI_USB_PBURN_SETUP:

			sunxi_usb_dbg("SUNXI_USB_PBURN_SETUP\n");

			if(sunxi_ubuf->rx_req_length != sizeof(struct umass_bbb_cbw_t))
			{
				printf("sunxi usb error: received bytes 0x%x is not equal cbw struct size 0x%zx\n", sunxi_ubuf->rx_req_length, sizeof(struct umass_bbb_cbw_t));

				sunxi_ubuf->rx_ready_for_data = 0;
				sunxi_usb_pburn_status = SUNXI_USB_PBURN_IDLE;

				break;
			}

			cbw = (struct umass_bbb_cbw_t *)sunxi_ubuf->rx_req_buffer;
			if(CBWSIGNATURE != cbw->dCBWSignature)
			{
				printf("sunxi usb error: the cbw signature 0x%x is bad, need 0x%x\n", cbw->dCBWSignature, CBWSIGNATURE);

				sunxi_ubuf->rx_ready_for_data = 0;
				sunxi_usb_pburn_status = SUNXI_USB_PBURN_IDLE;

				break;
			}

			csw.dCSWSignature = CSWSIGNATURE;
			csw.dCSWTag 	  = cbw->dCBWTag;

#if defined(SUNXI_USB_30)
			sunxi_usb_pburn_status_enable = 1;
#endif
			sunxi_usb_dbg("usb cbw command = 0x%x\n", cbw->CBWCDB[0]);

			switch(cbw->CBWCDB[0])
	  		{
#ifdef  CONFIG_SUNXI_SECURE_STORAGE
				case 0xf0:			//自定义命令,用于烧录用户数据
	  				sunxi_usb_dbg("usb burn secure storage data\n");
	  				printf("usb command = %d\n", cbw->CBWCDB[1]);
	  				switch(cbw->CBWCDB[1])
	  				{
	  					case 0:				//握手
	  					{
	  						__usb_handshake_sec_t  *handshake = (__usb_handshake_sec_t *)trans_data.base_send_buffer;

                            memset(handshake, 0, sizeof(__usb_handshake_sec_t));
							strcpy(handshake->magic, "usb_burn_handshake");
							sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;

		  					trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_sec_t));

							sunxi_usb_burn_from_boot_setup = 1;

							private_data_ext_buff = (u8 *)malloc(4 * 1024 * 1024);
							if(private_data_ext_buff == NULL)
							{
								printf("there is no memorfy to store all user key data\n");

								csw.bCSWStatus = -1;
							}
							else
		  					{
		  						csw.bCSWStatus = 0;
		  						sunxi_usb_burn_from_boot_handshake = 1;
		  					}
		  					private_data_ext_buff_step = private_data_ext_buff;
						}
						break;

						case 1:				//小机端接收数据
						{
							trans_data.recv_size = cbw->dCBWDataTransferLength;

                            sunxi_usb_pburn_write_enable = 0;
							sunxi_udc_start_recv_by_dma(private_data_ext_buff_step, trans_data.recv_size);	//start dma to receive data

							printf("recv_size=%d\n", trans_data.recv_size);
							sunxi_dump(private_data_ext_buff, trans_data.recv_size);

					        sunxi_usb_pburn_status = SUNXI_USB_PBURN_RECEIVE_NULL;
						}
						break;

						case 2:             //工具端声明数据传输已经完毕,要求获取烧录状态
						{
							__usb_handshake_ext_t  *handshake = (__usb_handshake_ext_t *)trans_data.base_send_buffer;

							memset(handshake, 0, sizeof(__usb_handshake_ext_t));
							//strcpy(handshake->magic, "usb_burn_receive_data_all");
							sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;

							printf("recv_size=%d\n", trans_data.recv_size);
							sunxi_dump(private_data_ext_buff, trans_data.recv_size);

							int ret = __sunxi_burn_key(private_data_ext_buff, trans_data.recv_size);

		  					trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_ext_t));
		  					//开始根据数据类型进行烧录动作

		  					if(!ret)	//数据烧写成功
		  					{
		  						strcpy(handshake->magic, "usb_burn_success");
		  						csw.bCSWStatus = 0;
		  					}
		  					else	//数据烧写失败
		  					{
		  						strcpy(handshake->magic, "usb_burn_error");
		  						csw.bCSWStatus = -1;
		  					}
		  					if(private_data_ext_buff)
		  					{
		  						free(private_data_ext_buff);
		  					}
						}
						break;

//						case 3:             //小机端读取每个key
//						{
//							uint start, sectors;
//							uint offset;
//
//							start   = *(int *)(cbw->CBWCDB + 4);		//读数据的偏移量
//							sectors = *(int *)(cbw->CBWCDB + 8);		//扇区数;
//
//							trans_data.send_size 	   = min(cbw->dCBWDataTransferLength, sectors * 512);
//							trans_data.act_send_buffer = (uint)trans_data.base_send_buffer;
//
//							offset = burn_private_start;
//							ret = sunxi_flash_read(start + offset, sectors, trans_data.base_send_buffer);
//							if(!ret)
//							{
//								printf("sunxi flash read err: start,0x%x sectors 0x%x\n", start, sectors);
//
//								csw.bCSWStatus = 1;
//							}
//							else
//							{
//								csw.bCSWStatus = 0;
//							}
//
//							sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;
//						}
//						break;

						case 4:				//关闭usb
						{
							__usb_handshake_ext_t  *handshake = (__usb_handshake_ext_t *)trans_data.base_send_buffer;

                            memset(handshake, 0, sizeof(__usb_handshake_ext_t));
							strcpy(handshake->magic, "usb_burn_finish");

							trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_ext_t));

							sunxi_udc_send_data((void *)trans_data.act_send_buffer, trans_data.send_size);

		  					csw.bCSWStatus = 0;

		  					sunxi_usb_pburn_status = SUNXI_USB_PBURN_EXIT;

						}
						break;

						case 5:
						{
							__usb_handshake_ext_t  *handshake = (__usb_handshake_ext_t *)trans_data.base_send_buffer;

							memset(handshake, 0, sizeof(__usb_handshake_ext_t));
							strcpy(handshake->magic, "usb_burn_saved");

							trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_ext_t));

		  					csw.bCSWStatus = 0;

		  					sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;
		  					if(sunxi_secure_storage_write("key_burned_flag", "key_burned", strlen("key_burned")))
		  					{
		  						printf("save burned flag err\n");

		  						csw.bCSWStatus = -1;
		  					}
		  					sunxi_secure_storage_exit();
						}
						break;

					default:
						break;
	  			}
	  			break;
#endif

	  			case 0xf3:			//自定义命令,用于烧录用户数据
	  				sunxi_usb_dbg("usb burn private\n");
	  				printf("usb command = %d\n", cbw->CBWCDB[1]);
	  				switch(cbw->CBWCDB[1])
	  				{
	  					case 0:				//握手
	  					{
	  						__usb_handshake_t  *handshake = (__usb_handshake_t *)trans_data.base_send_buffer;

							burn_private_start = sunxi_partition_get_offset_byname("private");
							burn_private_len   = sunxi_partition_get_size_byname("private");

							if(!burn_private_start)
							{
								printf("private partition is not exist\n");

								csw.bCSWStatus = -1;
							}
							else
							{
								csw.bCSWStatus = 0;
							}

                            memset(handshake, 0, sizeof(__usb_handshake_t));
							strcpy(handshake->magic, "usb_burn_handshake");
							handshake->sizelo = burn_private_len;
							handshake->sizehi = 0;
							sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;

							sunxi_usb_burn_from_boot_setup = 1;
							sunxi_usb_burn_from_boot_handshake = 1;

		  					trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_t));
						}
						break;

						case 1:				//小机端接收数据
						{
							//pburn_flash_sectors  = *(int *)(cbw->CBWCDB + 8);
							//pburn_flash_start    = *(int *)(cbw->CBWCDB + 4);
							memcpy(&pburn_flash_start,(cbw->CBWCDB + 4),4);

							trans_data.recv_size = cbw->dCBWDataTransferLength;
							trans_data.act_recv_buffer = trans_data.base_recv_buffer;

                            pburn_flash_start += burn_private_start;
                            sunxi_usb_pburn_write_enable = 0;
							sunxi_udc_start_recv_by_dma(trans_data.act_recv_buffer, trans_data.recv_size);	//start dma to receive data

					        sunxi_usb_pburn_status = SUNXI_USB_PBURN_RECEIVE_DATA;
						}
						break;

						case 3:             //小机端发送数据
						{
							uint start, sectors;

							//start   = *(int *)(cbw->CBWCDB + 4);		//读数据的偏移量
							//sectors = *(int *)(cbw->CBWCDB + 8);		//扇区数;
							memcpy(&start,(cbw->CBWCDB + 4),4);
							memcpy(&sectors,(cbw->CBWCDB + 8),4);

							printf("start=%d, sectors=%d\n", start, sectors);

							trans_data.send_size 	   = min(cbw->dCBWDataTransferLength, sectors * 512);
							trans_data.act_send_buffer = trans_data.base_send_buffer;

							printf("send size=%d\n", trans_data.send_size);

							ret = sunxi_flash_read(start + burn_private_start, sectors, trans_data.base_send_buffer);
							if(!ret)
							{
								printf("sunxi flash read err: start,0x%x sectors 0x%x\n", start, sectors);

								csw.bCSWStatus = 1;
							}
							else
							{
								csw.bCSWStatus = 0;
							}

							sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;
						}
						break;

						case 4:				//关闭usb
						{
							__usb_handshake_ext_t  *handshake = (__usb_handshake_ext_t *)trans_data.base_send_buffer;

                            memset(handshake, 0, sizeof(__usb_handshake_ext_t));
							strcpy(handshake->magic, "usb_burn_finish");

							trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_ext_t));

							sunxi_udc_send_data((void *)trans_data.act_send_buffer, trans_data.send_size);

		  					csw.bCSWStatus = 0;

							sunxi_flash_flush();
		  					sunxi_usb_pburn_status = SUNXI_USB_PBURN_EXIT;

						}
						break;

						case 5:
						{
							__usb_handshake_ext_t  *handshake = (__usb_handshake_ext_t *)trans_data.base_send_buffer;
							char buffer[512];

							memset(handshake, 0, sizeof(__usb_handshake_ext_t));
							strcpy(handshake->magic, "usb_burn_saved");

							trans_data.act_send_buffer = trans_data.base_send_buffer;
		  					trans_data.send_size = min(cbw->dCBWDataTransferLength, sizeof(__usb_handshake_ext_t));

		  					csw.bCSWStatus = 0;

		  					sunxi_usb_pburn_status = SUNXI_USB_PBURN_SEND_DATA;

		  					memset(buffer, 0, 512);
							strcpy(buffer, "key_burned");

		  					if(!sunxi_flash_write(burn_private_start + burn_private_len - (8192+512)/512, 1, buffer))
		  					{
		  						printf("save burned flag err\n");

		  						csw.bCSWStatus = -1;
		  					}
		  					sunxi_flash_flush();
#ifdef CONFIG_SUNXI_SECURE_STORAGE
							if(sunxi_secure_storage_init())
							{
								printf("init secure storage failed\n");

								csw.bCSWStatus = -1;
							}
		  					else
		  					{
		  						if(sunxi_secure_storage_write("key_burned_flag", "key_burned", strlen("key_burned")))
		  						{
		  							printf("save burned flag err\n");

		  							csw.bCSWStatus = -1;
		  						}
		  					}
		  					sunxi_secure_storage_exit();
#endif
						}
						break;

					default:
						break;
	  				}

	  			break;

	  			default:
	  				sunxi_usb_dbg("not supported command 0x%x now\n", cbw->CBWCDB[0]);
	  				sunxi_usb_dbg("asked size 0x%x\n", cbw->dCBWDataTransferLength);

	  				csw.bCSWStatus = 1;

	  				sunxi_usb_pburn_status = SUNXI_USB_PBURN_STATUS;

	  				break;
	  		}

	  		break;

	  	case SUNXI_USB_PBURN_SEND_DATA:

	  		sunxi_usb_dbg("SUNXI_USB_SEND_DATA\n");

			sunxi_usb_pburn_status = SUNXI_USB_PBURN_STATUS;
			printf("SUNXI_USB_SEND_DATA=%d\n", trans_data.send_size);
			sunxi_udc_send_data((void *)trans_data.act_send_buffer, trans_data.send_size);
#if defined(SUNXI_USB_30)
			sunxi_usb_pburn_status_enable = 0;
#endif
	  		break;

	  	case SUNXI_USB_PBURN_RECEIVE_DATA:

	  		sunxi_usb_dbg("SUNXI_USB_RECEIVE_DATA\n");

			if(sunxi_usb_pburn_write_enable == 1)
			{
				sunxi_usb_dbg("write flash, start 0x%x, sectors 0x%x\n", pburn_flash_start, trans_data.recv_size/512);
				ret = sunxi_flash_write(pburn_flash_start, (trans_data.recv_size+511)/512, (void *)trans_data.act_recv_buffer);
				if(!ret)
				{
					printf("sunxi flash write err: start,0x%x sectors 0x%x\n", pburn_flash_start, (trans_data.recv_size+511)/512);

					csw.bCSWStatus = 1;
				}
				else
				{
					csw.bCSWStatus = 0;
  				}
				sunxi_usb_pburn_write_enable = 0;

  				sunxi_usb_pburn_status = SUNXI_USB_PBURN_STATUS;
			}

	  		break;

		case SUNXI_USB_PBURN_STATUS:

			sunxi_usb_dbg("SUNXI_USB_PBURN_STATUS\n");
#if defined(SUNXI_USB_30)
			if(sunxi_usb_pburn_status_enable)
#endif
			{
				sunxi_usb_pburn_status = SUNXI_USB_PBURN_IDLE;
				sunxi_ubuf->rx_ready_for_data = 0;
				__sunxi_pburn_send_status(&csw, sizeof(struct umass_bbb_csw_t));
			}

			break;

		case SUNXI_USB_PBURN_EXIT:

			printf("SUNXI_USB_PBURN_EXIT\n");

			sunxi_usb_pburn_status = SUNXI_USB_PBURN_IDLE;
			sunxi_ubuf->rx_ready_for_data = 0;
			__sunxi_pburn_send_status(&csw, sizeof(struct umass_bbb_csw_t));

			printf("Device will shutdown in 3 Secends...\n");
			__msdelay(3000);

			return SUNXI_UPDATE_NEXT_ACTION_SHUTDOWN;

	  	case SUNXI_USB_PBURN_RECEIVE_NULL:

	  		sunxi_usb_dbg("SUNXI_USB_PBURN_RECEIVE_NULL\n");

			if(sunxi_usb_pburn_write_enable == 1)
			{
				csw.bCSWStatus = 0;
				sunxi_usb_pburn_write_enable = 0;
  				sunxi_usb_pburn_status = SUNXI_USB_PBURN_STATUS;
			}

	  		break;

	  	default:
	  		break;
	}

	return 0;
}
예제 #6
0
int __sunxi_burn_key(u8 *buff, uint buff_len)
{
	sunxi_usb_burn_main_info_t *key_main = (sunxi_usb_burn_main_info_t *)buff;
	sunxi_usb_burn_key_info_t  *key_list;
#ifdef CONFIG_SUNXI_SECURE_SYSTEM
	sunxi_efuse_key_info_t      efuse_key_info;
#endif
	int key_count;
	int offset;
	u8  *p_buff = (u8 *)&key_main->key_info;
	//比较key主体的信息
	if(strcmp((const char *)key_main->magic, "key-group-db"))
	{
		printf("key data magic unmatch, err\n");

		return -1;
	}
	key_count = key_main->count;
	printf("key_count=%d\n", key_count);
	if(sunxi_secure_storage_init())
	{
		printf("%s secure storage init failed\n", __func__);

		return -1;
	}
	for(;key_count>0;key_count--, key_list++)
	{
		key_list = (sunxi_usb_burn_key_info_t *)p_buff;
		printf("^^^^^^^^^^^^^^^^^^^\n");
		printf("key index=%d\n", key_main->count - key_count);
		printf("key name=%s\n", key_list->name);
		printf("key type=%d\n", key_list->type);
		printf("key len=%d\n", key_list->len);
		printf("key if_burn=%d\n", key_list->if_burn);
		printf("key if_replace=%d\n", key_list->if_replace);
		printf("key if_crypt=%d\n", key_list->if_crypt);
		printf("key data:\n");
		sunxi_dump(key_list->key_data, key_list->len);
		printf("###################\n");
		offset = (sizeof(sunxi_usb_burn_key_info_t)) + ((key_list->len + 15) & (~15));
		printf("offset=%d\n", offset);
		p_buff += offset;
#ifdef CONFIG_SUNXI_SECURE_SYSTEM
		if(!key_list->type)
		{
			memset(&efuse_key_info, 0, sizeof(efuse_key_info));
			strcpy(efuse_key_info.name, (const char *)key_list->name);
			efuse_key_info.len = key_list->len;
			efuse_key_info.key_data = (u8 *)key_list->key_data;

			if(smc_efuse_writel(&efuse_key_info))
			{
				return -1;
			}
		}
		else
#endif
		{
#ifdef CONFIG_SUNXI_HDCP_IN_SECURESTORAGE
			int ret;

			if(!strcmp("hdcpkey", key_list->name))
			{
				ret = sunxi_deal_hdcp_key((char *)key_list->key_data, key_list->len);
				if(ret)
				{
					printf("sunxi deal with hdcp key failed\n");

					return -1;
				}
			}
			else
#endif
			{
			if(key_list->if_crypt)
				smc_set_sst_crypt_name(key_list->name);

				if(sunxi_secure_object_write(key_list->name, (char *)key_list->key_data, key_list->len))
				{
					return -1;
				}
			}
		}
	}
	if(sunxi_secure_storage_exit())
	{
		printf("sunxi_secure_storage_exit err\n");

		return -1;
	}

	return 0;
}
예제 #7
0
int sunxi_verify_signature(void *buff, uint len, const char *cert_name)
{
	u8 hash_of_file[32];
	int ret;
	struct sbrom_toc1_head_info  *toc1_head;
	struct sbrom_toc1_item_info  *toc1_item;
	sunxi_certif_info_t  sub_certif;
	int i;

	memset(hash_of_file, 0, 32);
	sunxi_ss_open();
	ret = sunxi_sha_calc(hash_of_file, 32, buff, len);
	if(ret)
	{
		printf("sunxi_verify_signature err: calc hash failed\n");
		//sunxi_ss_close();

		return -1;
	}
	//sunxi_ss_close();
	printf("show hash of file\n");
	sunxi_dump(hash_of_file, 32);
	//获取来自toc1的证书序列
	toc1_head = (struct sbrom_toc1_head_info *)CONFIG_TOC1_STORE_IN_DRAM_BASE;
	toc1_item = (struct sbrom_toc1_item_info *)(CONFIG_TOC1_STORE_IN_DRAM_BASE + sizeof(struct sbrom_toc1_head_info));

	for(i=1;i<toc1_head->items_nr;i++, toc1_item++)
	{
		if(toc1_item->type == TOC_ITEM_ENTRY_TYPE_BIN_CERTIF)
		{
			printf("find cert name %s\n", toc1_item->name);
			if(!strcmp((const char *)toc1_item->name, cert_name))
			{
				//取出证书的扩展项
				if(sunxi_certif_probe_ext(&sub_certif, (u8 *)(CONFIG_TOC1_STORE_IN_DRAM_BASE + toc1_item->data_offset), toc1_item->data_len))
				{
					printf("%s error: cant verify the content certif\n", __func__);

					return -1;
				}
				//比较扩展项和hash
				printf("show hash in certif\n");
				sunxi_dump(sub_certif.extension.value[0], 32);
				if(memcmp(hash_of_file, sub_certif.extension.value[0], 32))
				{
					printf("hash compare is not correct\n");
					printf(">>>>>>>hash of file<<<<<<<<<<\n");
					sunxi_dump(hash_of_file, 32);
					printf(">>>>>>>hash in certif<<<<<<<<<<\n");
					sunxi_dump(sub_certif.extension.value[0], 32);

					return -1;
				}

				return 0;
			}
		}
	}

	printf("cant find a certif belong to %s\n", cert_name);

	return -1;
}