/* * The data to hash is 48 bytes made up of: * - 16 bytes: the UUID of the calling TA. * - 32 bytes: the hardware device ID * The resulting endorsement seed is 32 bytes. * * The output buffer is the "binary" struct defined in * the "prop_value" union and therefore comprises: * - 4 bytes: the size of the binary value data (32) * - 32 bytes: the binary value data (endorsement seed) * * Note that this code assumes an endorsement seed * size == device ID size for convenience. */ static TEE_Result get_prop_endorsement(struct tee_ta_session *sess, void *buf, size_t *blen) { TEE_Result res; uint32_t ta_endorsement_seed_size = 32; uint8_t data[sizeof(TEE_UUID) + ta_endorsement_seed_size]; uint32_t bin[1 + ta_endorsement_seed_size / sizeof(uint32_t)]; uint32_t *bin_len = (uint32_t *)bin; uint8_t *bin_val = (uint8_t *)(&bin[1]); if (*blen < sizeof(bin)) { *blen = sizeof(bin); return TEE_ERROR_SHORT_BUFFER; } *blen = sizeof(bin); memcpy(data, &sess->ctx->uuid, sizeof(TEE_UUID)); if (tee_otp_get_die_id(&data[sizeof(TEE_UUID)], ta_endorsement_seed_size)) return TEE_ERROR_BAD_STATE; res = tee_hash_createdigest(TEE_ALG_SHA256, data, sizeof(data), bin_val, ta_endorsement_seed_size); if (res != TEE_SUCCESS) return TEE_ERROR_BAD_STATE; *bin_len = ta_endorsement_seed_size; return tee_svc_copy_to_user((void *)buf, bin, sizeof(bin)); }
TEE_Result tee_svc_sys_get_property(uint32_t prop, tee_uaddr_t buf, size_t blen) { static const char api_vers[] = "1.0"; static const char descr[] = "Version N.N"; /* * Value 100 means: * System time based on REE-controlled timers. Can be tampered by the * REE. The implementation must still guarantee that the system time * is monotonous, i.e., successive calls to TEE_GetSystemTime must * return increasing values of the system time. */ static const uint32_t sys_time_prot_lvl = 100; static const uint32_t ta_time_prot_lvl = 100; struct tee_ta_session *sess; TEE_Result res; res = tee_ta_get_current_session(&sess); if (res != TEE_SUCCESS) return res; switch (prop) { case UTEE_PROP_TEE_API_VERSION: if (blen < sizeof(api_vers)) return TEE_ERROR_SHORT_BUFFER; return tee_svc_copy_to_user(sess, (void *)buf, api_vers, sizeof(api_vers)); case UTEE_PROP_TEE_DESCR: if (blen < sizeof(descr)) return TEE_ERROR_SHORT_BUFFER; return tee_svc_copy_to_user(sess, (void *)buf, descr, sizeof(descr)); case UTEE_PROP_TEE_DEV_ID: { TEE_UUID uuid; const size_t nslen = 4; uint8_t data[4 + FVR_DIE_ID_NUM_REGS * sizeof(uint32_t)] = { 'S', 'T', 'E', 'E' }; if (blen < sizeof(uuid)) return TEE_ERROR_SHORT_BUFFER; if (tee_otp_get_die_id (data + nslen, sizeof(data) - nslen)) return TEE_ERROR_BAD_STATE; res = tee_hash_createdigest( TEE_ALG_SHA256, data, sizeof(data), (uint8_t *)&uuid, sizeof(uuid)); if (res != TEE_SUCCESS) return TEE_ERROR_BAD_STATE; /* * Changes the random value into and UUID as specifiec * in RFC 4122. The magic values are from the example * code in the RFC. * * TEE_UUID is defined slightly different from the RFC, * but close enough for our purpose. */ uuid.timeHiAndVersion &= 0x0fff; uuid.timeHiAndVersion |= 5 << 12; /* uuid.clock_seq_hi_and_reserved in the RFC */ uuid.clockSeqAndNode[0] &= 0x3f; uuid.clockSeqAndNode[0] |= 0x80; return tee_svc_copy_to_user(sess, (void *)buf, &uuid, sizeof(TEE_UUID)); } case UTEE_PROP_TEE_SYS_TIME_PROT_LEVEL: if (blen < sizeof(sys_time_prot_lvl)) return TEE_ERROR_SHORT_BUFFER; return tee_svc_copy_to_user(sess, (void *)buf, &sys_time_prot_lvl, sizeof(sys_time_prot_lvl)); case UTEE_PROP_TEE_TA_TIME_PROT_LEVEL: if (blen < sizeof(ta_time_prot_lvl)) return TEE_ERROR_SHORT_BUFFER; return tee_svc_copy_to_user(sess, (void *)buf, &ta_time_prot_lvl, sizeof(ta_time_prot_lvl)); case UTEE_PROP_TEE_ARITH_MAX_BIG_INT_SIZE: { uint32_t v = LTC_MAX_BITS_PER_VARIABLE / 2; if (blen < sizeof(v)) return TEE_ERROR_SHORT_BUFFER; return tee_svc_copy_to_user(sess, (void *)buf, &v, sizeof(v)); } case UTEE_PROP_CLIENT_ID: { if (blen < sizeof(TEE_Identity)) return TEE_ERROR_SHORT_BUFFER; return tee_svc_copy_to_user(sess, (void *)buf, &sess->clnt_id, sizeof(TEE_Identity)); } case UTEE_PROP_TA_APP_ID: { if (blen < sizeof(TEE_UUID)) return TEE_ERROR_SHORT_BUFFER; return tee_svc_copy_to_user(sess, (void *)buf, &sess->ctx->head->uuid, sizeof(TEE_UUID)); } default: break; } return TEE_ERROR_NOT_IMPLEMENTED; }
static TEE_Result sha256(uint8_t *out, size_t out_size, const uint8_t *in, size_t in_size) { return tee_hash_createdigest(TEE_ALG_SHA256, in, in_size, out, out_size); }