Retrieve Public Key

This section documents how the Trusted Application (TA) securely retrieves the RSA public key from persistent storage.

Overview

  • Purpose: Provide the public part of the RSA key pair for external signature verification.

  • Format: Concatenated modulus and exponent

  • Access: Only public components are exposed; private key remains sealed

Steps

  1. Validate Output Buffer:

    • Ensures the caller’s buffer is large enough to hold modulus + exponent.

  2. Open Persistent RSA Key Object:

    • Retrieves the private key object using TEE_OpenPersistentObject(), which also contains public key parts.

  3. Extract Public Key Attributes:

    • TEE_GetObjectBufferAttribute() is used to fetch:

      • Modulus (n)

      • Public exponent (e)

  4. Copy to Output Buffer:

    • The function copies both parts into a single continuous output buffer.

    • Updates the length field to reflect actual data written.

Code Reference

 1TEE_Result get_rsa_public_key(uint8_t *public_key, size_t *public_key_len)
 2{
 3    TEE_Result res;
 4    TEE_ObjectHandle pubkey_handle = TEE_HANDLE_NULL;
 5    uint32_t flags = TEE_DATA_FLAG_ACCESS_READ;
 6    uint8_t modulus[RSA_MODULUS_SIZE];
 7    uint8_t exponent[RSA_EXPONENT_SIZE];
 8    uint32_t mod_len = sizeof(modulus);
 9    uint32_t exp_len = sizeof(exponent);
10
11    /* Check if the public key buffer is large enough */
12    if (*public_key_len < RSA_PUBLIC_KEY_SIZE)
13    {
14        EMSG("Public key buffer too small, expected size: %u bytes", RSA_PUBLIC_KEY_SIZE);
15        return TEE_ERROR_SHORT_BUFFER;
16    }
17
18    /* Open the persistent RSA key pair */
19    res = TEE_OpenPersistentObject(
20        TEE_STORAGE_PRIVATE,              /* storageID */
21        RSA_KEYPAIR_STORAGE_NAME,         /* objectID */
22        strlen(RSA_KEYPAIR_STORAGE_NAME), /* objectIDLen */
23        flags,                            /* flags */
24        &pubkey_handle                    /* object */
25    );
26    if (res != TEE_SUCCESS)
27    {
28        EMSG("Failed to open RSA key pair for public key retrieval, res=0x%08x", res);
29        return res;
30    }
31
32    /* Read modulus */
33    res = TEE_GetObjectBufferAttribute(pubkey_handle, TEE_ATTR_RSA_MODULUS, modulus, &mod_len);
34    if (res != TEE_SUCCESS)
35    {
36        EMSG("Failed to get modulus: 0x%08x", res);
37        TEE_CloseObject(pubkey_handle);
38        return res;
39    }
40
41    /* Read public exponent */
42    res = TEE_GetObjectBufferAttribute(pubkey_handle, TEE_ATTR_RSA_PUBLIC_EXPONENT, exponent, &exp_len);
43    TEE_CloseObject(pubkey_handle);
44    if (res != TEE_SUCCESS)
45    {
46        EMSG("Failed to get exponent: 0x%08x", res);
47        return res;
48    }
49
50    /* Copy modulus and exponent into output buffer */
51    TEE_MemMove(public_key, modulus, mod_len);
52    TEE_MemMove(public_key + mod_len, exponent, exp_len);
53    *public_key_len = mod_len + exp_len;
54
55    DMSG("RSA public key successfully retrieved");
56    return TEE_SUCCESS;
57}

Output Format

The final public_key buffer contains:

  • [0:n] — RSA Modulus

  • [n:n+e] — RSA Public Exponent

Total size is set via:

*public_key_len = mod_len + exp_len;

Possible Results

  • TEE_ERROR_SHORT_BUFFER: Output buffer too small

  • TEE_ERROR_ITEM_NOT_FOUND: RSA key object missing

  • TEE_ERROR_BAD_PARAMETERS: Invalid buffer or flags

  • TEE_SUCCESS: Public key successfully retrieved