首页
社区
课程
招聘
[原创]SCTF2023 逆向 SycTee 出题与解题思路
发表于: 2023-6-20 16:39 18723

[原创]SCTF2023 逆向 SycTee 出题与解题思路

2023-6-20 16:39
18723

SCTF2023是本年度xctf的第二次分站赛,这是第一次出这样大型的比赛的题,头一次没打xctf,在观赛者的角度来看比赛进程,是另一种体验,既担心自己题出的太简单,又怕题没人做。

这次比赛出题时间并不多,因为中间还穿插着一些比赛,所以真正开始出题大概是在比赛开始前2天,通宵两天把题目出完,在晚上9点上题前甚至还在添加一些东西,可能有些师傅会觉得有些脑洞,给师傅们造成了不好的体验,在这给各位师傅磕头了orz。

做题情况:

看到师傅们都在通宵做题,还是很感动的。

题目描述:

TEE的全称trusted execution environment,它是移动设备(智能手机、平板电脑、智能电视)CPU上的一块区域。这块区域的作用是给数据和代码的执行提供一个更安全的空间,并保证它们的机密性和完整性。TEE提供了一个与REE隔离的环境保存用户的敏感信息,TEE可以直接获取REE的信息,而REE不能获取TEE的信息。

而该题的出题思路就是旨在构建一个tee的系统。

TA(Trusted Application)是TEE中完成特定功能的应用,也叫做可信应用程序。由于TEE中完成计算因此具有较高的安全性。每一个TA在REE中有一个或者多个对应的CA,在REE环境中可以通过调用CA的接口,将信息传送到TEE环境中执行TA,完成对应功能然后返回计算结果。

了解了tee是什么,还应该了解一下一些基本名词:

CA(Client APP):对应一些上层应用,通过调用TEE Client API实现与TEE环境的交互。

REE Communication Agent:为TA和CA之间的消息传递提供了REE支持

TEE Client API:是REE中的TEE驱动程序提供给外部的接口,可以使运行在REE中的CA能够与运行在TEE中的TA交换数据。

TEE Communication Agent:是可信操作系统的特殊组成部分,它与REE Communication Agent一起工作,使TA与CA之间安全地传输消息。

TEE Internal Core API:是TEE操作系统提供给TA调用的内部接口,包括密码学算法,内存管理等功能。

Trusted Device Drivers:可信设备驱动程序,为专用于TEE的可信外设提供通信接口。

Shared Memory:是一块只有CA和TA可以访问的一块安全内存,CA和TA通过共享内存来快速有效传输指令和数据

CA与TA交互流程:CA首先调用TEE Client API触发系统调用,进入REE的操作系统内核态,根据CA调用的参数找到对应的REE驱动程序,REE驱动程序通过调用SMC汇编指令进入Monitor模式,并将处理器切换到安全内核状态,进入安全模式。切换进入TEE以后,CA的服务请求通过总线传到TEE侧,然后TEE OS通过TEE Internal API调用对应的TA,最后TA运行结束后将运行结果和数据返回给CA,执行完以后回到TEE内核态调用SMC汇编指令进入Monitor切回REE环境。

其实用更简单的理解就是:应用层输入 -> 内核 -> TA -> 内核 -> 应用层验证结果

如果在网上搜,其实这种类型题就在RealWorld上出现过:https://bestwing.me/RWCTF-4th-TrustZone-challenge-Writeup.html这个题他的考点是求被加密的 FEK,类似一个密码题,所以这次出题就换一个思路,原本思路是在optee框架下,build出一个rust的基于arm架构的ta文件,在上一些全局变量,顺便来点动调,把整个optee项目打包出题,不过由于时间问题,并没有完成大部分。在构建系统的时候踩过很多坑,接下来我在介绍的时候会尽量详细介绍,网上可阅读的解决方案实在少之又少。

项目文档:https://optee.readthedocs.io/en/latest/

