Encryption using CTR Mode

This section explains encrypting data using AES in Counter (CTR) mode within the TEE.

  • Purpose: Encrypts plaintext data with AES-CTR mode using a securely stored AES key.

  • Process Overview:

    1. Obtain AES key: Calls generate_aes_key() to get the key handle.

    2. Allocate cipher operation: Creates an AES-CTR encryption operation with TEE_AllocateOperation(), specifying encryption mode and key size.

    3. Set operation key: Assigns the AES key to the operation via TEE_SetOperationKey().

    4. Generate and prepend IV: Creates a random initialization vector (IV) of AES block size with TEE_GenerateRandom(), stores it at the start of the ciphertext buffer.

    5. Initialize cipher: Initializes the AES-CTR operation with the generated IV using TEE_CipherInit().

    6. Encrypt data: Processes the plaintext into ciphertext (starting after IV) via TEE_CipherUpdate().

    7. Update output length: Sets ciphertext length to the sum of IV size and encrypted data size.

    8. Cleanup: Frees operation and closes key handles, zeroes sensitive buffers.

  • Notes:

    • The first block of ciphertext contains the IV, which is critical for decryption.

    • Each ciphertext has a random IV to ensure uniqueness and security.

    • AES-CTR mode allows parallel encryption, making it efficient for stream data.

 1TEE_Result encrypt_aes_data(const char *plaintext, size_t plaintext_len, uint8_t *ciphertext, size_t *ciphertext_len)
 2{
 3    TEE_Result res;
 4    TEE_ObjectHandle key_handle = TEE_HANDLE_NULL;
 5    TEE_OperationHandle operation = TEE_HANDLE_NULL;
 6    uint8_t iv[AES_BLOCK_SIZE] = {0};
 7    uint32_t enc_len = 0;
 8
 9    /* Retrieve the AES key from persistent storage or generate a new one */
10    res = generate_aes_key(&key_handle);
11    if (res != TEE_SUCCESS)
12    {
13        EMSG("Failed to retrieve AES key, res=0x%08x", res);
14        goto exit;
15    }
16
17    /* Allocate AES-CTR operation */
18    res = TEE_AllocateOperation(&operation, TEE_ALG_AES_CTR, TEE_MODE_ENCRYPT, AES_KEY_SIZE);
19    if (res != TEE_SUCCESS)
20    {
21        EMSG("Failed to allocate operation, res=0x%08x", res);
22        goto exit;
23    }
24
25    res = TEE_SetOperationKey(operation, key_handle);
26    if (res != TEE_SUCCESS)
27    {
28        EMSG("Failed to set operation key, res=0x%08x", res);
29        goto exit;
30    }
31
32    /* Generate a new random IV */
33    TEE_GenerateRandom(iv, AES_BLOCK_SIZE);
34    memcpy(ciphertext, iv, AES_BLOCK_SIZE);
35
36    TEE_CipherInit(operation, iv, AES_BLOCK_SIZE);
37
38    /* Encrypt plaintext after the IV in ciphertext buffer */
39    enc_len = (uint32_t)(*ciphertext_len - AES_BLOCK_SIZE);
40    res = TEE_CipherUpdate(operation, plaintext, plaintext_len, ciphertext + AES_BLOCK_SIZE, &enc_len);
41    if (res != TEE_SUCCESS)
42    {
43        EMSG("Failed to encrypt data, res=0x%08x", res);
44        goto exit;
45    }
46
47    *ciphertext_len = AES_BLOCK_SIZE + enc_len;
48
49exit:
50    if (operation != TEE_HANDLE_NULL)
51        TEE_FreeOperation(operation);
52    if (key_handle != TEE_HANDLE_NULL)
53        TEE_CloseObject(key_handle);
54    TEE_MemFill(iv, 0, sizeof(iv));
55
56    return res;
57}