215 lines
5.5 KiB
C
215 lines
5.5 KiB
C
|
|
// SPDX-License-Identifier: GPL-2.0
|
||
|
|
/*
|
||
|
|
* Copyright (C) 2011 MediaTek Inc.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "sec_osal.h"
|
||
|
|
#include "sec_hal.h"
|
||
|
|
#include "sec_osal_light.h"
|
||
|
|
#include "sec_boot_lib.h"
|
||
|
|
#include "sec_error.h"
|
||
|
|
#include "hacc_mach.h"
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/******************************************************************************
|
||
|
|
* This file provide the HACC operation function to secure library
|
||
|
|
* All the functions should be general ...
|
||
|
|
******************************************************************************/
|
||
|
|
#define MOD "ASF"
|
||
|
|
|
||
|
|
/******************************************************************************
|
||
|
|
* GLOBAL VARIABLES
|
||
|
|
******************************************************************************/
|
||
|
|
bool bHACC_HWWrapKeyInit;
|
||
|
|
bool bHACC_SWKeyInit;
|
||
|
|
|
||
|
|
/******************************************************************************
|
||
|
|
* INTERNAL VARIABLES
|
||
|
|
******************************************************************************/
|
||
|
|
static const unsigned int g_HACC_CFG_1[8] = {
|
||
|
|
0x9ED40400, 0x00E884A1, 0xE3F083BD, 0x2F4E6D8A,
|
||
|
|
0xFF838E5C, 0xE940A0E3, 0x8D4DECC6, 0x45FC0989
|
||
|
|
};
|
||
|
|
|
||
|
|
static const unsigned int g_HACC_CFG_2[8] = {
|
||
|
|
0xAA542CDA, 0x55522114, 0xE3F083BD, 0x55522114,
|
||
|
|
0xAA542CDA, 0xAA542CDA, 0x55522114, 0xAA542CDA
|
||
|
|
};
|
||
|
|
|
||
|
|
static const unsigned int g_HACC_CFG_3[8] = {
|
||
|
|
0x2684B690, 0xEB67A8BE, 0xA113144C, 0x177B1215,
|
||
|
|
0x168BEE66, 0x1284B684, 0xDF3BCE3A, 0x217F6FA2
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/******************************************************************************
|
||
|
|
* INTERNAL ENGINE
|
||
|
|
******************************************************************************/
|
||
|
|
static unsigned char *sp_hacc_internal(unsigned char *buf, unsigned int size,
|
||
|
|
bool bAC,
|
||
|
|
enum hacc_user user,
|
||
|
|
bool bDoLock,
|
||
|
|
enum aes_ops aes_type,
|
||
|
|
bool bEn)
|
||
|
|
{
|
||
|
|
unsigned int err = 0;
|
||
|
|
|
||
|
|
/* ---------------------------- */
|
||
|
|
/* get hacc lock */
|
||
|
|
/* ---------------------------- */
|
||
|
|
if (true == bDoLock) {
|
||
|
|
/* If the semaphore is successfully acquired,
|
||
|
|
* this function returns 0.
|
||
|
|
*/
|
||
|
|
err = osal_hacc_lock();
|
||
|
|
|
||
|
|
if (err) {
|
||
|
|
err = ERR_SBOOT_HACC_LOCK_FAIL;
|
||
|
|
goto _err;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ---------------------------- */
|
||
|
|
/* ciphering and force AC */
|
||
|
|
/* ---------------------------- */
|
||
|
|
switch (user) {
|
||
|
|
case HACC_USER1:
|
||
|
|
/* ------------------------------- */
|
||
|
|
/* use smart phone hacc function 1 */
|
||
|
|
/* ------------------------------- */
|
||
|
|
HACC_V3_Init(bEn, g_HACC_CFG_1);
|
||
|
|
|
||
|
|
HACC_V3_Run((unsigned int *)buf, size, (unsigned int *)buf);
|
||
|
|
|
||
|
|
HACC_V3_Terminate();
|
||
|
|
break;
|
||
|
|
|
||
|
|
case HACC_USER2:
|
||
|
|
/* ---------------------------- */
|
||
|
|
/* use smart phone hacc function 2 */
|
||
|
|
/* ---------------------------- */
|
||
|
|
HACC_V3_Init(bEn, g_HACC_CFG_2);
|
||
|
|
|
||
|
|
HACC_V3_Run((unsigned int *)buf, size, (unsigned int *)buf);
|
||
|
|
|
||
|
|
HACC_V3_Terminate();
|
||
|
|
break;
|
||
|
|
|
||
|
|
|
||
|
|
case HACC_USER3:
|
||
|
|
/* use smart phone hacc function 3 */
|
||
|
|
/* ---------------------------- */
|
||
|
|
if (false == bHACC_HWWrapKeyInit) {
|
||
|
|
err = ERR_HACC_HW_WRAP_KEY_NOT_INIT;
|
||
|
|
goto _err;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
err = hacc_set_key(AES_HW_WRAP_KEY, AES_KEY_256);
|
||
|
|
|
||
|
|
if (err != SEC_OK)
|
||
|
|
goto _err;
|
||
|
|
|
||
|
|
err = hacc_do_aes(aes_type, buf, buf, AES_BLK_SZ_ALIGN(size));
|
||
|
|
|
||
|
|
if (err != SEC_OK)
|
||
|
|
goto _err;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case HACC_USER4:
|
||
|
|
/* ---------------------------- */
|
||
|
|
/* use smart phone hacc function 4 */
|
||
|
|
/* ---------------------------- */
|
||
|
|
HACC_V3_Init(bEn, g_HACC_CFG_3);
|
||
|
|
|
||
|
|
HACC_V3_Run((unsigned int *)buf, size, (unsigned int *)buf);
|
||
|
|
|
||
|
|
HACC_V3_Terminate();
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
err = ERR_HACC_UNKNOWN_USER;
|
||
|
|
goto _err;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ---------------------------- */
|
||
|
|
/* release hacc lock */
|
||
|
|
/* ---------------------------- */
|
||
|
|
if (true == bDoLock)
|
||
|
|
osal_hacc_unlock();
|
||
|
|
|
||
|
|
return buf;
|
||
|
|
|
||
|
|
_err:
|
||
|
|
if (true == bDoLock)
|
||
|
|
osal_hacc_unlock();
|
||
|
|
|
||
|
|
pr_debug("[%s] HACC Fail (0x%x)\n", MOD, err);
|
||
|
|
|
||
|
|
WARN_ON(!(0));
|
||
|
|
|
||
|
|
return buf;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************
|
||
|
|
* ENCRYPTION
|
||
|
|
******************************************************************************/
|
||
|
|
unsigned char *masp_hal_sp_hacc_enc(unsigned char *buf, unsigned int size,
|
||
|
|
unsigned char bAC,
|
||
|
|
enum hacc_user user,
|
||
|
|
unsigned char bDoLock)
|
||
|
|
{
|
||
|
|
return sp_hacc_internal(buf, size, true, user, bDoLock, AES_ENC, true);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/******************************************************************************
|
||
|
|
* DECRYPTION
|
||
|
|
******************************************************************************/
|
||
|
|
unsigned char *masp_hal_sp_hacc_dec(unsigned char *buf, unsigned int size,
|
||
|
|
unsigned char bAC,
|
||
|
|
enum hacc_user user,
|
||
|
|
unsigned char bDoLock)
|
||
|
|
{
|
||
|
|
return sp_hacc_internal(buf, size, true, user, bDoLock, AES_DEC, false);
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************
|
||
|
|
* HACC BLK SIZE
|
||
|
|
******************************************************************************/
|
||
|
|
unsigned int masp_hal_sp_hacc_blk_sz(void)
|
||
|
|
{
|
||
|
|
return AES_BLK_SZ;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************
|
||
|
|
* HACC INITIALIZATION
|
||
|
|
******************************************************************************/
|
||
|
|
unsigned int masp_hal_sp_hacc_init(unsigned char *sec_seed, unsigned int size)
|
||
|
|
{
|
||
|
|
struct aes_key_seed keyseed;
|
||
|
|
unsigned int i = 0;
|
||
|
|
|
||
|
|
bHACC_HWWrapKeyInit = false;
|
||
|
|
bHACC_SWKeyInit = false;
|
||
|
|
|
||
|
|
if (size != _CRYPTO_SEED_LEN)
|
||
|
|
return ERR_HACC_SEED_LEN_ERROR;
|
||
|
|
|
||
|
|
keyseed.size = HACC_AES_MAX_KEY_SZ;
|
||
|
|
for (i = 0; i < HACC_AES_MAX_KEY_SZ / 2; i++) {
|
||
|
|
keyseed.seed[i] = sec_seed[i];
|
||
|
|
keyseed.seed[HACC_AES_MAX_KEY_SZ - i - 1] = sec_seed[i] +
|
||
|
|
MTK_HACC_SEED;
|
||
|
|
}
|
||
|
|
|
||
|
|
pr_debug("0x%x,0x%x,0x%x,0x%x\n",
|
||
|
|
keyseed.seed[0],
|
||
|
|
keyseed.seed[1],
|
||
|
|
keyseed.seed[2],
|
||
|
|
keyseed.seed[3]);
|
||
|
|
|
||
|
|
return hacc_init(&keyseed);
|
||
|
|
}
|