OP-TEE 是一个可信执行环境 (TEE),旨在与在 Arm 上运行的非安全 Linux 内核配套使用;使用 TrustZone 技术的 Cortex-A 内核。

该项目的构建有两种方法:第一种是用repo直接懒人布置,第二种是手拉文件,逐项布置。

两种方式各有各的坏处,但综合起来第一种方式更好。首先如果选用repo来部署的话,会面临一个被墙的问题,即使在虚拟机里配代理,又或者是在服务器上拉都会遇到很大报错问题。手拉文件也会遇到很多问题,比如optee-client的make会报很多错误,网上并没有很多解决方案。

repo的安装:

接下来初始化repo:

在这里我拉取的是3.18.0版本的optee,而且用qemu_v8平台,建议换源来拉。

在.repo\manifests目录下可以看到qemu_v8.xml配置单。

接下来就是要下载配置单的过程:

在下载前呢,需要设置代理,这样更快,或者在qemu_v8清单中的revision后加上clone-depth="1",或者:

最后别忘了代理:

不过经过测验,这个拉取也是需要时间的,不管用服务器还是设代理有时候照样拉不了,多尝试几次就可以拉了,我是下午的时候拉成功的。

构建完的目录如下:

optee_example和optee_rust目录都是可以自己创建ta程序

如果某些文件实在拉不下来,就手拉,从qemu-v8里找,一个一个拉,但版本要一定。

接下来获取工具链:

实在不能获取,就只能手拉下载,解压即可

然后在build目录下:

之后能得到/out/bin文件夹下就是启动文件,设置run.sh启动

接下来是编译rust,在optee_rust里有许多测试用例:

不过当时编译了一天一直报错,首先是helloworld-rs有错误,删除之后再编译就会出现缺少glibc库,解决方案还没有思路,不过应该要看一下makefile是怎么做的。

bj666将数据全部存储在了ta文件中,不需要host的main进行传输数据,用了rc4,输入key就能得到right。

重点是bj888文件,采取了魔改原有aes的方法:

main.c

bj888.ta

该加密是aes的ctr加密。

本题采用optee项目,项目文档地址:https://optee.readthedocs.io/en/latest/

该题采用arm架构,意在找出系统中关键加密文件,从而拿到flag

文件目录:

运行run.sh

输入test进入测试,或者root进入系统,主要关注/usr/bin下可执行程序,由于optee环境中optee_example_*开头文件是源项目optee_expample文件夹下所编译文件,再对比源库,甚至可以从名字看出optee_example_bj666,optee_example_bj777,optee_example_bj888这写文件是后来写的文件

其实每一个文件都是有深意的,如果仔细看过optee_example_bj666代码,其实只需要找到ta文件就能逆向,而optee_example_bj777文件,是通过ca向ta传入key才可以逆向。上述两个文件也就演示了一些可信文件的基本操作。

找到可疑ca文件后,如何定位到ta文件也是考点之一,ta文件在/lib/optee_armtz目录下,以uuid开头,两种方法定位到对应uuid,第一种可以遍历目录下文件,查看字符串(如文件名bj777或者wrong)这种关键字符串。第二种通过strace可以轻松拿到对应ta文件的uuid:

从上述分析,我们只需要看bj888文件即可,先看ca文件

该main函数向ta文件传了一个字符串,并且判断字符串长度是否为27

接下来是045ccc45-ee83-43ec-b69f-121819c1ba6b.ta文件

可以看到主要逻辑是获取key和iv然后进行加密,再对比。如果有手动构建过optee的话,这个其实就是内置的aes的ctr加密魔改过来的,加密并没有魔改,只是将key和iv初始化在了host,下面可以直接用在线网站跑出结果:

当然,最好的方法是修改optee_example_aes文件中host目录下的main:

然后编译运行,可以直接跑出flag:sctf{T3e_not_s4f3_anym0re!}

