# Equipment certification TEE specification

# 1. background

Device identity is WeChat VOIP Business to be able to function properly on the basis that developers in access VOIP Business, identity will be determined through the following two processes:

  1. Device registration. adopt SN + modelId Two dimensions to calibrate this device.
  2. Get the tickets. In the ongoing VOIP Before the call, you need to get the ticket corresponding to this device.

For no TEE Of the machine, we require the equipment system to be able to operate EMMC Stored RPMB Region, and the need to place RPMB The right of attribution to VOIP Business, VOIP A unique key corresponding to the device is written to the stored KEY Area for identity verification.

And for those with TEE The machine we trust. TEE Of the results, but the need for TEE Done according to the specifications TA Development of.

# 2. TA Development

Whether it's Optee, or trusty or qsee Etc., TEE The flow of usage is usually as follows:

open TEE Environment > Opening a Session > Send command > Access to information > End Session > Stop TEE Environment

Here we need to define the following criteria:

  1. The session name.
  2. Function of the command.
  3. Interactive data definition for the command.
  4. TA The operational logic in

Device developers need to develop according to the specification as follows:

  1. TA Development, requires a developer or tee Providers are developed according to specifications TA。
  2. HAL Development, HAL Used in conjunction with TA WeChat's system services are based on this HAL。
  3. Service integration, the WeChat released rpmbd_tee Run as a system service.

TA inlogicThe storage is divided into two areas. It is important to note that this data should ultimately be present in EMMC or UFS of rpmb Division, or other REE Inaccessible safe device areas.

  1. Key area: 32 bytes. he or she The code logic needs to implement this area so that it can only be written once, similar to the hardware OTP (One Time Programmable) Region.
  2. Data Area: The units are Block, each Block Yes 256 One byte, minimum required 32 The developer can determine the size according to the actual situation, and if the border is crossed, the corresponding error code is returned. Block The address of the 0 Here we go.

# 2.1 Session name

TA The name of the unified ta_Devauth

# 2.2 Command definition

Define three commands, read data, write data, and write key.

#Define TA_DEVAUTH_CMD_READ   0x10
#Define TA_DEVAUTH_CMD_WRITE  0x11
#Define TA_DEVAUTH_CMD_PROKEY 0x12

Detailed Dxplaination:

command TA_DEVAUTH_CMD_READ 0x10
function read 1 individual Block The data of the
parameter Input: Block address
input/Output: Block data BUFFER, 284 bytes, see 2.3 Data definition.
Output: Signature BUFFER, = 32 bytes
return 0: Successfully read and return 284 Byte Data and 32 Byte signature
-1: Parameter error.
- 2: The address crosses the line.
-3: The key area has not been written yet.
- 5: Other errors.
Special note If the keyfield has not been written (for example, the bare data is all 0x00, or there is no TEE document file in the system? ), this case is considered to be a brand new, unactivated device that needs to read the error return -3。
command TA_DEVAUTH_CMD_WRITE 0x11
function write 1 individual Block The data of the
parameter Input: Block address
Input: Block data BUFFER, = 284 bytes, see 2.3 Data definition.
Input: The corresponding signature BUFFER, = 32 bytes
return 0: Write successfully.
-1: Parameter error.
- 2: The address crosses the line.
-3: The key area has not been written yet.
-4: Signature error.
- 5: Other errors.
Special note If the keyfield has not been written (for example, the bare data is all 0x00, or there is no TEE document file in the system? ), this case is considered a brand new, unactivated device that needs to be returned -3。
This function needs to calculate the signature of the data before writing the data, and compare it with the signature passed in by the parameter. -4
command TA_DEVAUTH_CMD_PROKEY 0x12
function Write key
parameter Key BUFFER, = 32 bytes
return 0: Write successfully.
-1: Parameter error.
- 3: The key area has data.
- 5: Other errors.
Special note If there is already data in the keyarea (for example, the naked data is not 0x00, or there is a file? ), you need to return the -3。

# 2.3 Data definition

and TA Incoming and outgoing when interacting Buffer The size of the 284 byte, which is defined as follows:

struct ta_Data {
    uint8_t  Data[256]    // this 256 Bytes are TA Content written to 1 block
    uint8_t  nonce[16]    // Generally random bytes, incoming and outgoing must be consistent.
    uint32_t reserve1
    uint16_t reserve2
    uint16_t reserve3
    uint16_t reserve4
    uint16_t reserve5
}

