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 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 52 static void bytes_to_u16(uint8_t *bytes, uint16_t *u16) 53 { 54 *u16 = (uint16_t) ((*bytes << 8) + *(bytes + 1)); 55 } 56 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 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 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 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 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 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 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 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 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 */ 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 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 */ 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 */ 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 */ 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 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 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 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 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 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 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 654 int ufs_rpmb_init(struct ufs_hba *hba) 655 { 656 rpmb_hba = hba; 657 658 return 0; 659 } 660