当然该题还可以进行动态调试,只需要把run.sh最后一行改为:

指定串口即可,然后run.sh运行,再用gdb连接,接下来下断点到文件加载处,便可以进行动态调试。

这次出题学到了很多,在赛后也受到许多大师傅的启发,之后会让题出的更有逻辑和思路,而不是一味的堆砌。在这次出题后,在平时需要进行沉淀和思考,不能急于求成。

题目链接:链接:https://pan.baidu.com/s/1kVAGU1RwJJ8iDUkPhqPpGA
提取码:8u9r

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mkdir ~/bin
PATH=~/bin:$PATH
//下载工具并执行
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
mkdir ~/bin
PATH=~/bin:$PATH
//下载工具并执行
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
 
cd optee
mkdir optee
repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml --repo-url=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/ -b 3.18.0
cd optee
mkdir optee
repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml --repo-url=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/ -b 3.18.0
 
 
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
        <remote name="github"   fetch="https://github.com" />
        <remote name="tfo"      fetch="https://git.trustedfirmware.org" />
 
        <default remote="github" revision="master" clone-depth="1"/>
 
        <!-- OP-TEE gits -->
        <project path="optee_client"         name="OP-TEE/optee_client.git" revision="refs/tags/3.8.0" clone-depth="1" />
        <project path="optee_os"             name="OP-TEE/optee_os.git" revision="refs/tags/3.8.0" clone-depth="1" />
        <project path="optee_test"           name="OP-TEE/optee_test.git" revision="refs/tags/3.8.0" clone-depth="1" />
        <project path="build"                name="OP-TEE/build.git" revision="refs/tags/3.8.0" clone-depth="1">
                <linkfile src="qemu_v8.mk" dest="build/Makefile" />
        </project>
 
        <!-- linaro-swg gits -->
        <project path="linux"                name="linaro-swg/linux.git"                  revision="9823b258b332b4ac98e05fa23448bbc9e937b24c" clone-depth="1" />
        <project path="optee_benchmark"      name="linaro-swg/optee_benchmark.git" revision="refs/tags/3.8.0" clone-depth="1"/>
        <project path="optee_examples"       name="linaro-swg/optee_examples.git" revision="refs/tags/3.8.0" clone-depth="1" />
        <project path="soc_term"             name="linaro-swg/soc_term.git"               revision="5493a6e7c264536f5ca63fe7511e5eed991e4f20" clone-depth="1" />
 
        <!-- Misc gits -->
        <project path="buildroot"            name="buildroot/buildroot.git"               revision="95942f5fcd35d783a49adce621ccf33480f1c88c" clone-depth="1" />
        <project path="edk2"                 name="tianocore/edk2.git"                    revision="dd4cae4d82c7477273f3da455084844db5cca0c0" clone-depth="1" />
        <project path="mbedtls"              name="ARMmbed/mbedtls.git"                   revision="refs/tags/mbedtls-2.16.0" clone-depth="1" />
        <project path="qemu"                 name="qemu/qemu.git"                         revision="refs/tags/v3.1.0-rc3" clone-depth="1" />
        <project path="trusted-firmware-a"   name="TF-A/trusted-firmware-a.git"           revision="34efb683e32254b8c325ac3071c5776d243a7b99" remote="tfo" />
