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