int DRV_GET_CHIPID(unsigned char* buf,int length)
{
    unsigned int i = 0;
    int ret = 0;

    if(NULL == buf)
    {
        efuse_print_error("die id buf is error.\n");
        return EFUSE_ERROR;
    }

    if(length < EFUSE_CHIPID_LEN)
    {
        efuse_print_error("die id lenth is error.\n");
        return EFUSE_ERROR;
    }

    memset(buf, 0, EFUSE_CHIPID_LEN);

    pr_info("efuse read start group %d length %d.\n", EFUSE_GRP_CHIPID, EFUSE_CHIPID_SIZE);

    if(0 != (ret = bsp_efuse_read((u32*)buf, EFUSE_GRP_CHIPID, EFUSE_CHIPID_SIZE)))
    {
        efuse_print_error("chip id read efuse error.\n");
        return READ_EFUSE_ERROR;
    }

    for(i = 0; i < EFUSE_CHIPID_SIZE; i++)
    {
        pr_info("efuse end buf[%d] is 0x%x.\n", i, buf[i]);
    }
    pr_info("efuse read end ret %d\n", ret);

    return EFUSE_OK;
}
Esempio n. 2
0
/******************************************************************************
* 函 数 名: is_burn
* 功能描述: 检查efuse是否已经烧写了flash info
* 输入参数: @burn_flag: 烧写标志。1 - 已烧写;0 - 未烧写
*			@buffer: efuse中nandc info所在group的值
* 输出参数: 无
* 返 回 值: 0 - 成功; 非0 - 失败
* 函数说明: 检查
*******************************************************************************/
static s32 is_burn(u32 *burn_flag)
{
	s32 ret;
	u32 efuse_nand_info_addr = EFUSE_NANDC_GROUP_OFFSET;
    u32 buffer = 0;

	ret = bsp_efuse_read(&buffer, efuse_nand_info_addr, EFUSE_NANDC_GROUP_LENGTH);
	if(ret)
	{
		PRINT_MSG("Efuse read info error\n");
		goto erro;
	}

	PRINT_MSG("After read: 0x%x\n", buffer);

	ret = check_flag(buffer);
	if(EFUSE_NANDC_NOT_BURN == ret)
	{
		*burn_flag = EFUSE_NANDC_NOT_BURN;
	}
	else
	{
		*burn_flag = EFUSE_NANDC_HAD_BURN;
	}

	return OK;
erro:
	return ret;
}
void efuse_handle_work(struct work_struct *work)
{
    u32 i = 0;
    int length = 0;
    u32 channel_id = ICC_CHN_IFC << 16 | IFC_RECV_FUNC_EFUSE;
    EFUSE_DATA_STRU *msg = &efuse_msg;

    if(EFUSE_READ == (u32)msg->opt)
    {
        if(1 == efuse_debug_flag)
        {
            pr_info("efuse read start group %d length %d.\n", msg->start, msg->len);
        }
        
        msg->ret = bsp_efuse_read(msg->buf, msg->start,msg->len);
        
        if(1 == efuse_debug_flag)
        {
            pr_info("efuse read end group %d length %d.\n", msg->start, msg->len);
            for(i = 0;i < msg->len;i++)
            {
                pr_info("efuse buf[%d] is 0x%x.\n", i, msg->buf[i]);
            }
            pr_info("efuse read ret %d\n", msg->ret);
        }
    }
    else if(EFUSE_WRITE == (u32)msg->opt)
    {
        if(1 == efuse_debug_flag)
        {
            pr_info("efuse write start group %d length %d.\n", msg->start, msg->len);
            for(i = 0;i < msg->len;i++)
            {
                pr_info("efuse buf[%d] is 0x%x.\n", i, msg->buf[i]);
            }
        }
        
        msg->ret = bsp_efuse_write(msg->buf, msg->start,msg->len);
        
        if(1 == efuse_debug_flag)
        {
            pr_info("efuse write ret %d.\n", msg->ret);
        }

    }
    else
    {
        msg->ret = EFUSE_ERROR;
    }

    length = bsp_icc_send(ICC_CPU_MODEM, channel_id, (unsigned char*)msg, sizeof(EFUSE_DATA_STRU));
    if(length != (int)sizeof(EFUSE_DATA_STRU))
    {
        efuse_print_error("send len(%x) != expected len(%lu).\n", length, (unsigned long)sizeof(EFUSE_DATA_STRU));
        return;
    }


}
Esempio n. 4
0
void bsp_efuse_show(void)
{
    unsigned int i = 0;
    unsigned int value = 0;

    for(i = 0;i < EFUSE_MAX_SIZE;i++)
    {
        if(OK == bsp_efuse_read(&value, i, 1))
        {
            efuse_print_info("efuse group%d value = 0x%x.\n ", i, value);
        }
        else
        {
            efuse_print_error("efuse group%d read fail.\n", i);
            return;
        }

    }

}
Esempio n. 5
0
/*************************************************
 函 数 名   : secureAlreadyUse
 功能描述   : 查询当前版本是否已经启用安全启动
 输入参数   : unsigned char *pData
 输出参数   : unsigned char *pData
 返 回 值   : OK/ERROR
 调用函数   :
 被调函数   :

 修改历史   :
 日    期   : 2010年12月21日
 作    者   :
 修改内容   :

*************************************************/
s32 secureAlreadyUse(u8 * pData)
{
    u32 efuse_security_flag = 0;
	s32 sec_err_code = SEC_OK;

    if(NULL == pData)
    {
        return SEC_ERROR_NULL_PTR;
    }

	sec_err_code = bsp_efuse_read(&efuse_security_flag, EFUSE_GRP_SECURITY, 1);
    if( SEC_OK != sec_err_code)
    {
        return sec_err_code;
    }
    /*判断安全位是否已写入*/
	*pData = ((efuse_security_flag & EFUSEC_SEC_EN_MASK) == EFUSEC_SEC_EN) ? (u8)SECURE_ENABLE : (u8)SECURE_DISABLE;

    return sec_err_code;
}
Esempio n. 6
0
/******************************************************************************
* 函 数 名: do_burn
* 功能描述: 将flash spec信息烧写到efuse
* 输入参数: @spec:存放flash info
* 输出参数: 无
* 返 回 值: 0 - 成功; 非0 - 失败
* 函数说明:
*******************************************************************************/
static s32 do_burn(struct nand_spec *spec)
{
	s32 ret = ERROR;
	u32 efuse_nand_info_addr = EFUSE_NANDC_GROUP_OFFSET;
    u32 read_value;
    u32 value = 0;

	/* param error */
	if(!spec)
	{
		PRINT_MSG("Param failed\n");
		goto erro;
	}

	/* make value */
    switch(spec->pagenumperblock)       /* add page num per block */
    {
        case NANDC_BLOCK_64PAGE:
            value |= EFUSE_NANDC_BLOCKSIZE_64PAGE;
            break;
        case NANDC_BLOCK_128PAGE:
            value |= EFUSE_NANDC_BLOCKSIZE_128PAGE;
            break;
        default:
			break;
    }

	PRINT_MSG("Add block size: 0x%x\n", value);

    /*lint -save -e30, -e142*/
	switch(spec->ecctype)         		/* add ecc type */
	{
	    case NANDC_ECC_NONE:
            value |= EFUSE_NANDC_ECCTYPE_NONE;
			break;
		case NANDC_ECC_1BIT:
            value |= EFUSE_NANDC_ECCTYPE_1BIT;
			break;
		case NANDC_ECC_4BIT:
			value |= EFUSE_NANDC_ECCTYPE_4BIT;
			break;
		case NANDC_ECC_8BIT:
			value |= EFUSE_NANDC_ECCTYPE_8BIT;
			break;
		default:
			break;
	}
    /*lint -restore*/

	PRINT_MSG("Add ecc type: 0x%x\n", value);

	switch(spec->pagesize)				/* add page size */
    {
        case NANDC_SIZE_HK:
			value |= EFUSE_NANDC_PAGESIZE_hK;
			break;
		case NANDC_SIZE_2K:
			value |= EFUSE_NANDC_PAGESIZE_2K;
			break;
		case NANDC_SIZE_4K:
			value |= EFUSE_NANDC_PAGESIZE_4K;
			break;
		case NANDC_SIZE_8K:
			value |= EFUSE_NANDC_PAGESIZE_8K;
			break;
		default:
			break;
	}

	PRINT_MSG("Add page size: 0x%x\n", value);

    switch(spec->addrnum)               /* add addr num */
    {
        case NANDC_ADDRCYCLE_4:
            value |= EFUSE_NANDC_ADDRNUM_4CYCLE;
            break;
        case NANDC_ADDRCYCLE_5:
            value |= EFUSE_NANDC_ADDRNUM_5CYCLE;
            break;
        default:
			break;
    }

	PRINT_MSG("Add addr num: 0x%x\n", value);

	/* set burn flag */
	value |= EFUSE_NANDC_BURNFLAG_HADBURN;

	PRINT_MSG("Add burn flag: 0x%x\n", value);

    /* set configure nandc from efuse */
    value |= EFUSE_CONF_FROM_EFUSE;

	PRINT_MSG("Add conf flag: 0x%x\n", value);

	/* write info */
	ret = bsp_efuse_write(&value, efuse_nand_info_addr, EFUSE_NANDC_GROUP_LENGTH);
	if(ret)
	{
		PRINT_MSG("EFuse write failed\n");
		goto erro;
	}

    /* read and compare */
    ret = bsp_efuse_read(&read_value, efuse_nand_info_addr, EFUSE_NANDC_GROUP_LENGTH);
    if(ret)
	{
		PRINT_MSG("EFuse read failed\n");
		goto erro;
	}

    if(read_value != value)
    {
        PRINT_MSG("EFuse value cmp error, write value: 0x%x, read value 0x%x\n", value, read_value);
        ret = ERROR;
		goto erro;
    }

    PRINT_MSG("SUCCESS: write nandc info successful\n");

	return OK;
erro:
	return ret;
}
Esempio n. 7
0
/*****************************************************************************
* 函 数 名  : create_crypto_key
*
* 功能描述  : 使用输入的数据和HUK,生成密钥。当前支持MD5、和SHA-1算法。
*
*             生成密钥的方法:
*             把HUK和输入的数据连接起来作为MD5或SHA-1算法的输入,计算其HASH值。
*
* 输入参数  : data:      用于生成密钥的数据。
*             len:       用于生成密钥的数据长度。(byte)
*             algorithm: 要使用的密钥生成算法。
*             klen:      作为输入参数,存放key的缓冲区的长度。(byte)
*
* 输出参数  : key:       存放生成的密钥。buffer必须大于16(MD5)/20(SHA-1)字节。
*             klen:      作为输出参数,存放生成的密钥的长度。(byte)
*
* 返 回 值  : BSP_OK:    生成成功。
*             BSP_ERROR: 生成失败。
*
* 其它说明  : klen为输入/输出参数,传入的klen变量所用内存必须可写回。
*             所以避免直接传入类似sizeof()的函数调用结果。
*
*****************************************************************************/
int create_crypto_key_o(char *data, int len, CREATE_CRYPTO_KEY_ALGORITHM algorithm, char *key, int *klen)
{
    char* crypto_data = NULL;
    UINT8 i=0;

        if(BSP_OK != param_check(data,len,algorithm,key,klen))
        {
        security_print("ERROR create_crypto_key: param is invalid!\n");
        goto ERROR_EXIT;
        }

    crypto_data = (char*)malloc(len + HUK_LEN);

    if(crypto_data == NULL)
    {
        security_print("ERROR create_crypto_key: malloc failed!\n");
        goto ERROR_EXIT;
    }

	memset(crypto_data, 0, len + HUK_LEN);

	/* Read & Copy HUK.*/
	if(BSP_OK != bsp_efuse_read((u32*)crypto_data, EFUSE_GRP_HUK, (HUK_LEN/sizeof(uint32)) ))
	{
		/*规避EFUSE写入后需要重启才能读取的问题*/
		if(!CheckHukIsValid())
		{
			security_print("ERROR create_crypto_key: efuseRead failed!\n");
			goto ERROR_EXIT;
		}
	}

    for(i=0;i<HUK_LEN;i++)
    {
            if(0 != *(((UINT8*)crypto_data)+i))
            {
                break;
            }
    }

    if(i>=HUK_LEN)
        {
            security_print("ERROR create_crypto_key: read_efuse NULL!\n");
            goto ERROR_EXIT;
    }


    // Copy user data.
    memcpy((void*)((UINT32)crypto_data + HUK_LEN), data, len);


    // Encrypt.
    switch(algorithm)
    {
    /*case CREATE_CRYPTO_KEY_ALGORITHM_MD5:*/
    /*case CREATE_CRYPTO_KEY_ALGORITHM_SHA1:*/
    case CREATE_CRYPTO_KEY_ALGORITHM_SHA256:
        if(BSP_OK != crypto_hash(crypto_data, len + HUK_LEN, (CRYPTO_HASH_ALGORITHM)algorithm, key, klen))
        {
            security_print("ERROR create_crypto_key: crypto_hash failed!\n");
            goto ERROR_EXIT;
        }

        break;

    default:
        security_print("ERROR create_crypto_key: unknown algorithm!\n");

        goto ERROR_EXIT;
    }

//OK_EXIT:
    if(crypto_data != NULL)
    {
        free(crypto_data);
    }
#ifndef _DRV_LLT_
       /*REG_WRITE_32(PWR_SC_PERIPH_CLKDIS0, SOC_CLK_CLOSE_DIS0);*/
#endif
    return BSP_OK;

ERROR_EXIT:
    if(crypto_data != NULL)
    {
        free(crypto_data);
    }

    return BSP_ERROR;
}
Esempio n. 8
0
s32 startSecure(void)
{
	s32 sec_err_code = SEC_OK;
    u8  flag = 0;
	u8 * m3boot_ram_addr = NULL;
    u32 ulEfuseRootCaHash[SHA256_HASH_SIZE] = {0}; /*用来存放SHA256值的临时buffer*/
    u32 efuse_security_flag = 0;
	u32 md5_hash[MD5_HASH_SIZE] = {0};

    sec_err_code = secureAlreadyUse(&flag);
	if(sec_err_code)
	{
		return -1;
	}
    if( SECURE_ENABLE == flag )                    /* has been written */
    {
        return SEC_OK;
    }
	sec_err_code = secureSupport(&flag);
    if(SEC_OK != sec_err_code)
    {
		bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "[SEC ERROR]check Secure support error!\n");
        return sec_err_code;
    }
    if(SECURE_NOT_SUPPORT == flag)
    {
		bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "[SEC ERROR]Secure not support!\n");
        return SEC_ERROR_IMG_SECURY_NOT_SUPPORT;
    }

	m3boot_ram_addr = (u8*)osl_malloc(ROOT_CA_LEN);
	if(!m3boot_ram_addr)
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "[SEC ERROR]NO mem error!\n");
		return -1;
	}
	sec_err_code = BSP_mass_read("m3boot", /*P531_M3_LEN_INDEX + sizeof(u32)*/ROOT_CA_INDEX, ROOT_CA_LEN, m3boot_ram_addr);
    if(SEC_OK != sec_err_code)
    {
		bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "BSP_mass_read error!\n");
        return sec_err_code;
    }