</manifest>
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
        <remote name="github"   fetch="https://github.com" />
        <remote name="tfo"      fetch="https://git.trustedfirmware.org" />
 
        <default remote="github" revision="master" clone-depth="1"/>
 
        <!-- OP-TEE gits -->
        <project path="optee_client"         name="OP-TEE/optee_client.git" revision="refs/tags/3.8.0" clone-depth="1" />
        <project path="optee_os"             name="OP-TEE/optee_os.git" revision="refs/tags/3.8.0" clone-depth="1" />
        <project path="optee_test"           name="OP-TEE/optee_test.git" revision="refs/tags/3.8.0" clone-depth="1" />
        <project path="build"                name="OP-TEE/build.git" revision="refs/tags/3.8.0" clone-depth="1">
                <linkfile src="qemu_v8.mk" dest="build/Makefile" />
        </project>
 
        <!-- linaro-swg gits -->
        <project path="linux"                name="linaro-swg/linux.git"                  revision="9823b258b332b4ac98e05fa23448bbc9e937b24c" clone-depth="1" />
        <project path="optee_benchmark"      name="linaro-swg/optee_benchmark.git" revision="refs/tags/3.8.0" clone-depth="1"/>
        <project path="optee_examples"       name="linaro-swg/optee_examples.git" revision="refs/tags/3.8.0" clone-depth="1" />
        <project path="soc_term"             name="linaro-swg/soc_term.git"               revision="5493a6e7c264536f5ca63fe7511e5eed991e4f20" clone-depth="1" />
 
        <!-- Misc gits -->
        <project path="buildroot"            name="buildroot/buildroot.git"               revision="95942f5fcd35d783a49adce621ccf33480f1c88c" clone-depth="1" />
        <project path="edk2"                 name="tianocore/edk2.git"                    revision="dd4cae4d82c7477273f3da455084844db5cca0c0" clone-depth="1" />
        <project path="mbedtls"              name="ARMmbed/mbedtls.git"                   revision="refs/tags/mbedtls-2.16.0" clone-depth="1" />
        <project path="qemu"                 name="qemu/qemu.git"                         revision="refs/tags/v3.1.0-rc3" clone-depth="1" />
        <project path="trusted-firmware-a"   name="TF-A/trusted-firmware-a.git"           revision="34efb683e32254b8c325ac3071c5776d243a7b99" remote="tfo" />
</manifest>
 
//-j是开启多线程, 不加也可以
repo sync -j8
//-j是开启多线程, 不加也可以
repo sync -j8
 
//将配置单换成.git速度更快
sed -i "s/\.git//g" .repo/manifest.xml
//将配置单换成.git速度更快
sed -i "s/\.git//g" .repo/manifest.xml
 
