可信应用的存储密钥(Trusted Applicant Storage Key, TSK)是生成FEK时使用到的密钥。
TSK是使用SSK作为密钥对TA的UUID经HMAC计算获得,类似于HMAC(SSK, UUID)的方式生成TSK。
在调用tee_fs_fek_crypt函数时会计算TSK的值。TSK最终会被用来生成FEK, FEK会在使用安全存储功能保存数据时被用来加密数据。
文件加密密钥(File Encryption Key, FEK)是安全存储功能用于对数据进行加密时使用的AES密钥,该密钥在生成文件时会 使用PRNG算法随机产生 ,产生的 FEK会使用TSK进行加密 ,然后保存到head.enc_fek变量中。
(PRNGPRNG(pseudorandom number generator)伪随机数生成器是指通过特定算法生成一系列的数字,使得这一系列的数字看起来是随机的,但是实际是确定的,所以叫伪随机数。)
TA在每次使用 安全存储功能创建一个安全文件时就会生成一个随机数作为FEK ,即每个TA 中的每个安全文件都有一个FEK用于加密对应文件中的数据 。(安全加倍啊)
关于FEK的产生可简单理解为如下公式,使用的初始化向量IV值为0:
AES_CBC(in_key, TSK)
OP-TEE通过调用tee_fs_fek_crypt函数来生成一个FEK,该函数代码如下:
TEE_Result tee_fs_fek_crypt(const TEE_UUID *uuid, TEE_OperationMode mode,
const uint8_t *in_key, size_t size,
uint8_t *out_key)
{
TEE_Result res;
uint8_t *ctx = NULL;
size_t ctx_size;
uint8_t tsk[TEE_FS_KM_TSK_SIZE];
uint8_t dst_key[size];
/* 检查输入的用于生成FEK的随机数in_key和用于存放生成的out_key地址是否合法 */
if (! in_key || ! out_key)
return TEE_ERROR_BAD_PARAMETERS;
/* 检查in_key长度 */
if (size ! = TEE_FS_KM_FEK_SIZE)
return TEE_ERROR_BAD_PARAMETERS;
/* 判定SSK是否已经被初始化 */
if (tee_fs_ssk.is_init == 0)
return TEE_ERROR_GENERIC;
/* 如果调用时参数uuid不为0,则调用HMAC算法生成TSK。如果UUID的值为0,则默认生成TSK
使用的原始数据为0 */
if (uuid) {
res = do_hmac(tsk, sizeof(tsk), tee_fs_ssk.key,
TEE_FS_KM_SSK_SIZE, uuid, sizeof(*uuid));
if (res ! = TEE_SUCCESS)
return res;
} else {
uint8_t dummy[1] = { 0 };
res = do_hmac(tsk, sizeof(tsk), tee_fs_ssk.key,
TEE_FS_KM_SSK_SIZE, dummy, sizeof(dummy));
if (res ! = TEE_SUCCESS)
return res;
}
/* 获取调用AEC_CBC操作需要的context的大小 */
res = crypto_ops.cipher.get_ctx_size(TEE_FS_KM_ENC_FEK_ALG, &ctx_size);
if (res ! = TEE_SUCCESS)
return res;
/* 分配一份进行AES_CBC操作时需要的context空间 */
ctx = malloc(ctx_size);
if (! ctx)
return TEE_ERROR_OUT_OF_MEMORY;
/* 使用TSK作为进行AES_CBC计算使用的key,而IV值默认为0 */
res = crypto_ops.cipher.init(ctx, TEE_FS_KM_ENC_FEK_ALG, mode, tsk,
sizeof(tsk), NULL, 0, NULL, 0);
if (res ! = TEE_SUCCESS)
goto exit;
/* 将输入的in_key填充到context中,做完AES_CBC操作之后,输出的数据将会被保存到dst_
key中 */
res = crypto_ops.cipher.update(ctx, TEE_FS_KM_ENC_FEK_ALG,
mode, true, in_key, size, dst_key);
if (res ! = TEE_SUCCESS)
goto exit;
/* 执行AES_CBC的加密运算,生成FEK */
crypto_ops.cipher.final(ctx, TEE_FS_KM_ENC_FEK_ALG);
/* 将生成的FEK的值复制到输出参数中 */
memcpy(out_key, dst_key, sizeof(dst_key));
exit:
free(ctx);
return res;
}
全部0条评论
快来发表一下你的评论吧 !