#if 0//for debug, print rootca
	printf("\n");
	for(i = 0; i < ROOT_CA_LEN / 4; i += 4)
	{
		printf("%X\n", *(unsigned long *)(m3boot_ram_addr + i));
	}
	printf("\n");
#endif

	/*计算ROOT CA HASH*/
	sec_err_code = kdf_sha256(m3boot_ram_addr, ROOT_CA_LEN, (u8*)ulEfuseRootCaHash);
    if(SEC_OK != sec_err_code)
    {
		bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "\r\ncalc RootCa sha1 err!\n");
        return SEC_ERROR_SHA_ERR;
    }
	/*计算HASH值的MD5值*/
	sec_err_code = encrypt_lock_md5_data(ulEfuseRootCaHash, SHA256_HASH_SIZE * sizeof(u32), md5_hash);
	if(sec_err_code)
	{
		return -1;
	}

	sec_err_code = bsp_efuse_read(&efuse_security_flag, EFUSE_GRP_SECURITY, 1);
    if( SEC_OK != sec_err_code)
    {
    	bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "startSecure: run efuse_read error!\n");
        return SEC_ERROR_EFUSE_READ_ERR;
    }
    efuse_security_flag |= EFUSEC_SEC_EN;

    /* write RootCA hash */
    if( SEC_OK != bsp_efuse_write( md5_hash, EFUSE_GRP_ROOT_CA, 4 ) )
    {
        return -1;
    }

    /* Last step, enable security boot */
    if( SEC_OK != bsp_efuse_write( (u32 *)&efuse_security_flag, EFUSE_GRP_SECURITY, 1 ) )
    {
        return -1;
    }

	bsp_trace(BSP_LOG_LEVEL_INFO, BSP_MODU_SECURITY, "\r\nstartSecure SUCC!\r\n", 0, 0, 0, 0, 0, 0 );
    return 0;
}