export https_proxy=http://127.0.0.1:7890
http_proxy=http://127.0.0.1:7890
all_proxy=socks5://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
http_proxy=http://127.0.0.1:7890
all_proxy=socks5://127.0.0.1:7890
 
 
 
 
 
 
cd build
make toolchains
cd build
make toolchains
 
 
make
make
 
 
 
 
static TEE_Result www(uint32_t param_types,
    TEE_Param params[4])
{
    uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
                           TEE_PARAM_TYPE_NONE,
                           TEE_PARAM_TYPE_NONE,
                           TEE_PARAM_TYPE_NONE);
 
    //who需要爆破
    const char *who = (const char *)(params[0].memref.buffer);
    const size_t GREETING_LEN = strlen(who);
    if (param_types != exp_param_types)
        return TEE_ERROR_BAD_PARAMETERS;
    char *buf = TEE_Malloc(strlen(who) + GREETING_LEN + 1, 0);
 
    if (!buf)
    {
        return TEE_ERROR_OUT_OF_MEMORY;
    }
    int data[34] = {0x73,0x63,0x74,0x66,0x7b,0x54,0x65,0x33,0x26,0x54,0x41,0x5f,0x69,0x73,0x5f,0x73,0x61,0x66,0x33,0x5f,0x62,0x75,0x74,0x5f,0x46,0x41,0x4b,0x45,0x5f,0x46,0x4c,0x41,0x47,0x7d};
    enc_dec(who,data);
    int cmp[34] = {0x8e,0xd6,0x93,0x67,0x84,0xce,0xd2,0x7d,0xcb,0x9a,0xb7,0xa8,0x65,0xe6,0x97,0x80,0x63,0x26,0x74,0x7c,0xdf,0xcd,0x3a,0x8b,0x9f,0x38,0x9e,0x9f,0x7a,0xd4,0x9d,0xfe,0x36,0x88};
    for(int i = 0; i < strlen(data); i++){
        if(cmp[i] != data[i])
        {
            sprintf(buf, "wrong %s", who);
            params[0].memref.size = strlen(buf) + 1;
            TEE_MemMove(params[0].memref.buffer, buf, params[0].memref.size);
            TEE_Free(buf);
            return TEE_ERROR_BAD_PARAMETERS;
        }
    }
    char *buf1 = TEE_Malloc(strlen(who) + GREETING_LEN + 1, 0);
    sprintf(buf1, "right but it is a test ^_^%s", who);
    params[0].memref.size = strlen(buf1) + 1;
    TEE_MemMove(params[0].memref.buffer, buf1, params[0].memref.size);
    TEE_Free(buf1);
    return TEE_SUCCESS;
}
static TEE_Result www(uint32_t param_types,
    TEE_Param params[4])
{
    uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
                           TEE_PARAM_TYPE_NONE,
                           TEE_PARAM_TYPE_NONE,
                           TEE_PARAM_TYPE_NONE);
 
    //who需要爆破
    const char *who = (const char *)(params[0].memref.buffer);
    const size_t GREETING_LEN = strlen(who);
    if (param_types != exp_param_types)
        return TEE_ERROR_BAD_PARAMETERS;
    char *buf = TEE_Malloc(strlen(who) + GREETING_LEN + 1, 0);
 
    if (!buf)
    {
        return TEE_ERROR_OUT_OF_MEMORY;
    }
    int data[34] = {0x73,0x63,0x74,0x66,0x7b,0x54,0x65,0x33,0x26,0x54,0x41,0x5f,0x69,0x73,0x5f,0x73,0x61,0x66,0x33,0x5f,0x62,0x75,0x74,0x5f,0x46,0x41,0x4b,0x45,0x5f,0x46,0x4c,0x41,0x47,0x7d};
    enc_dec(who,data);
    int cmp[34] = {0x8e,0xd6,0x93,0x67,0x84,0xce,0xd2,0x7d,0xcb,0x9a,0xb7,0xa8,0x65,0xe6,0x97,0x80,0x63,0x26,0x74,0x7c,0xdf,0xcd,0x3a,0x8b,0x9f,0x38,0x9e,0x9f,0x7a,0xd4,0x9d,0xfe,0x36,0x88};
    for(int i = 0; i < strlen(data); i++){
        if(cmp[i] != data[i])
        {
            sprintf(buf, "wrong %s", who);
            params[0].memref.size = strlen(buf) + 1;
            TEE_MemMove(params[0].memref.buffer, buf, params[0].memref.size);
            TEE_Free(buf);
            return TEE_ERROR_BAD_PARAMETERS;
        }
    }
    char *buf1 = TEE_Malloc(strlen(who) + GREETING_LEN + 1, 0);
    sprintf(buf1, "right but it is a test ^_^%s", who);
    params[0].memref.size = strlen(buf1) + 1;
    TEE_MemMove(params[0].memref.buffer, buf1, params[0].memref.size);
    TEE_Free(buf1);
    return TEE_SUCCESS;
}
 
 
 
