1 /* 2 * Copyright (c) 2024, The ChromiumOS Authors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stdint.h> 9 #include <string.h> 10 11 #include <common/debug.h> 12 #include <common/runtime_svc.h> 13 #include <lib/psci/psci.h> 14 #include <lib/xlat_tables/xlat_tables_v2.h> 15 #include <services/oem/chromeos/widevine_smc_handlers.h> 16 #include <tools_share/uuid.h> 17 18 #define CROS_OEM_TPM_AUTH_PK_MAX_LEN 128 19 #define CROS_OEM_HUK_LEN 32 20 #define CROS_OEM_ROT_LEN 32 21 22 static uint8_t cros_oem_tpm_auth_pk_buffer[CROS_OEM_TPM_AUTH_PK_MAX_LEN]; 23 static uint8_t cros_oem_huk_buffer[CROS_OEM_HUK_LEN]; 24 static uint8_t cros_oem_rot_len_buffer[CROS_OEM_ROT_LEN]; 25 26 struct cros_oem_data cros_oem_tpm_auth_pk = { 27 .buffer = cros_oem_tpm_auth_pk_buffer, 28 .max_length = sizeof(cros_oem_tpm_auth_pk_buffer), 29 }; 30 31 struct cros_oem_data cros_oem_huk = { 32 .buffer = cros_oem_huk_buffer, 33 .max_length = sizeof(cros_oem_huk_buffer), 34 }; 35 36 struct cros_oem_data cros_oem_rot = { 37 .buffer = cros_oem_rot_len_buffer, 38 .max_length = sizeof(cros_oem_rot_len_buffer), 39 }; 40 41 static uintptr_t cros_write_data(struct cros_oem_data *data, 42 u_register_t length, u_register_t address, 43 void *handle) 44 { 45 uintptr_t aligned_address; 46 uintptr_t aligned_size; 47 int32_t rc; 48 49 if (data->length) { 50 SMC_RET1(handle, PSCI_E_ALREADY_ON); 51 } 52 53 if (length > data->max_length) { 54 SMC_RET1(handle, PSCI_E_INVALID_PARAMS); 55 } 56 57 aligned_address = page_align(address, DOWN); 58 aligned_size = page_align(length + (address - aligned_address), UP); 59 60 /* 61 * We do not validate the passed in address because we are trusting the 62 * non-secure world at this point still. 63 */ 64 rc = mmap_add_dynamic_region(aligned_address, aligned_address, 65 aligned_size, MT_MEMORY | MT_RO | MT_NS); 66 if (rc != 0) { 67 SMC_RET1(handle, PSCI_E_INVALID_ADDRESS); 68 } 69 70 memcpy(data->buffer, (void *)address, length); 71 data->length = length; 72 73 mmap_remove_dynamic_region(aligned_address, aligned_size); 74 SMC_RET1(handle, SMC_OK); 75 } 76 77 /* Handler for servicing specific SMC calls. */ 78 static uintptr_t cros_oem_svc_smc_handler(uint32_t smc_fid, u_register_t x1, 79 u_register_t x2, u_register_t x3, 80 u_register_t x4, void *cookie, 81 void *handle, u_register_t flags) 82 { 83 switch (smc_fid) { 84 case CROS_OEM_SMC_DRM_SET_TPM_AUTH_PUB_FUNC_ID: 85 return cros_write_data(&cros_oem_tpm_auth_pk, x1, x2, handle); 86 case CROS_OEM_SMC_DRM_SET_HARDWARE_UNIQUE_KEY_FUNC_ID: 87 return cros_write_data(&cros_oem_huk, x1, x2, handle); 88 case CROS_OEM_SMC_DRM_SET_ROOT_OF_TRUST_FUNC_ID: 89 return cros_write_data(&cros_oem_rot, x1, x2, handle); 90 default: 91 WARN("Unimplemented OEM Call: 0x%x\n", smc_fid); 92 SMC_RET1(handle, SMC_UNK); 93 } 94 } 95 96 /* Register OEM Service Calls as runtime service */ 97 DECLARE_RT_SVC(cros_oem_svc_smc_handler, OEN_OEM_START, OEN_OEM_END, 98 SMC_TYPE_FAST, NULL, cros_oem_svc_smc_handler); 99