xref: /rk3399_rockchip-uboot/drivers/ufs/ufs-rockchip-rpmb.c (revision 395c77b5f9b45eba4468a378527c654ac1160fc0)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Rockchip UFS Host Controller driver
4  *
5  * Copyright (C) 2024 Rockchip Electronics Co.Ltd.
6  */
7 
8 #include <command.h>
9 #include <charset.h>
10 #include <common.h>
11 #include <dm.h>
12 #include <log.h>
13 #include <dm/lists.h>
14 #include <dm/device-internal.h>
15 #include <malloc.h>
16 #include <hexdump.h>
17 #include <scsi.h>
18 #include <asm/io.h>
19 #include <asm/dma-mapping.h>
20 #include <linux/bitops.h>
21 #include <linux/delay.h>
22 
23 #include "ufs.h"
24 #include "ufs-rockchip-rpmb.h"
25 #include <u-boot/sha256.h>
26 
27 extern int ufs_send_scsi_cmd(struct ufs_hba *hba, struct scsi_cmd *pccb);
28 
29 #define UFS_OP_SECURITY_PROTOCOL_IN	0xA2
30 #define UFS_OP_SECURITY_PROTOCOL_OUT	0xB5
31 #define UFS_OP_TST_U_RDY		0x00
32 #define UFS_RPMB_KEY_SZ			32
33 #define SHA256_BLOCK_SIZE		64
34 
35 static struct ufs_hba *rpmb_hba;
36 
37 struct lu_info_tbl {
38 	int lu_index;
39 	uint32_t log2blksz;
40 	uint64_t blkcnt;
41 };
42 
43 struct lu_info_tbl rpmb_lu_info = {0};
44 static struct scsi_cmd tempccb;	/* temporary scsi command buffer */
45 
u16_to_bytes(uint16_t u16,uint8_t * bytes)46 static void u16_to_bytes(uint16_t u16, uint8_t *bytes)
47 {
48 	*bytes = (uint8_t) (u16 >> 8);
49 	*(bytes + 1) = (uint8_t) u16;
50 }
51 
bytes_to_u16(uint8_t * bytes,uint16_t * u16)52 static void bytes_to_u16(uint8_t *bytes, uint16_t *u16)
53 {
54 	*u16 = (uint16_t) ((*bytes << 8) + *(bytes + 1));
55 }
56 
bytes_to_u32(uint8_t * bytes,uint32_t * u32)57 static void bytes_to_u32(uint8_t *bytes, uint32_t *u32)
58 {
59 	*u32 = (uint32_t) ((*(bytes) << 24) +
60 			   (*(bytes + 1) << 16) +
61 			   (*(bytes + 2) << 8) + (*(bytes + 3)));
62 }
63 
u32_to_bytes(uint32_t u32,uint8_t * bytes)64 static void u32_to_bytes(uint32_t u32, uint8_t *bytes)
65 {
66 	*bytes = (uint8_t) (u32 >> 24);
67 	*(bytes + 1) = (uint8_t) (u32 >> 16);
68 	*(bytes + 2) = (uint8_t) (u32 >> 8);
69 	*(bytes + 3) = (uint8_t) u32;
70 }
71 
hba_test(struct ufs_hba * hba)72 static int hba_test(struct ufs_hba *hba)
73 {
74 	if (!hba) {
75 		printf("No UFS device!\n");
76 		return -ENODEV;
77 	}
78 
79 	return 0;
80 }
81 
scsi_secproc_in(struct scsi_cmd * pccb,uint32_t lba,uint32_t size)82 static void scsi_secproc_in(struct scsi_cmd *pccb, uint32_t lba, uint32_t size)
83 {
84 	pccb->cmd[0] = UFS_OP_SECURITY_PROTOCOL_IN;	/* 0: opcode */
85 	pccb->cmd[1] = 0xEC;				/* 1: security protocal */
86 	pccb->cmd[2] = 0;				/* 2: specific */
87 	pccb->cmd[3] = 0x1;				/* 3: specific */
88 	pccb->cmd[4] = 0;				/* 4: reserved */
89 	pccb->cmd[5] = 0;				/* 5: reserved */
90 	pccb->cmd[6] = (uint8_t)((size >> 24) & 0xff);	/* 6: MSB, shift 24 */
91 	pccb->cmd[7] = (uint8_t)((size >> 16) & 0xff);	/* 7: MSB, shift 16 */
92 	pccb->cmd[8] = (uint8_t)((size >> 8) & 0xff);	/* 8: LSB, shift 8 */
93 	pccb->cmd[9] = (uint8_t)(size & 0xff);		/* 9: LSB */
94 	pccb->cmd[10] = 0;				/* 10: reserved */
95 	pccb->cmd[11] = 0;				/* 11: control */
96 
97 	pccb->cmdlen = 12;
98 }
99 
scsi_secproc_out(struct scsi_cmd * pccb,uint32_t lba,uint32_t size)100 static void scsi_secproc_out(struct scsi_cmd *pccb, uint32_t lba, uint32_t size)
101 {
102 	pccb->cmd[0] = UFS_OP_SECURITY_PROTOCOL_OUT;	/* 0: opcode */
103 	pccb->cmd[1] = 0xEC;				/* 1: security protocal */
104 	pccb->cmd[2] = 0;				/* 2: specific */
105 	pccb->cmd[3] = 0x1;				/* 3: specific */
106 	pccb->cmd[4] = 0;				/* 4: reserved */
107 	pccb->cmd[5] = 0;				/* 5: reserved */
108 	pccb->cmd[6] = (uint8_t)((size >> 24) & 0xff);	/* 6: MSB, shift 24 */
109 	pccb->cmd[7] = (uint8_t)((size >> 16) & 0xff);	/* 7: MSB, shift 16 */
110 	pccb->cmd[8] = (uint8_t)((size >> 8) & 0xff);	/* 8: LSB, shift 8 */
111 	pccb->cmd[9] = (uint8_t)(size & 0xff);		/* 9: LSB */
112 	pccb->cmd[10] = 0;				/* 10: reserved */
113 	pccb->cmd[11] = 0;				/* 11: control */
114 
115 	pccb->cmdlen = 12;
116 }
117 
scsi_test_unit_ready(struct scsi_cmd * pccb)118 static void scsi_test_unit_ready(struct scsi_cmd *pccb)
119 {
120 	pccb->cmd[0] = UFS_OP_TST_U_RDY;
121 	pccb->cmd[1] = pccb->lun << 5;
122 	pccb->cmd[2] = 0;
123 	pccb->cmd[3] = 0;
124 	pccb->cmd[4] = 0;
125 	pccb->cmd[5] = 0;
126 	pccb->cmdlen = 6;
127 }
128 
rpmb_send_scsi_cmd(struct ufs_hba * hba,uint32_t opcode,int dma_dir,int lun,void * buf_addr,lbaint_t start,lbaint_t blkcnt)129 static int rpmb_send_scsi_cmd(struct ufs_hba *hba, uint32_t opcode, int dma_dir, int lun,
130 			      void *buf_addr, lbaint_t start, lbaint_t blkcnt)
131 {
132 	struct scsi_cmd *pccb = (struct scsi_cmd *)&tempccb;
133 
134 	pccb->lun = lun;
135 	pccb->pdata = buf_addr;
136 	pccb->dma_dir = dma_dir;
137 	pccb->datalen = blkcnt * sizeof(struct rpmb_data_frame);
138 
139 	if (opcode == UFS_OP_SECURITY_PROTOCOL_OUT) {
140 		scsi_secproc_out(pccb, start, pccb->datalen);
141 		pccb->cmdlen = 12;
142 	} else if (opcode == UFS_OP_SECURITY_PROTOCOL_IN) {
143 		scsi_secproc_in(pccb, start, pccb->datalen);
144 		pccb->cmdlen = 12;
145 	} else if (opcode == UFS_OP_TST_U_RDY) {
146 		scsi_test_unit_ready(pccb);
147 	} else {
148 		return -EINVAL;
149 	}
150 
151 	return  ufs_send_scsi_cmd(hba, pccb);
152 }
153 
ufs_rpmb_hmac(unsigned char * key,struct rpmb_data_frame * frames_in,ssize_t blocks_cnt,unsigned char * output)154 static void ufs_rpmb_hmac(unsigned char *key, struct rpmb_data_frame *frames_in, ssize_t blocks_cnt,
155 			  unsigned char *output)
156 {
157 	sha256_context ctx;
158 	int i;
159 	unsigned char k_ipad[SHA256_BLOCK_SIZE];
160 	unsigned char k_opad[SHA256_BLOCK_SIZE];
161 
162 	sha256_starts(&ctx);
163 
164 	/* According to RFC 4634, the HMAC transform looks like:
165 	   SHA(K XOR opad, SHA(K XOR ipad, text))
166 
167 	   where K is an n byte key.
168 	   ipad is the byte 0x36 repeated blocksize times
169 	   opad is the byte 0x5c repeated blocksize times
170 	   and text is the data being protected.
171 	*/
172 
173 	for (i = 0; i < UFS_RPMB_KEY_SZ; i++) {
174 		k_ipad[i] = key[i] ^ 0x36;
175 		k_opad[i] = key[i] ^ 0x5c;
176 	}
177 	/* remaining pad bytes are '\0' XOR'd with ipad and opad values */
178 	for ( ; i < SHA256_BLOCK_SIZE; i++) {
179 		k_ipad[i] = 0x36;
180 		k_opad[i] = 0x5c;
181 	}
182 	sha256_update(&ctx, k_ipad, SHA256_BLOCK_SIZE);
183 
184 	for (i = 0; i < blocks_cnt; i++)
185 		sha256_update(&ctx, frames_in[i].data, RPMB_DATA_HAM_SIZE);
186 
187 	sha256_finish(&ctx, output);
188 
189 	/* Init context for second pass */
190 	sha256_starts(&ctx);
191 
192 	/* start with outer pad */
193 	sha256_update(&ctx, k_opad, SHA256_BLOCK_SIZE);
194 
195 	/* then results of 1st hash */
196 	sha256_update(&ctx, output, UFS_RPMB_KEY_SZ);
197 
198 	/* finish up 2nd pass */
199 	sha256_finish(&ctx, output);
200 }
201 
prepare_rpmb_lu(void)202 int prepare_rpmb_lu(void)
203 {
204 	struct ufs_rpmb_unit_desc_tbl rpmb_unit_desc;
205 	uint64_t block_count = 0;
206 	int ret = 0;
207 
208 	ret = hba_test(rpmb_hba);
209 	if (ret)
210 		return ret;
211 
212 	ret = ufshcd_read_desc_param(rpmb_hba, QUERY_DESC_IDN_UNIT, 0xc4, 0, (u8 *)&rpmb_unit_desc,
213 				     QUERY_DESC_UNIT_DEF_SIZE);
214 	if (ret) {
215 		dev_err(hba->dev, "%s: Failed reading RPMB Desc. err = %d\n", __func__, ret);
216 		return ret;
217 	}
218 
219 	block_count = be64_to_cpu(rpmb_unit_desc.qLogicalBlockCount);
220 	if (block_count) {
221 		rpmb_lu_info.lu_index = 0xc4;
222 		rpmb_lu_info.blkcnt = block_count;
223 		rpmb_lu_info.log2blksz = rpmb_unit_desc.bLogicalBlockSize;
224 		/*
225 		* write key,read counter,write data,
226 		* need this test_unit_ready operation.
227 		*/
228 		ret = rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_TST_U_RDY, DMA_NONE, rpmb_lu_info.lu_index,
229 					 NULL, 0, 0);
230 	}
231 
232 	return ret;
233 }
234 
235 /* @retrun 0 rpmb key unwritten */
is_wr_ufs_rpmb_key(void)236 int is_wr_ufs_rpmb_key(void)
237 {
238 	int ret = 0;
239 	struct rpmb_data_frame *data_frame;
240 	uint16_t msg_type;
241 	uint16_t op_result;
242 	uint8_t nonce[RPMB_NONCE_SIZE] = {
243 		0xa5, 0x5a, 0xff, 0x00, 0xbe, 0xef, 0xbe, 0xef,
244 		0xbe, 0xef, 0xbe, 0xef, 0x00, 0xff, 0x5a, 0xa5
245 	};
246 
247 	ret = hba_test(rpmb_hba);
248 	if (ret)
249 		return ret;
250 
251 	if (rpmb_lu_info.log2blksz == 0) {
252 		ret = prepare_rpmb_lu();
253 		if(0 != ret)
254 			return ret;
255 	}
256 
257 	msg_type = RPMB_READ;
258 	data_frame = memalign(ARCH_DMA_MINALIGN, RPMB_DATA_FRAME_SIZE);
259 	if (!data_frame) {
260 		printf("%s malloc error\n", __func__);
261 		return -1;
262 	}
263 
264 	memset(data_frame, 0, RPMB_DATA_FRAME_SIZE);
265 	u16_to_bytes(msg_type, data_frame->msg_type);
266 	memcpy(data_frame->nonce, nonce, RPMB_NONCE_SIZE);
267 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_OUT, DMA_TO_DEVICE,
268 		 	   rpmb_lu_info.lu_index, (void*)data_frame, 0, 1);
269 
270 
271 	memset(data_frame, 0, RPMB_DATA_FRAME_SIZE);
272 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_IN, DMA_FROM_DEVICE,
273 			   rpmb_lu_info.lu_index, (void*)data_frame, 0, 1);
274 
275 	/* result check */
276 	bytes_to_u16(data_frame->op_result, &op_result);
277 	bytes_to_u16(data_frame->msg_type, &msg_type);
278 	if (op_result == RPMB_RES_NO_AUTH_KEY) {
279 		printf("%s rpmb key not write\n", __func__);
280 		ret = 0;
281 	} else {
282 		printf("%s rpmb key has been written\n", __func__);
283 		ret = -1;
284 	}
285 	free(data_frame);
286 
287 	return ret;
288 }
289 
ufs_rpmb_read_writecount(void)290 uint32_t ufs_rpmb_read_writecount(void)
291 {
292 	struct rpmb_data_frame *data_frame;
293 	uint16_t msg_type;
294 	uint16_t op_result;
295 	uint32_t writecount;
296 	uint8_t nonce[RPMB_NONCE_SIZE] = {
297 		0xa5, 0x5a, 0xff, 0x00, 0xbe, 0xef, 0xbe, 0xef,
298 		0xbe, 0xef, 0xbe, 0xef, 0x00, 0xff, 0x5a,0xa5
299 	};
300 	int ret = 0;
301 
302 	ret = hba_test(rpmb_hba);
303 	if (ret)
304 		return ret;
305 
306 	if (rpmb_lu_info.log2blksz == 0) {
307 		ret = prepare_rpmb_lu();
308 		if (ret != 0) {
309 			printf("prepare rpmb unit failed!\n");
310 			return ret;
311 		}
312 	}
313 
314 	msg_type = RPMB_READ_CNT;
315 	data_frame = memalign(ARCH_DMA_MINALIGN, RPMB_DATA_FRAME_SIZE);
316 	memset(data_frame, 0, RPMB_DATA_FRAME_SIZE);
317 	u16_to_bytes(msg_type, data_frame->msg_type);
318 	memcpy(data_frame->nonce, nonce, RPMB_NONCE_SIZE);
319 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_OUT, DMA_TO_DEVICE,
320 			   rpmb_lu_info.lu_index, (void*)data_frame, 0, 1);
321 
322 	memset(data_frame, 0, RPMB_DATA_FRAME_SIZE);
323 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_IN, DMA_FROM_DEVICE,
324 			   rpmb_lu_info.lu_index, (void*)data_frame, 0, 1);
325 
326 	/* result check */
327 	bytes_to_u16(data_frame->op_result, &op_result);
328 	bytes_to_u16(data_frame->msg_type, &msg_type);
329 	if ((op_result == RPMB_RESULT_OK) &&
330 	    (msg_type == RPMB_RESP_WRITE_COUNTER_VAL_READ)) {
331 		bytes_to_u32(data_frame->write_counter, &writecount);
332 		printf("read write count successed\n");
333 		free(data_frame);
334 		return writecount;
335 	}
336 	else
337 		printf(" read write count:0x%x ,msg_type:0x%x\n",
338 		       op_result,msg_type);
339 	free(data_frame);
340 
341 	return 1;
342 }
343 
344 /*
345  * blk_data: for save read data;
346  * blk_index: the block index for read;
347  * block_count: the read count;
348  * success return 0;
349  */
ufs_rpmb_blk_read(char * blk_data,uint8_t * key,uint16_t blk_index,uint16_t block_count)350 int ufs_rpmb_blk_read(char *blk_data, uint8_t *key, uint16_t blk_index, uint16_t block_count)
351 {
352 	struct rpmb_data_frame *data_frame;
353 	struct rpmb_data_frame *resp_buf;
354 	uint16_t msg_type;
355 	uint16_t op_result;
356 	uint8_t nonce[RPMB_NONCE_SIZE] = {
357 		0xa5, 0x5a, 0xff, 0x00, 0xbe, 0xef, 0xbe, 0xef,
358 		0xbe, 0xef, 0xbe, 0xef, 0x00, 0xef, 0x5a,0xa5
359 	};
360 	int ret = 0;
361 
362 	ret = hba_test(rpmb_hba);
363 	if (ret)
364 		return ret;
365 
366 	if (rpmb_lu_info.log2blksz == 0) {
367 		ret = prepare_rpmb_lu();
368 		if (ret != 0)
369 		return ret;
370 	}
371 
372 	if (!blk_data) {
373 		printf("rpmb_blk_read null \n");
374 		return 0;
375 	}
376 
377 	msg_type = RPMB_READ;
378 	data_frame = memalign(ARCH_DMA_MINALIGN, RPMB_DATA_FRAME_SIZE);
379 	memset(data_frame, 0, RPMB_DATA_FRAME_SIZE);
380 	u16_to_bytes(msg_type, data_frame->msg_type);
381 	u16_to_bytes(blk_index, data_frame->address);
382 	u16_to_bytes(block_count, data_frame->block_count);
383 	memcpy(data_frame->nonce, nonce, RPMB_NONCE_SIZE);
384 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_OUT, DMA_TO_DEVICE,
385 			   rpmb_lu_info.lu_index, (void*)data_frame, 0, 1);
386 
387 	resp_buf = memalign(ARCH_DMA_MINALIGN, RPMB_DATA_FRAME_SIZE * block_count);
388 	memset(resp_buf, 0, RPMB_DATA_FRAME_SIZE * block_count);
389 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_IN, DMA_FROM_DEVICE,
390 			   rpmb_lu_info.lu_index, (void*)resp_buf, 0, block_count);
391 
392 	/* result check */
393 	bytes_to_u16((resp_buf + block_count - 1)->op_result, &op_result);
394 	bytes_to_u16((resp_buf + block_count - 1)->msg_type, &msg_type);
395 	if ((op_result == RPMB_RESULT_OK) &&
396             (msg_type == RPMB_RESP_AUTH_DATA_READ)) {
397 		uint8_t i = 0;
398 		for (i = 0; i < block_count; i++)
399 			memcpy((blk_data + i * RPMB_DATA_SIZE),
400 			       ((uint8_t *) (resp_buf + i) +
401 				RPMB_STUFF_DATA_SIZE + RPMB_KEY_MAC_SIZE),
402 			       RPMB_DATA_SIZE);
403 		printf("read  successed\n");
404 		free(resp_buf);
405 		free(data_frame);
406 		return block_count;
407 	} else
408 		printf("read write count:0x%x ,msg_type:0x%x\n", op_result, msg_type);
409 
410 	free(resp_buf);
411 	free(data_frame);
412 
413 	return 0;
414 }
415 
416 /*
417  * write_data: data for write
418  * blk_index: the block will be write to;
419  * success return 0
420  */
421 
422 /* for single data */
ufs_rpmb_blk_write(char * write_data,uint8_t * key,uint16_t blk_index,uint16_t blk_count)423 int ufs_rpmb_blk_write(char *write_data, uint8_t *key, uint16_t blk_index, uint16_t blk_count)
424 {
425 	struct rpmb_data_frame *data_frame;
426 	uint16_t msg_type;
427 	uint16_t op_result;
428 	uint32_t writecount;
429 	int ret = 0, i;
430 
431 
432 	ret = hba_test(rpmb_hba);
433 	if (ret)
434 		return ret;
435 
436 	if(rpmb_lu_info.log2blksz == 0) {
437 		ret = prepare_rpmb_lu();
438 		if (ret != 0)
439 			return ret;
440 	}
441 
442 	if (!write_data)
443 		return 1;
444 
445 	/* TODO: The following codes is multiple block write
446 	 * for(int i=0;i<(strlen(write_data)/RPMB_DATA_SIZE),i++){
447 	 */
448 
449 	msg_type = RPMB_WRITE;
450 	data_frame = memalign(ARCH_DMA_MINALIGN, RPMB_DATA_FRAME_SIZE * blk_count);
451 	memset(data_frame, 0, RPMB_DATA_FRAME_SIZE * blk_count);
452 	writecount = ufs_rpmb_read_writecount();
453 
454 	for (i = 0; i < blk_count; i++) {
455 		u16_to_bytes(msg_type, data_frame[i].msg_type);
456 		u16_to_bytes(blk_index, data_frame[i].address);
457 		u16_to_bytes(blk_count, data_frame[i].block_count);
458 		u32_to_bytes(writecount, data_frame[i].write_counter);
459 		memcpy(data_frame[i].data, write_data, RPMB_DATA_SIZE);
460 		write_data += RPMB_DATA_FRAME_SIZE;
461 	}
462 
463 	ufs_rpmb_hmac(key, data_frame, blk_count, data_frame[blk_count - 1].key_mac);
464 
465 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_OUT, DMA_TO_DEVICE,
466 			   rpmb_lu_info.lu_index, (void*)data_frame, 0, blk_count);
467 
468 	/* for read result req */
469 	memset(data_frame, 0, RPMB_DATA_FRAME_SIZE);
470 	msg_type = RPMB_READ_RESP;
471 	u16_to_bytes(msg_type, data_frame->msg_type);
472 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_OUT, DMA_TO_DEVICE,
473 			   rpmb_lu_info.lu_index, (void*)data_frame, 0, 1);
474 
475 	memset(data_frame, 0, RPMB_DATA_FRAME_SIZE);
476 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_IN, DMA_FROM_DEVICE,
477 			   rpmb_lu_info.lu_index, (void*)data_frame, 0, 1);
478 
479 	/* result check */
480 	bytes_to_u16(data_frame->op_result, &op_result);
481 	bytes_to_u16(data_frame->msg_type, &msg_type);
482 	if ((op_result == RPMB_RESULT_OK) && (msg_type == RPMB_RESP_AUTH_DATA_WRITE)) {
483 		printf(" data  write successed\n");
484 		free(data_frame);
485 		return blk_count;
486 	} else {
487 		printf(" data write fail op_result:0x%x ,msg_type:0x%x\n", op_result, msg_type);
488 	}
489 
490 	free(data_frame);
491 
492 	return 0;
493 }
494 
495 /*
496  * key: the key will write must 32 len;
497  * len :must be 32;
498  * reutrn 0 success
499  */
ufs_rpmb_write_key(uint8_t * key,uint8_t len)500 int ufs_rpmb_write_key(uint8_t * key, uint8_t len)
501 {
502 	struct rpmb_data_frame *data_frame = NULL;
503 	uint16_t msg_type;
504 	uint16_t op_result;
505 	int ret = 0;
506 	lbaint_t transfer_blkcnt = 0;
507 
508 	ret = hba_test(rpmb_hba);
509 	if (ret)
510 		return ret;
511 
512 	if (rpmb_lu_info.log2blksz == 0) {
513 		ret = prepare_rpmb_lu();
514 		if (ret != 0)
515 			return ret;
516 	}
517 
518 	/* rpmb_lu_info.log2blksz=0x08,256B */
519 	transfer_blkcnt = RPMB_DATA_FRAME_SIZE >> (rpmb_lu_info.log2blksz);
520 
521 	if (!key || len != RPMB_KEY_MAC_SIZE)
522 		return 1;
523 
524 	/* for write rpmb key req */
525 	msg_type = RPMB_WRITE_KEY;
526 	data_frame = memalign(ARCH_DMA_MINALIGN, RPMB_DATA_FRAME_SIZE);
527 	memset(data_frame, 0, RPMB_DATA_FRAME_SIZE);
528 	u16_to_bytes(msg_type, data_frame->msg_type);
529 	memcpy(data_frame->key_mac, key, RPMB_KEY_MAC_SIZE);
530 
531 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_OUT, DMA_TO_DEVICE,
532 			   rpmb_lu_info.lu_index, (void*)data_frame, 0, transfer_blkcnt);
533 
534 	/* for read result req */
535 	memset(data_frame, 0, RPMB_DATA_FRAME_SIZE);
536 	msg_type = RPMB_READ_RESP;
537 	u16_to_bytes(msg_type, data_frame->msg_type);
538 
539 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_OUT, DMA_TO_DEVICE,
540 			   rpmb_lu_info.lu_index, (void*)data_frame, 0, transfer_blkcnt);
541 
542 	memset(data_frame, 0xcc, RPMB_DATA_FRAME_SIZE);
543 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_IN, DMA_FROM_DEVICE,
544 			   rpmb_lu_info.lu_index, (void*)data_frame, 0, transfer_blkcnt);
545 
546 	/* result check */
547 	bytes_to_u16(data_frame->op_result, &op_result);
548 	bytes_to_u16(data_frame->msg_type, &msg_type);
549 	if ((op_result == RPMB_RESULT_OK) && (msg_type == RPMB_RESP_AUTH_KEY_PROGRAM)) {
550 		printf(" key write successed\n");
551 		free(data_frame);
552 		return 0;
553 	} else {
554 		printf(" key write fail op_result:0x%x ,msg_type:0x%x\n", op_result, msg_type);
555 	}
556 
557 	free(data_frame);
558 
559 	return 1;
560 }
561 
ufs_read_desc(struct ufs_hba * hba,enum desc_idn desc_id,int desc_index,u8 * buf,u32 size)562 static int ufs_read_desc(struct ufs_hba *hba, enum desc_idn desc_id,
563 		  int desc_index, u8 *buf, u32 size)
564 {
565 	return ufshcd_read_desc_param(hba, desc_id, desc_index, 0, buf, size);
566 }
567 
ufs_read_device_desc(u8 * buf,u32 size)568 int ufs_read_device_desc(u8 *buf, u32 size)
569 {
570 	int ret = 0;
571 
572 	ret = hba_test(rpmb_hba);
573 	if (ret)
574 		return ret;
575 
576 	return ufs_read_desc(rpmb_hba, QUERY_DESC_IDN_DEVICE, 0, buf, size);
577 }
578 
ufs_read_string_desc(int desc_index,u8 * buf,u32 size)579 int ufs_read_string_desc(int desc_index, u8 *buf, u32 size)
580 {
581 	int ret = 0;
582 
583 	ret = hba_test(rpmb_hba);
584 	if (ret)
585 		return ret;
586 
587 	return ufs_read_desc(rpmb_hba, QUERY_DESC_IDN_STRING, desc_index, buf, size);
588 }
589 
ufs_read_geo_desc(u8 * buf,u32 size)590 int ufs_read_geo_desc(u8 *buf, u32 size)
591 {
592 	int ret = 0;
593 
594 	ret = hba_test(rpmb_hba);
595 	if (ret)
596 		return ret;
597 
598 	return ufs_read_desc(rpmb_hba, QUERY_DESC_IDN_GEOMETRY, 0, buf, size);
599 }
600 
ufs_read_rpmb_unit_desc(u8 * buf,u32 size)601 int ufs_read_rpmb_unit_desc(u8 *buf, u32 size)
602 {
603 	int ret = 0;
604 
605 	ret = hba_test(rpmb_hba);
606 	if (ret)
607 		return ret;
608 
609 	return ufs_read_desc(rpmb_hba, QUERY_DESC_IDN_UNIT, 0xc4, buf, size);
610 }
611 
do_rpmb_op(struct rpmb_data_frame * frame_in,uint32_t in_cnt,struct rpmb_data_frame * frame_out,uint32_t out_cnt)612 int do_rpmb_op(struct rpmb_data_frame *frame_in, uint32_t in_cnt,
613 	       struct rpmb_data_frame *frame_out, uint32_t out_cnt)
614 {
615 	uint16_t msg_type = 0;
616 	int ret = 0;
617 
618 	ret = hba_test(rpmb_hba);
619 	if (ret)
620 		return ret;
621 
622 	if (rpmb_lu_info.log2blksz == 0) {
623 		ret = prepare_rpmb_lu();
624 		if (ret != 0) {
625 			printf("prepare rpmb unit failed!\n");
626 			return ret;
627 		}
628 	}
629 
630 	if (!frame_in || !frame_out || !in_cnt || !out_cnt) {
631 		printf("Wrong rpmb parameters\n");
632 		return -1;
633 	}
634 
635 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_OUT, DMA_TO_DEVICE,
636 			   rpmb_lu_info.lu_index, (void*)frame_in, 0, in_cnt);
637 
638 	bytes_to_u16(frame_in->msg_type, &msg_type);
639 	if ((msg_type == RPMB_WRITE) || (msg_type == RPMB_WRITE_KEY) ||
640 	    (msg_type == RPMB_SEC_CONF_WRITE)) {
641 		memset(&frame_in[0], 0, sizeof(frame_in[0]));
642 		msg_type = RPMB_READ_RESP;
643 		u16_to_bytes(msg_type, frame_in->msg_type);
644 
645 		rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_OUT, DMA_TO_DEVICE,
646 				   rpmb_lu_info.lu_index, (void*)frame_in, 0, 1);
647 	}
648 
649 	rpmb_send_scsi_cmd(rpmb_hba, UFS_OP_SECURITY_PROTOCOL_IN, DMA_FROM_DEVICE,
650 			   rpmb_lu_info.lu_index, (void*)frame_out, 0, out_cnt);
651 	return 0;
652 }
653 
ufs_rpmb_init(struct ufs_hba * hba)654 int ufs_rpmb_init(struct ufs_hba *hba)
655 {
656 	rpmb_hba = hba;
657 
658 	return 0;
659 }
660