/*
 * Copyright (c) 2017, Linaro Limited
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include <inttypes.h>
#include<string.h>
#include <tee_internal_api.h>
#include <tee_internal_api_extensions.h>
 
#include <bj888_ta.h>
 
#define BJ888128_KEY_BIT_SIZE       128
#define BJ888128_KEY_BYTE_SIZE      (BJ888128_KEY_BIT_SIZE / 8)
#define BJ888256_KEY_BIT_SIZE       256
#define BJ888256_KEY_BYTE_SIZE      (BJ888256_KEY_BIT_SIZE / 8)
 
 
static TEE_Result set_bj888_key(void *session, uint32_t param_types,
                TEE_Param params[4])
{
    const uint32_t exp_param_types =
        TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
                TEE_PARAM_TYPE_NONE,
                TEE_PARAM_TYPE_NONE,
                TEE_PARAM_TYPE_NONE);
    struct bj888_cipher *sess;
    TEE_Attribute attr;
    TEE_Result res;
    uint32_t key_sz1;
    char *key1;
 
    /* Get ciphering context from session ID */
    DMSG("Session %p: load ", session);
    sess = (struct bj888_cipher *)session;
 
    /* Safely get the invocation parameters */
    if (param_types != exp_param_types)
        return TEE_ERROR_BAD_PARAMETERS;
 
    key1 = params[0].memref.buffer;
    key_sz1 = params[0].memref.size;
 
    if (key_sz1 != sess->key_size) {
        EMSG("Wrong size %" PRIu32 ", expect %" PRIu32 " bytes",
             key_sz1, sess->key_size);
        return TEE_ERROR_BAD_PARAMETERS;
    }
 
    /*
     * Load the key material into the configured operation
     * - create a secret key attribute with the key material
     *   TEE_InitRefAttribute()
     * - reset transient object and load attribute data
     *   TEE_ResetTransientObject()
     *   TEE_PopulateTransientObject()
     * - load the key (transient object) into the ciphering operation
     *   TEE_SetOperationKey()
     *
     * TEE_SetOperationKey() requires operation to be in "initial state".
     * We can use TEE_ResetOperation() to reset the operation but this
     * API cannot be used on operation with key(s) not yet set. Hence,
     * when allocating the operation handle, we load a dummy key.
     * Thus, set_key sequence always reset then set key on operation.
     */
     //bj888默认一个key
    //char *key = "snbjklefsdcvfsyc";
    //uint32_t key_sz = 16;
    TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key1, key_sz1);
 
    TEE_ResetTransientObject(sess->key_handle);
    res = TEE_PopulateTransientObject(sess->key_handle, &attr, 1);
    if (res != TEE_SUCCESS) {
        EMSG("TEE failed, %x", res);
        return res;
    }
 
    TEE_ResetOperation(sess->op_handle);
    res = TEE_SetOperationKey(sess->op_handle, sess->key_handle);
    if (res != TEE_SUCCESS) {
        EMSG("TEE failed %x", res);
        return res;
    }
 
    return res;
}
 
/*
 * Process command TA_BJ888_CMD_SET_IV. API in bj888_ta.h
 */
static TEE_Result reset_bj888_iv(void *session, uint32_t param_types,
                TEE_Param params[4])
{
    const uint32_t exp_param_types =
        TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
                TEE_PARAM_TYPE_NONE,
                TEE_PARAM_TYPE_NONE,
                TEE_PARAM_TYPE_NONE);
    struct bj888_cipher *sess;
    size_t iv_sz1;
    char *iv1;
 
    /* Get ciphering context from session ID */
    DMSG("Session %p: no hint", session);
    sess = (struct bj888_cipher *)session;
 
    /* Safely get the invocation parameters */
    if (param_types != exp_param_types)
        return TEE_ERROR_BAD_PARAMETERS;
 
    iv1 = params[0].memref.buffer;
    iv_sz1 = params[0].memref.size;
 
    /*
     * Init cipher operation with the initialization vector.
     */
    //char *iv = "snbjklefsdcvfsyc";
    //uint32_t iv_sz = 16;
    TEE_CipherInit(sess->op_handle, iv1, iv_sz1);
 
    return TEE_SUCCESS;
}
 
/*
 * Process command TA_BJ888_CMD_CIPHER. API in bj888_ta.h
 */