// sizeof(struct ta_Data) = 284

autograph Buffer The size is 32 byte


CA and TA Interactive Message Definition:
struct ta_message {
    uint32_t        cmd        // Command number 
    uint32_t        block      // Read and write address
    struct ta_Data  Data       // 284 Byte data
    uint8_t         key[32]    // 32 byte Key
    uint8_t         hmac[32]   // 32 byte hmac
    int             ret        // Return value
}

CA Side Reference Pseudocode:

static int tee_send_cmd_req(struct ta_message* ta_msg) {
    int rc = 0
    
    if (ca_handle == 0) {
        printf("not connectedn")
        return -EINVAL 
    }
    
    if (tee_send_msg(ca_handle, ta_msg) < 0) {
        return -1
    }
    
    if (tee_resp_msg(ca_handle, ta_msg) < 0) {
        return -1
    }
    
    return 0
}

# 2.4 Operational logic

The data signature algorithm is HMAC_SHA256。

When reading the data, TA Of the process:

  1. If there is no data in the key area, return -3。
  2. Read address parameter correspondence Block of 256 Byte data.
  3. Will read. 256 Byte and the input parameter in the 16 byte Noce And others Reserve, a total of 284 One byte.
  4. Using the key area's 32 Byte key? Yeah. 284 Byte for signature, and returns the 284 Bytes as well as signatures.

When writing data, TA Of the process:

  1. If there is no data in the key area, return -3。
  2. Get the input parameter 284 Byte to get the signature 1 in the input parameter.
  3. Using the key area's 32 Byte key? Yeah. 284 Byte for signature, get signature 2.
  4. Compare signature 1 with signature 2, if equal, 284 In bytes 256 Byte is written to the corresponding Block, if not, returns an error -4。

When writing the key, TA Of the process:

  1. If the key area already has data, return -3。
  2. will 32 Byte's key is written to the keypad.

A signed data example, developers can use as a benchmark to verify their own hmac_sha256:

char *key = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH"
uint8_t buffer[284] = {0}

int Main(int argc, char **argv) {
    uint8_t hmac[32] = {0}
    memset (buffer, 0x55, 284)

    hmac_sha256(key, 32,
      buffer, 284,
      hmac, sizeof(hmac)
    )

    for (int i=0 i < 32 i++) {
        printf("%02x ", hmac[i])
    }
    return 0
}
// The above code output:
// 61 16 67 22 a0 93 66 74 bb 75 f8 87 0e 5e d4 59 2c d6 99 c0 14 a6 93 70 bd ff EA  3e 8e 84 52 4e 

hmac_sha256 For standard algorithms, generally tee There is such an algorithm, if not, you can refer toOpen source implementation

# 2.5 Note

  1. TEE The key area and the data area in the "Permanent Storage" Characteristics, and should not be REE Direct access in any way and will not be lost with the user's swiping, upgrading, or other routine actions.
  2. The key region needs to be implemented as OTP Feature, that is, write only once.
  3. When there is no data in the key area, the error code needs to be returned according to the specification.
  4. Manufacturers will need to CA Test routines and code to WeChat, WeChat acceptance test.

# 3. HAL Development

according to HAL Specification completed HAL Development of, HAL Used in CA Code and TA To interact and complete TEE Of the use.

HAL Path:android/hardware/Interface/Devauth

# 3.1 HAL specification

types.hal

package android.hardware.devauth@1.0

enum TA_CMD : uint32_t {
    TA_DEVAUTH_CMD_READ = 0x10,
    TA_DEVAUTH_CMD_WRITE = 0x11,
    TA_DEVAUTH_CMD_PROKEY = 0x12,
}

struct ta_Data {
    uint8_t[256] Data // this 256 Bytes are TA Content written to 1 block
    uint8_t[16]  nonce // Generally random bytes, incoming and outgoing must be consistent.
    uint32_t reserve1
    uint16_t reserve2
    uint16_t reserve3
    uint16_t reserve4
    uint16_t reserve5
}

struct ta_message {
    uint32_t        cmd        // Command number 
    uint32_t        block      // Read and write address
    ta_Data         Data       // 284 Byte data
    uint8_t[32]     key        // 32 byte Key
    HMacBuffer      hmac       // 32 byte hmac
    int8_t          ret        // Return value
}

typedef uint8_t[32] HMacBuffer
typedef uint8_t[32] ProKeyBuffer

