xref: /rk3399_rockchip-uboot/common/write_keybox.c (revision 6aa65bb1ee0951865e27da81dde1de76c6d4687e)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <optee_include/OpteeClientApiLib.h>
8 #include <optee_include/tee_client_api.h>
9 #include <optee_include/tee_api_defines.h>
10 #include <boot_rkimg.h>
11 #include <stdlib.h>
12 #include <attestation_key.h>
13 #include "write_keybox.h"
14 #include <keymaster.h>
15 
16 #define	BOOT_FROM_EMMC	(1 << 1)
17 #define	WIDEVINE_TAG	"KBOX"
18 #define	ATTESTATION_TAG	"ATTE"
19 
20 uint32_t rk_send_keybox_to_ta(uint8_t *filename, uint32_t filename_size,
21 			      TEEC_UUID uuid,
22 			      uint8_t *key, uint32_t key_size,
23 			      uint8_t *data, uint32_t data_size)
24 {
25 	TEEC_Result TeecResult;
26 	TEEC_Context TeecContext;
27 	TEEC_Session TeecSession;
28 	uint32_t ErrorOrigin;
29 	TEEC_UUID *TeecUuid = &uuid;
30 	TEEC_Operation TeecOperation = {0};
31 	struct blk_desc *dev_desc;
32 
33 	dev_desc = rockchip_get_bootdev();
34 	if (!dev_desc) {
35 		printf("%s: dev_desc is NULL!\n", __func__);
36 		return -TEEC_ERROR_GENERIC;
37 	}
38 
39 	OpteeClientApiLibInitialize();
40 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
41 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
42 						    TEEC_NONE,
43 						    TEEC_NONE,
44 						    TEEC_NONE);
45 
46 	/* 0 nand or emmc "security" partition , 1 rpmb */
47 	TeecOperation.params[0].value.a =
48 		(dev_desc->if_type == IF_TYPE_MMC) ? 1 : 0;
49 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
50 	TeecOperation.params[0].value.a = 0;
51 #endif
52 	TeecResult = TEEC_OpenSession(&TeecContext,
53 				      &TeecSession,
54 				      TeecUuid,
55 				      TEEC_LOGIN_PUBLIC,
56 				      NULL,
57 				      &TeecOperation,
58 				      &ErrorOrigin);
59 
60 	TEEC_SharedMemory SharedMem0 = {0};
61 
62 	SharedMem0.size = filename_size;
63 	SharedMem0.flags = 0;
64 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
65 	memcpy(SharedMem0.buffer, filename, SharedMem0.size);
66 	TEEC_SharedMemory SharedMem1 = {0};
67 
68 	SharedMem1.size = key_size;
69 	SharedMem1.flags = 0;
70 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
71 	memcpy(SharedMem1.buffer, key, SharedMem1.size);
72 	TEEC_SharedMemory SharedMem2 = {0};
73 
74 	SharedMem2.size = data_size;
75 	SharedMem2.flags = 0;
76 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem2);
77 	memcpy(SharedMem2.buffer, data, SharedMem2.size);
78 
79 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
80 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
81 	TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
82 	TeecOperation.params[1].tmpref.size = SharedMem1.size;
83 	TeecOperation.params[2].tmpref.buffer = SharedMem2.buffer;
84 	TeecOperation.params[2].tmpref.size = SharedMem2.size;
85 
86 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
87 						    TEEC_MEMREF_TEMP_INPUT,
88 						    TEEC_MEMREF_TEMP_INOUT,
89 						    TEEC_NONE);
90 
91 	printf("write keybox to secure storage\n");
92 	TeecResult = TEEC_InvokeCommand(&TeecSession,
93 					6,
94 					&TeecOperation,
95 					&ErrorOrigin);
96 	if (TeecResult != TEEC_SUCCESS)
97 		printf("send data to TA failed with code 0x%x\n", TeecResult);
98 	else
99 		printf("send data to TA success with code 0x%x\n", TeecResult);
100 
101 	TEEC_ReleaseSharedMemory(&SharedMem0);
102 	TEEC_ReleaseSharedMemory(&SharedMem1);
103 	TEEC_ReleaseSharedMemory(&SharedMem2);
104 
105 	TEEC_CloseSession(&TeecSession);
106 	TEEC_FinalizeContext(&TeecContext);
107 
108 	return TeecResult;
109 }
110 
111 uint32_t write_keybox_to_secure_storage(uint8_t *received_data, uint32_t len)
112 {
113 	uint32_t key_size;
114 	uint32_t data_size;
115 	TEEC_Result ret;
116 	int rc = 0;
117 
118 	if (memcmp(received_data, WIDEVINE_TAG, 4) == 0) {
119 		/* widevine keybox */
120 		TEEC_UUID widevine_uuid = { 0x1b484ea5, 0x698b, 0x4142,
121 			{ 0x82, 0xb8, 0x3a, 0xcf, 0x16, 0xe9, 0x9e, 0x2a } };
122 
123 		key_size = *(received_data + 4);
124 		data_size = *(received_data + 8);
125 
126 		ret = rk_send_keybox_to_ta((uint8_t *)"widevine_keybox",
127 					   sizeof("widevine_keybox"),
128 					   widevine_uuid,
129 					   received_data + 12,
130 					   key_size,
131 					   received_data + 12 + key_size,
132 					   data_size);
133 		if (ret == TEEC_SUCCESS) {
134 			rc = 0;
135 			printf("write widevine keybox to secure storage success\n");
136 		} else {
137 			rc = -EIO;
138 			printf("write widevine keybox to secure storage fail\n");
139 		}
140 	} else if (memcmp(received_data, ATTESTATION_TAG, 4) == 0) {
141 		/* attestation key */
142 		atap_result ret;
143 
144 		ret = write_attestation_key_to_secure_storage(received_data, len);
145 		if (ret == ATAP_RESULT_OK) {
146 			rc = 0;
147 			printf("write attestation key to secure storage success\n");
148 		} else {
149 			rc = -EIO;
150 			printf("write attestation key to secure storage fail\n");
151 		}
152 	}
153 	/* write all data to secure storage for readback check */
154 	if (!rc) {
155 		uint32_t ret;
156 
157 		ret = write_to_keymaster((uint8_t *)"raw_data",
158 					 sizeof("raw_data"),
159 					 received_data, len);
160 		if (ret == TEEC_SUCCESS)
161 			rc = 0;
162 		else
163 			rc = -EIO;
164 	}
165 	return rc;
166 }
167 
168 uint32_t read_raw_data_from_secure_storage(uint8_t *data, uint32_t data_size)
169 {
170 	uint32_t rc;
171 
172 	rc = read_from_keymaster((uint8_t *)"raw_data", sizeof("raw_data"),
173 				 data, data_size - 8);
174 	if (rc != TEEC_SUCCESS)
175 		return 0;
176 	rc = data_size - 8;
177 
178 	return rc;
179 }
180