static TEE_Result cipher_buffer(void *session, uint32_t param_types,
                TEE_Param params[4])
{
    const uint32_t exp_param_types =
        TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
                TEE_PARAM_TYPE_MEMREF_OUTPUT,
                TEE_PARAM_TYPE_NONE,
                TEE_PARAM_TYPE_NONE);
    struct bj888_cipher *sess;
 
    /* Get ciphering context from session ID */
    DMSG("Session %p: no hints", session);
    sess = (struct bj888_cipher *)session;
 
    /* Safely get the invocation parameters */
    if (param_types != exp_param_types)
        return TEE_ERROR_BAD_PARAMETERS;
 
    if (params[1].memref.size < params[0].memref.size) {
        EMSG("Bad sizes: in %d, out %d", params[0].memref.size,
                         params[1].memref.size);
        return TEE_ERROR_BAD_PARAMETERS;
    }
 
    if (sess->op_handle == TEE_HANDLE_NULL)
        return TEE_ERROR_BAD_STATE;
    const char *cipher = (const char *)(params[0].memref.buffer);
    const size_t cipher_len = strlen(cipher);
    /*
     * Process ciphering operation on provided buffers
     */
    TEE_CipherUpdate(sess->op_handle,
                params[0].memref.buffer, params[0].memref.size,
                params[1].memref.buffer, &params[1].memref.size);
    const char *en = (const char *)(params[1].memref.buffer);
    const size_t en_len = 27;
    //char cmp[] = {0x20,0x0b,0x1c,0xff,0xc5,0xa4,0x0a,0xfe,0x31,0x10,0x9d,0x67,0xfe,0xf5,0x60,0xa9,0x9e,0xc6,0x44,0x93,0x36,0xa4,0xfd,0xe9,0x37,0x9d,0x07,0xf1,0x50,0xcc,0x84,0x95};
    char cmp[27] = {0x25,0x03,0x0a,0x6c,0xf8,0xb1,0xce,0x7f,0xc9,0x42,0x0c,0x0d,0x68,0xb3,0x1c,0x04,0x64,0xfa,0xe5,0xa4,0x22,0xd4,0x2c,0xff,0x4e,0x36,0x2a};
    for(int i = 0; i < 27; i++){
        if(cmp[i] != en[i])
        {
            char *buf = "wrong";
            TEE_MemMove(params[0].memref.buffer, buf, 6);
            TEE_Free(buf);
            return TEE_ERROR_BAD_PARAMETERS;
        }
    }
    char *buf1 = "right";
    TEE_MemMove(params[0].memref.buffer, buf1, 6);
    TEE_Free(buf1);
    return TEE_SUCCESS;
}
/*
 * Copyright (c) 2017, Linaro Limited
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include <inttypes.h>
#include<string.h>
#include <tee_internal_api.h>
#include <tee_internal_api_extensions.h>
 
#include <bj888_ta.h>
 
#define BJ888128_KEY_BIT_SIZE       128
#define BJ888128_KEY_BYTE_SIZE      (BJ888128_KEY_BIT_SIZE / 8)
#define BJ888256_KEY_BIT_SIZE       256
#define BJ888256_KEY_BYTE_SIZE      (BJ888256_KEY_BIT_SIZE / 8)
 
 
static TEE_Result set_bj888_key(void *session, uint32_t param_types,
                TEE_Param params[4])
{
    const uint32_t exp_param_types =
        TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
                TEE_PARAM_TYPE_NONE,
                TEE_PARAM_TYPE_NONE,
                TEE_PARAM_TYPE_NONE);
    struct bj888_cipher *sess;
    TEE_Attribute attr;
    TEE_Result res;
    uint32_t key_sz1;
    char *key1;
 
    /* Get ciphering context from session ID */
    DMSG("Session %p: load ", session);
    sess = (struct bj888_cipher *)session;
 
    /* Safely get the invocation parameters */
    if (param_types != exp_param_types)
        return TEE_ERROR_BAD_PARAMETERS;
 
    key1 = params[0].memref.buffer;
    key_sz1 = params[0].memref.size;
 
    if (key_sz1 != sess->key_size) {
        EMSG("Wrong size %" PRIu32 ", expect %" PRIu32 " bytes",
             key_sz1, sess->key_size);
        return TEE_ERROR_BAD_PARAMETERS;
    }
 
    /*
     * Load the key material into the configured operation
     * - create a secret key attribute with the key material
     *   TEE_InitRefAttribute()
     * - reset transient object and load attribute data
     *   TEE_ResetTransientObject()
     *   TEE_PopulateTransientObject()
     * - load the key (transient object) into the ciphering operation
     *   TEE_SetOperationKey()
     *
     * TEE_SetOperationKey() requires operation to be in "initial state".
     * We can use TEE_ResetOperation() to reset the operation but this
     * API cannot be used on operation with key(s) not yet set. Hence,
     * when allocating the operation handle, we load a dummy key.
     * Thus, set_key sequence always reset then set key on operation.
     */
     //bj888默认一个key
    //char *key = "snbjklefsdcvfsyc";
    //uint32_t key_sz = 16;
    TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key1, key_sz1);
 
    TEE_ResetTransientObject(sess->key_handle);
    res = TEE_PopulateTransientObject(sess->key_handle, &attr, 1);
    if (res != TEE_SUCCESS) {
        EMSG("TEE failed, %x", res);
        return res;
    }
 
    TEE_ResetOperation(sess->op_handle);
    res = TEE_SetOperationKey(sess->op_handle, sess->key_handle);
    if (res != TEE_SUCCESS) {
        EMSG("TEE failed %x", res);
        return res;
    }
 
    return res;
}
 