typedef ta_Data ta_Data_t
typedef ta_message ta_message_t

IDevauth.hal

package android.hardware.devauth@1.0

Interface IDevauth  {

    /**
     * read Block data
     *
     * @param  addr:     Block address
     * @param  data:     Input struct ta_Data
     * @return retval:   Return value, see specification for return value
     * @return data:    Returned struct ta_data,284 Bytes.
     * @return hmac:    The signature returned, 32 Bytes.
     *
     */
    read_block(uint16_t addr, ta_Data Data) generates (int8_t retval, Vec <uint8_t> data, Vec <uint8_t> hmac) 

    /**
     * write Block data
     *
     * @param  addr:     Block address
     * @param  data:     Input and output data, corresponding to the struct ta_data,284 Bytes.
     * @param  hmac:     HAL The signature used to write data, 32 byte
     *
     * @return retval:   Return Value Dxplaination See specification
     */
    write_block(uint16_t addr, ta_Data data, HMacBuffer hmac) generates (int8_t retval ) 

    /**
     * write Key
     *
     * @param  key:      32 Byte key
     *
     * @return retval:   Return Value Dxplaination See specification
     */
    program_key(ProKeyBuffer key) generates(int8_t retval )
}

# 3.2 Development reference

hardware/interfaces/Devauth /1.0/ Under Placement IDevauth.haltypes.hal, as above.

Then generate the code as follows:

LOC=hardware/interfaces/Devauth /1.0/default
PACKAGE=android.hardware.devauth@1.0
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware /interfaces -randroid.hidl:system/libhidl /transport ${PACKAGE}
hidl-gen -o $LOC -Landroidbp-impl  -randroid.hardware:hardware /interfaces -randroid.hidl:system/libhidl /transport ${PACKAGE}
./hardware/interfaces/update-makefiles.sh

here hal The directory should be as follows:

root/android> tree hardware/interfaces/Devauth /
hardware/interfaces/Devauth /
 1.0
     Android.bp
     default
        Android.bp
        Devauth.cpp 
        Devauth.h 
     IDevauth.hal 
     types.hal 

2 directories, 6 files

Again in accordance with HAL Interface definition, done in the corresponding interface function CA Development of the code.

# 4. acceptance

# 4.1 Submission of information

  • Chip platform, storage type. Examples: MTK81xx, EMMC 64GB
  • REE Operating system details. Example: Android 7 64bit
  • TEE System details. Example: Based on optee Self-study of Tee, the provider for XXX
  • TEE Data storage location. Example: EMMC In RPMB partition
  • TEE Lateral TA Code. Example: He_Devauth Module code
  • REE Lateral CA Code. Example: Test case code package and corresponding TEE function so。
  • REE Lateral HAL Code. Example: hardware/Interface/Devauth Under the code.
  • can adb root The prototype.

# 4.2 Test case

Developer Completed TEE of TA Development, test case development should be performed to verify TA Function and logic. Pre-conditions:ta_deauth No data available for areas managed, and then perform the following tests in order.

  1. Read the data test, expect to return -3
  2. Write data tests, expect to return -3
  3. Write key test, expected to return 0
  4. Write key test, expected to return -3
  5. Read the data test, expect to return 0 and all the data is 0x00 And signed.
  6. With the right HMAC Write data tests, expect to return 0
  7. With the wrong HMAC Write data tests, expect to return -4
  8. Read the data test, expect to return 0, and return the correct data and signature.

Available at[Official Test Case Code](https://git.weixin.qq.com /wxa_iot/Devauth _tee_testcase/tree/master/ca_testcase)On the basis of, plus their own CA Implementation, in order to quickly verify TA。

Developer Completed HAL After development, available[Test case](https://git.weixin.qq.com /wxa_iot/Devauth _tee_testcase/tree/master/hal_testcase)For testing,

You can also download the compiled tee_hal_test For testing, the test method is as follows

  1. tee_hal_test a For a whole new test that requires a ta_Devauth No data were available for the areas managed.
  2. tee_hal_test Without any parameters, available in the 1. After running.

# 4.3 integrated

4.2 After the test cases in the rpmbd_tee And integrated into the system to operate in a service manner, refer to:

service rpmbd_tee /system/bin/rpmbd_tee
  class Main
  user root
  group root system

tee_hal_test and rpmbd_tee Available fromthis placeto download