/*
 * Process command TA_BJ888_CMD_SET_IV. API in bj888_ta.h
 */
static TEE_Result reset_bj888_iv(void *session, uint32_t param_types,
                TEE_Param params[4])
{
    const uint32_t exp_param_types =
        TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
                TEE_PARAM_TYPE_NONE,
                TEE_PARAM_TYPE_NONE,
                TEE_PARAM_TYPE_NONE);
    struct bj888_cipher *sess;
    size_t iv_sz1;
    char *iv1;
 
    /* Get ciphering context from session ID */
    DMSG("Session %p: no hint", session);
    sess = (struct bj888_cipher *)session;
 
    /* Safely get the invocation parameters */
    if (param_types != exp_param_types)
        return TEE_ERROR_BAD_PARAMETERS;
 
    iv1 = params[0].memref.buffer;
    iv_sz1 = params[0].memref.size;
 
    /*
     * Init cipher operation with the initialization vector.
     */
    //char *iv = "snbjklefsdcvfsyc";
    //uint32_t iv_sz = 16;
    TEE_CipherInit(sess->op_handle, iv1, iv_sz1);
 
    return TEE_SUCCESS;
}
 
/*
 * Process command TA_BJ888_CMD_CIPHER. API in bj888_ta.h
 */
static TEE_Result cipher_buffer(void *session, uint32_t param_types,
                TEE_Param params[4])
{
    const uint32_t exp_param_types =
        TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
                TEE_PARAM_TYPE_MEMREF_OUTPUT,
                TEE_PARAM_TYPE_NONE,
                TEE_PARAM_TYPE_NONE);
    struct bj888_cipher *sess;

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2023-6-20 16:43 被bj777编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (3)
雪    币: 29183
活跃值: (63681)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2

附件存档一份:

链接: https://pan.baidu.com/s/1OPQ9YRsUseYsCVeORhdUIw?pwd=pte9

2023-6-20 16:41
0
雪    币: 916
活跃值: (3434)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3

其实我是这么确定是哪个 TA 的... 简单粗暴

2023-6-21 15:26
3
雪    币: 377
活跃值: (1331)
能力值: ( LV6,RANK:98 )
在线值:
发帖
回帖
粉丝
4
2023-10-28 07:11
0
游客
登录 | 注册 方可回帖
返回
//