ufs_aio_rpmb.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include "ufs_aio_cfg.h" // Include ufs_aio_cfg.h for defining MTK_UFS_DRV_PRELOADER
  32. #include "ufs_aio_types.h"
  33. #include "ufs_aio.h"
  34. #include "ufs_aio_hcd.h"
  35. #include "ufs_aio_core.h"
  36. #include "ufs_aio_utils.h"
  37. #include "ufs_aio_error.h"
  38. #include "ufs_aio_rpmb.h"
  39. #if defined(MTK_UFS_DRV_LK)
  40. #include <stdlib.h>
  41. #include <arch/arm/mmu.h>
  42. #include "partition_wp.h"
  43. #include <arch/ops.h> /* arch_clean_invalidate_cache_range() is defined in bootable/bootloader/include/arch/ops.h */
  44. #endif
  45. #if defined(MTK_UFS_DRV_PRELOADER)
  46. #include <hmac.h>
  47. #if CFG_RPMB_KEY_RETRY_IN_PL
  48. extern char g_rpmb_key[];
  49. #endif
  50. #endif
  51. #if defined(MTK_UFS_DRV_DA)
  52. #include "malloc.h"
  53. #include "boot/security_export/rpmb_hmac.h"
  54. #endif
  55. static u8 rpmb_nonce_buf[RPMB_FRM_NONCE_LEN] __attribute__((aligned(UFS_PLATFORM_CACHE_LINE_SIZE)));
  56. static u8 rpmb_frame_buf[RPMB_FRM_DATA_LEN] __attribute__((aligned(UFS_PLATFORM_CACHE_LINE_SIZE)));
  57. void rpmb_req_copy_data_for_hmac(u8 *buf, struct rpmb_data_frame *f)
  58. {
  59. u32 size;
  60. /*
  61. * Copy below members for HMAC calculation
  62. * one by one with specifically assigning
  63. * buf to each member to pass buffer-overrun checker.
  64. *
  65. * u8 data[RPMB_FRM_DATA_LEN];
  66. * u8 nonce[RPMB_FRM_NONCE_LEN];
  67. * u32 wr_cnt;
  68. * u16 addr;
  69. * u16 blk_cnt;
  70. * u16 result;
  71. * u16 req_resp;
  72. */
  73. memcpy(buf, f->data, RPMB_FRM_DATA_LEN);
  74. buf += RPMB_FRM_DATA_LEN;
  75. size = sizeof(f->nonce);
  76. memcpy(buf, f->nonce, size);
  77. buf += size;
  78. size = sizeof(f->wr_cnt);
  79. memcpy(buf, &f->wr_cnt, size);
  80. buf += size;
  81. size = sizeof(f->addr);
  82. memcpy(buf, &f->addr, size);
  83. buf += size;
  84. size = sizeof(f->blk_cnt);
  85. memcpy(buf, &f->blk_cnt, size);
  86. buf += size;
  87. size = sizeof(f->result);
  88. memcpy(buf, &f->result, size);
  89. buf += size;
  90. size = sizeof(f->req_resp);
  91. memcpy(buf, &f->req_resp, size);
  92. buf += size;
  93. }
  94. #if defined(MTK_UFS_DRV_LK)
  95. extern int32_t rpmb_hmac(uint32_t pattern, uint32_t size);
  96. extern int32_t rpmb_init(void);
  97. u32 *shared_msg_addr1 = (u32 *)(LK_SHARED_MEM_ADDR + 0x40); /* fixed and pre-allocated in lk */
  98. u32 *shared_hmac_addr1 = (u32 *)(LK_SHARED_MEM_ADDR+ 0xCE0); /* fixed and pre-allocated in lk */
  99. int init_rpmb_sharemem()
  100. {
  101. uint32_t start, size;
  102. int ret = 0;
  103. /* map shared memory for rpmb */
  104. start = ROUNDDOWN((uint32_t)LK_SHARED_MEM_ADDR, PAGE_SIZE);
  105. size = PAGE_SIZE;
  106. arch_mmu_map((uint64_t)start, (uint32_t)start,
  107. MMU_MEMORY_TYPE_NORMAL_WRITE_BACK | MMU_MEMORY_AP_P_RW_U_NA, ROUNDUP(size, PAGE_SIZE));
  108. ret = rpmb_init();
  109. if (ret) {
  110. UFS_DBG_LOGE("[%s]: RPMB rpmb_init error, ret = %d \n", __func__, ret);
  111. return ret;
  112. }
  113. return 0;
  114. }
  115. static int rpmb_get_mac(struct rpmb_data_frame *pfrm)
  116. {
  117. int ret = 0;
  118. if (pfrm == NULL) {
  119. UFS_DBG_LOGE("[%s]: RPMB pfrm pointer NULL\n", __func__);
  120. return -1;
  121. }
  122. rpmb_req_copy_data_for_hmac((u8*)shared_msg_addr1, pfrm);
  123. arch_clean_invalidate_cache_range((addr_t) LK_SHARED_MEM_ADDR, 4096);
  124. ret = rpmb_hmac(0, 284);
  125. if (ret) {
  126. UFS_DBG_LOGE("[%s]: RPMB rpmb_hmac error, ret = %d \n", __func__, ret);
  127. return ret;
  128. }
  129. return 0;
  130. }
  131. #endif //#if defined(MTK_UFS_DRV_LK)
  132. static void cmd_scsi_security_protocol_out(struct ufs_aio_scsi_cmd *cmd, u32 tag, u32 blk_cnt, u8 protocol, u32 protocol_specific)
  133. {
  134. if (cmd == NULL) {
  135. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  136. return;
  137. }
  138. memset(cmd->cmd_data, 0, MAX_CDB_SIZE);
  139. cmd->lun = WLUN_RPMB;
  140. cmd->tag = tag;
  141. cmd->dir = DMA_TO_DEVICE;
  142. cmd->exp_len = blk_cnt << 9; //block size:512
  143. cmd->attr = ATTR_SIMPLE;
  144. cmd->cmd_len = 12;
  145. cmd->cmd_data[0] = SECURITY_PROTOCOL_OUT; //opcode
  146. cmd->cmd_data[1] = protocol; //security protocol
  147. cmd->cmd_data[2] = (protocol_specific >> 8) & 0xFF; //security protocol specific
  148. cmd->cmd_data[3] = protocol_specific & 0xFF; //security protocol specific
  149. cmd->cmd_data[4] = 0x0; // INC_512 = 0
  150. cmd->cmd_data[5] = 0x0; //Reserved
  151. cmd->cmd_data[6] = ((blk_cnt << 9) >> 24) & 0xFF; //Reserved
  152. cmd->cmd_data[7] = ((blk_cnt << 9) >> 16) & 0xFF; //Reserved
  153. cmd->cmd_data[8] = ((blk_cnt << 9) >> 8) & 0xFF; //Reserved
  154. cmd->cmd_data[9] = 0x0; //(blk_cnt << 9) & 0xFF; actually = 0 //Reserved
  155. cmd->cmd_data[10] = 0x0; //Reserved
  156. cmd->cmd_data[11] = 0x0; //control = 0
  157. }
  158. static void ufshcd_authen_key_prog_req_prepare(struct ufs_aio_scsi_cmd *cmd,
  159. const char *authenKey, unsigned int key_sz)
  160. {
  161. struct rpmb_data_frame *pfrm = NULL;
  162. if (cmd == NULL) {
  163. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  164. return;
  165. }
  166. if (authenKey == NULL) {
  167. UFS_DBG_LOGE("[%s]: RPMB authenKey pointer NULL\n", __func__);
  168. return;
  169. }
  170. pfrm = cmd->data_buf;
  171. if (pfrm == NULL) {
  172. UFS_DBG_LOGE("[%s]: RPMB pfrm pointer NULL\n", __func__);
  173. return;
  174. }
  175. memset(pfrm, 0, sizeof(struct rpmb_data_frame));
  176. memcpy(pfrm->key_MAC, authenKey, key_sz);
  177. pfrm->req_resp = cpu_to_be16(RPMB_REQ_AUTHEN_KEY_PRG);
  178. }
  179. static void ufshcd_authen_result_read_req_prepare(struct ufs_aio_scsi_cmd *cmd)
  180. {
  181. struct rpmb_data_frame *pfrm = NULL;
  182. if (cmd == NULL) {
  183. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  184. return;
  185. }
  186. pfrm = cmd->data_buf;
  187. if (pfrm == NULL) {
  188. UFS_DBG_LOGE("[%s]: RPMB pfrm pointer NULL\n", __func__);
  189. return;
  190. }
  191. memset(pfrm, 0, sizeof(struct rpmb_data_frame));
  192. pfrm->req_resp = cpu_to_be16(RPMB_REQ_RESULT_RD);
  193. }
  194. static void cmd_scsi_security_protocol_in(struct ufs_aio_scsi_cmd *cmd, u32 tag, u32 blk_cnt, u8 protocol, u32 protocol_specific)
  195. {
  196. if (cmd == NULL) {
  197. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  198. return;
  199. }
  200. memset(cmd->cmd_data, 0, MAX_CDB_SIZE);
  201. cmd->lun = WLUN_RPMB;
  202. cmd->tag = tag;
  203. cmd->dir = DMA_FROM_DEVICE;
  204. cmd->exp_len = blk_cnt * 512;
  205. cmd->attr = ATTR_SIMPLE;
  206. cmd->cmd_len = 12;
  207. cmd->cmd_data[0] = SECURITY_PROTOCOL_IN; //opcode
  208. cmd->cmd_data[1] = protocol; //security protocol
  209. cmd->cmd_data[2] = (protocol_specific >> 8) & 0xFF; //security protocol specific
  210. cmd->cmd_data[3] = protocol_specific & 0xFF; //security protocol specific
  211. cmd->cmd_data[4] = 0x0; // INC_512 = 0
  212. cmd->cmd_data[5] = 0x0; //Reserved
  213. cmd->cmd_data[6] = ((blk_cnt << 9) >> 24) & 0xFF; //Reserved
  214. cmd->cmd_data[7] = ((blk_cnt << 9) >> 16) & 0xFF; //Reserved
  215. cmd->cmd_data[8] = ((blk_cnt << 9) >> 8) & 0xFF; //Reserved
  216. cmd->cmd_data[9] = 0x0; //(blk_cnt << 9) & 0xFF; actually = 0 //Reserved
  217. cmd->cmd_data[10] = 0x0; //Reserved
  218. cmd->cmd_data[11] = 0x0; //control = 0
  219. }
  220. /*Response Frame check for Authenkey program request and write data request*/
  221. static int ufshcd_authen_result_read_rsp_check(u32 host_id, struct ufs_aio_scsi_cmd *cmd,
  222. u16 addr, u32 wcnt,
  223. enum enum_rpmb_msg type)
  224. {
  225. struct rpmb_data_frame *rpmb_frame = NULL;
  226. unsigned int idx = 0;
  227. if (cmd == NULL) {
  228. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  229. return -1;
  230. }
  231. rpmb_frame = cmd->data_buf;
  232. if (rpmb_frame == NULL) {
  233. UFS_DBG_LOGE("[%s]: RPMB rpmb_frame pointer NULL\n", __func__);
  234. return -1;
  235. }
  236. if ( rpmb_frame->req_resp != cpu_to_be16(type)) {
  237. /* Check response type */
  238. UFS_DBG_LOGE("[%s]: RPMB Fail in checking response type : 0x%x\r\n", __func__ , cpu_to_be16(rpmb_frame->req_resp));
  239. return -1;
  240. } else if ((idx = (cpu_to_be16(rpmb_frame->result) & 0x7F))) {
  241. /* Check response type */
  242. UFS_DBG_LOGE("[%s]: RPMB Fail in checking result : %s \r\n", __func__ , rpmb_oper_result[idx]);
  243. return -1;
  244. }
  245. return 0;
  246. }
  247. unsigned char ufs_rpmb_buf[sizeof(struct rpmb_data_frame)]; /* for RPMB only */
  248. int rpmb_authen_key_program(u32 host_id, const char *authen_key, u32 Key_sz)
  249. {
  250. struct ufs_aio_scsi_cmd cmd;
  251. struct ufs_hba *hba;
  252. int ret = 0;
  253. int tag;
  254. if (authen_key == NULL) {
  255. UFS_DBG_LOGE("[%s]: RPMB authen_key pointer NULL\n", __func__);
  256. return -1;
  257. }
  258. cmd.data_buf = ufs_rpmb_buf;
  259. hba = ufs_aio_get_host(host_id);
  260. if (!ufshcd_get_free_tag(hba, &tag))
  261. return -1;
  262. /*Step1. Authen key Data */
  263. cmd_scsi_security_protocol_out(&cmd, tag, 1,
  264. UFS_SECURITY_PROTOCOL,
  265. RPMB_PROTOCOL_ID);
  266. ufshcd_authen_key_prog_req_prepare(&cmd, authen_key,
  267. Key_sz);
  268. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  269. UFS_DBG_LOGE("[%s]: RPMB Fail in Sending authen key program request, ret = %d \n", __func__, ret);
  270. goto exit;
  271. }
  272. /*Step2. Result Register Read Request*/
  273. cmd_scsi_security_protocol_out(&cmd, tag, 1,
  274. UFS_SECURITY_PROTOCOL,
  275. RPMB_PROTOCOL_ID);
  276. ufshcd_authen_result_read_req_prepare(&cmd);
  277. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  278. UFS_DBG_LOGE("[%s]: RPMB Fail in Sending result register read request, ret = %d \n", __func__, ret);
  279. goto exit;
  280. }
  281. /*Step3. Resp for Resutl Register Request*/
  282. cmd_scsi_security_protocol_in(&cmd, tag, 1,
  283. UFS_SECURITY_PROTOCOL,
  284. RPMB_PROTOCOL_ID);
  285. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  286. UFS_DBG_LOGE("[%s]: RPMB Fail in Sending request get result register response, ret = %d \n", __func__, ret);
  287. goto exit;
  288. }
  289. /*Step4. Resp frame check*/
  290. if ((ret = ufshcd_authen_result_read_rsp_check(host_id, &cmd, 0, 0,
  291. RPMB_RSP_AUTHEN_KEY_PRG))) {
  292. UFS_DBG_LOGE("[%s]: RPMB Authentication Key Program Fail, ret = %d \n", __func__, ret);
  293. goto exit;
  294. }
  295. exit:
  296. ufshcd_put_tag(hba, tag);
  297. return ret;
  298. }
  299. ////////////////////////////////////////////////////////////////////////////
  300. #define RPMB_MAC_DUMP_DEBUG 0
  301. #if RPMB_MAC_DUMP_DEBUG
  302. static inline void ufshcd_rpmb_mac_dump(const u8 *mac, u32 mac_len)
  303. {
  304. u32 i = 0;
  305. UFS_DBG_LOGE("mac dump:\n");
  306. if (mac == NULL) {
  307. UFS_DBG_LOGE("[%s]: RPMB mac pointer NULL\n", __func__);
  308. return;
  309. }
  310. for (i = 0; i < mac_len; i++) {
  311. UFS_DBG_LOGE("[%d]:0x%x\n", i, *(mac+i));
  312. }
  313. UFS_DBG_LOGE("\n");
  314. }
  315. #else
  316. static inline void ufshcd_rpmb_mac_dump(const u8 *mac, u32 mac_len)
  317. {
  318. }
  319. #endif
  320. static int ufshcd_authen_wcnt_read_req_prepare(struct ufs_aio_scsi_cmd *cmd,
  321. u8 *nonce, unsigned int nonce_len)
  322. {
  323. struct rpmb_data_frame *pfrm = NULL;
  324. // struct ufs_hba *hba;
  325. unsigned int i = 0;
  326. int ret = 0;
  327. // hba = ufs_aio_get_host(host_id);
  328. if (cmd == NULL) {
  329. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  330. return -1;
  331. }
  332. if (nonce ==NULL) {
  333. UFS_DBG_LOGE("[%s]: RPMB nonce pointer NULL\n", __func__);
  334. return -1;
  335. }
  336. pfrm = cmd->data_buf;
  337. if (pfrm == NULL) {
  338. UFS_DBG_LOGE("[%s]: RPMB pfrm pointer NULL\n", __func__);
  339. return -1;
  340. }
  341. if (nonce_len > RPMB_FRM_NONCE_LEN) {
  342. UFS_DBG_LOGE(
  343. "[%s]: RPMB Fail Nonce data length larger than max allow len(%d)", __func__ ,
  344. RPMB_FRM_NONCE_LEN);
  345. return -1;
  346. }
  347. memset(pfrm, 0, sizeof(struct rpmb_data_frame));
  348. /* Prepare the max 16 bytes nonce */
  349. for (i = 0; i < nonce_len; i++)
  350. nonce[i] = (u8)i & 0xFF; /* ToDO: get random nonce */
  351. memcpy(pfrm->nonce, nonce, nonce_len);
  352. pfrm->req_resp = cpu_to_be16(RPMB_REQ_READ_WR_CNT);
  353. return ret;
  354. }
  355. static int ufshcd_authensss_wcnt_read_rsp_check(u32 host_id,
  356. struct ufs_aio_scsi_cmd *cmd, u32 *wcnt,
  357. u8 *nonce, unsigned int nonce_len,
  358. enum enum_rpmb_msg type)
  359. {
  360. struct rpmb_data_frame *rpmb_frame = NULL;
  361. unsigned int idx = 0;
  362. int ret = 0;
  363. #if (CFG_RPMB_KEY_RETRY_IN_PL || defined(MTK_UFS_DRV_DA))
  364. u8 rpmb_hmac_data[HMAC_TEXT_LEN] = {0};
  365. u8 rpmb_hmac_derived[RPMB_FRM_KEY_MAC_LEN] = {0};
  366. #endif
  367. if (cmd == NULL) {
  368. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  369. return -1;
  370. }
  371. if (wcnt == NULL) {
  372. UFS_DBG_LOGE("[%s]: RPMB wcnt pointer NULL\n", __func__);
  373. return -1;
  374. }
  375. if (nonce == NULL) {
  376. UFS_DBG_LOGE("[%s]: RPMB nonce pointer NULL\n", __func__);
  377. return -1;
  378. }
  379. rpmb_frame = cmd->data_buf;
  380. if (rpmb_frame == NULL) {
  381. UFS_DBG_LOGE("[%s]: RPMB rpmb_frame pointer NULL\n", __func__);
  382. return -1;
  383. }
  384. if ( rpmb_frame->req_resp != cpu_to_be16(type)) {
  385. /* Check response type */
  386. UFS_DBG_LOGE("[%s]: RPMB Fail in checking response type : 0x%x\r\n", __func__, cpu_to_be16(rpmb_frame->req_resp));
  387. return -1;
  388. } else if ((idx = (cpu_to_be16(rpmb_frame->result) & 0x7F))) {
  389. /* Check response type */
  390. UFS_DBG_LOGE("[%s]: RPMB Fail in checking result : %s \r\n", __func__, rpmb_oper_result[idx]);
  391. return -1;
  392. } else if (cpu_to_be16(rpmb_frame->result) & 0x80) {
  393. /*Check Write Counter*/
  394. UFS_DBG_LOGE("[%s]: RPMB write counter is expired\r\n", __func__);
  395. }
  396. if ( memcmp(rpmb_frame->nonce, nonce, nonce_len) ) {
  397. /*for other response type noce will be "0"*/
  398. UFS_DBG_LOGE("[%s]: RPMB Fail in checking nonce\r\n", __func__);
  399. return -1;
  400. }
  401. #if defined(MTK_UFS_DRV_LK)
  402. // Then check MAC
  403. ret = rpmb_get_mac(rpmb_frame);
  404. if (ret) {
  405. UFS_DBG_LOGE("[%s]: RPMB ufshcd_authensss_wcnt_read_rsp_check rpmb_get_mac fail\r\n", __func__);
  406. return -1;
  407. }
  408. if (memcmp(rpmb_frame->key_MAC, shared_hmac_addr1, RPMB_FRM_KEY_MAC_LEN)) {
  409. UFS_DBG_LOGE("[%s]: RPMB Fail in Mac Check!\n", __func__);
  410. UFS_DBG_LOGE("Device Return ");
  411. ufshcd_rpmb_mac_dump((const u8*)rpmb_frame->key_MAC, RPMB_FRM_KEY_MAC_LEN);
  412. UFS_DBG_LOGE("Host Recalc");
  413. ufshcd_rpmb_mac_dump((const u8*)shared_hmac_addr1, RPMB_FRM_KEY_MAC_LEN);
  414. return -1;
  415. }
  416. #endif
  417. #if CFG_RPMB_KEY_RETRY_IN_PL
  418. /* copy rpmb_frame contents for hmac one by one to avoid coverity issue */
  419. rpmb_req_copy_data_for_hmac(rpmb_hmac_data, rpmb_frame);
  420. ret = hmac_sha256(g_rpmb_key, 32, rpmb_hmac_data, HMAC_TEXT_LEN, rpmb_hmac_derived);
  421. if (ret) {
  422. UFS_DBG_LOGE("%s, rpmb_hmac error.\n", __func__);
  423. return -1;
  424. }
  425. if (memcmp(rpmb_frame->key_MAC, rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN)) {
  426. UFS_DBG_LOGE("%s, compare hmac error!!\n", __func__);
  427. return -1;
  428. }
  429. #endif //CFG_RPMB_KEY_RETRY_IN_PL
  430. #if defined(MTK_UFS_DRV_DA)
  431. rpmb_req_copy_data_for_hmac(rpmb_hmac_data, rpmb_frame);
  432. ret = rpmb_hmac(rpmb_hmac_data, HMAC_TEXT_LEN, rpmb_hmac_derived);
  433. if (ret) {
  434. UFS_DBG_LOGE("[%s]: RPMB ufshcd_authensss_wcnt_read_rsp_check rpmb_get_mac fail\r\n", __func__);
  435. return -1;
  436. }
  437. if (memcmp(rpmb_frame->key_MAC, rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN)) {
  438. UFS_DBG_LOGE("[%s]: RPMB Fail in Mac Check!\n", __func__);
  439. UFS_DBG_LOGE("Device Return ");
  440. ufshcd_rpmb_mac_dump((const u8*)rpmb_frame->key_MAC, RPMB_FRM_KEY_MAC_LEN);
  441. UFS_DBG_LOGE("Host Recalc");
  442. ufshcd_rpmb_mac_dump((const u8*)rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN);
  443. return -1;
  444. }
  445. #endif
  446. // Then Return WCNT
  447. *wcnt = cpu_to_be32(rpmb_frame->wr_cnt);
  448. return 0;
  449. }
  450. int rpmb_authen_read_counter(u32 host_id, u8 *nonce_buf, u32 nonce_len,
  451. u32 *wr_cnt)
  452. {
  453. struct ufs_aio_scsi_cmd cmd;
  454. struct ufs_hba *hba;
  455. int ret = 0;
  456. int tag;
  457. if (nonce_buf == NULL) {
  458. UFS_DBG_LOGE("[%s]: RPMB nonce_buf pointer NULL\n", __func__);
  459. return -1;
  460. }
  461. if (wr_cnt == NULL) {
  462. UFS_DBG_LOGE("[%s]: RPMB wr_cnt pointer NULL\n", __func__);
  463. return -1;
  464. }
  465. cmd.data_buf = ufs_rpmb_buf;
  466. hba = ufs_aio_get_host(host_id);
  467. if (!ufshcd_get_free_tag(hba, &tag))
  468. return -1;
  469. /*Step1 write counter read request */
  470. cmd_scsi_security_protocol_out(&cmd, tag, 1,
  471. UFS_SECURITY_PROTOCOL,
  472. RPMB_PROTOCOL_ID);
  473. ufshcd_authen_wcnt_read_req_prepare(&cmd,
  474. nonce_buf, nonce_len);
  475. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  476. UFS_DBG_LOGE("[%s]: RPMB Fail in Sending Write counter read request, ret = %d \n", __func__, ret);
  477. goto exit;
  478. }
  479. /*Step2. Resp for write counter read Request*/
  480. cmd_scsi_security_protocol_in(&cmd, tag, 1, UFS_SECURITY_PROTOCOL, RPMB_PROTOCOL_ID);
  481. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  482. UFS_DBG_LOGE("[%s]: RPMB Fail in Sending request get result register response, ret = %d \n", __func__, ret);
  483. goto exit;
  484. }
  485. /*Step3. Response frame check*/
  486. if ((ret = ufshcd_authensss_wcnt_read_rsp_check(host_id, &cmd, wr_cnt,
  487. nonce_buf, nonce_len,
  488. RPMB_RSP_READ_WR_CNT))) {
  489. UFS_DBG_LOGE("[%s]: RPMB WriteCounter Read Resp Check Fail, ret = %d \n", __func__, ret);
  490. }
  491. exit:
  492. ufshcd_put_tag(hba, tag);
  493. return ret;
  494. }
  495. int ufs_rpmb_authen_key_program(const char *authen_key, int *rpmb_result)
  496. {
  497. int ret = 0;
  498. u32 host_id = 0;
  499. u8 *nonce_buf = NULL;
  500. u32 wr_cnt = 0;
  501. if (authen_key == NULL) {
  502. UFS_DBG_LOGE("[%s]: RPMB authen_key pointer NULL\n", __func__);
  503. return -1;
  504. }
  505. nonce_buf = rpmb_nonce_buf;
  506. memset(nonce_buf, 0, RPMB_FRM_NONCE_LEN);
  507. /* If read counter success, it means key has been written -> return without program key again */
  508. ret = rpmb_authen_read_counter(host_id, nonce_buf, RPMB_FRM_NONCE_LEN,
  509. &wr_cnt);
  510. if (!ret) {
  511. UFS_DBG_LOGE("[%s]: RPMB Key has been written! ret = %d\n", __func__, ret);
  512. return 0;
  513. }
  514. #if CFG_RPMB_KEY_PROGRAMED_IN_KERNEL
  515. if (rpmb_result != NULL)
  516. *rpmb_result = 7; /* Key not program */
  517. print("UFS rpmb key will be programmed in kernel, skip now!\n" );
  518. #else
  519. ret = rpmb_authen_key_program(host_id, authen_key, RPMB_FRM_KEY_MAC_LEN);
  520. if (ret)
  521. UFS_DBG_LOGE("[%s]: RPMB [Failed]Authentication Key not Programed this time, ret = %d\n", __func__, ret);
  522. else
  523. UFS_DBG_LOGI("[%s]: RPMB [PASS]Authentication Key Program Success\n", __func__);
  524. #endif
  525. return ret;
  526. }
  527. #ifdef MTK_UFS_OTP
  528. int otp_found = 0;
  529. #endif
  530. static void dump_swpcb(struct secure_wp_config_block *swpcb)
  531. {
  532. int i;
  533. UFS_DBG_LOGE("swpcb lun %d\n", swpcb->lun);
  534. UFS_DBG_LOGE("swpcb data_length %d\n", swpcb->data_length);
  535. for (i = 0; i < (swpcb->data_length/WP_ENTRY_SIZE); i++) {
  536. UFS_DBG_LOGE("swpcb entry[%d] wpt_wpf 0x%x\n", i, swpcb->wp_entry[i].wpt_wpf);
  537. UFS_DBG_LOGE("swpcb entry[%d] upper_addr 0x%x\n", i, swpcb->wp_entry[i].upper_addr);
  538. UFS_DBG_LOGE("swpcb entry[%d] lower_addr 0x%x\n", i, swpcb->wp_entry[i].lower_addr);
  539. UFS_DBG_LOGE("swpcb entry[%d] block_num 0x%x\n", i, swpcb->wp_entry[i].block_num);
  540. }
  541. }
  542. static int ufshcd_swp_conf_block_write_prepare(u32 host_id, struct ufs_aio_scsi_cmd *cmd,
  543. u16 blk_num, u32 wr_cnt, STORAGE_WP_TYPE type, unsigned long blknr, u32 blkcnt, ufs_logical_unit partition,u8 wp_entry,const u8 *data_buf)
  544. {
  545. struct rpmb_data_frame *pfrm = NULL;
  546. int err = 0;
  547. struct secure_wp_config_block *swpcb = (void *)data_buf;
  548. int skip_new_entry = 0;
  549. #if (defined(MTK_UFS_DRV_DA) || defined(MTK_UFS_DRV_PRELOADER))
  550. u8 rpmb_hmac_data[HMAC_TEXT_LEN] = {0};
  551. u8 rpmb_hmac_derived[RPMB_FRM_KEY_MAC_LEN] = {0};
  552. #endif
  553. #if defined(MTK_UFS_DRV_PRELOADER)
  554. char rpmb_key[RPMB_KEY_SIZE] = {0};
  555. #endif
  556. if (cmd == NULL) {
  557. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  558. return -1;
  559. }
  560. if (data_buf == NULL) {
  561. UFS_DBG_LOGE("[%s]: RPMB data_buf pointer NULL\n", __func__);
  562. return -1;
  563. }
  564. pfrm = cmd->data_buf;
  565. if (pfrm == NULL) {
  566. UFS_DBG_LOGE("[%s]: RPMB pfrm pointer NULL\n", __func__);
  567. return -1;
  568. }
  569. #ifdef MTK_UFS_OTP
  570. if (type == WP_PERMANENT && otp_found) {
  571. /*
  572. * Do not add new entry if we want to add an OTP entry but
  573. * OTP region is already existed in configuration block.
  574. *
  575. * We are here because we still need to write
  576. * modified configuration block after clean job in the 1st round.
  577. */
  578. skip_new_entry = 1;
  579. }
  580. #endif
  581. memset(pfrm, 0, sizeof(struct rpmb_data_frame) * blk_num);
  582. pfrm->req_resp = cpu_to_be16(RPMB_REQ_SEC_WPCB_WRITE);
  583. pfrm->blk_cnt = cpu_to_be16(blk_num);
  584. pfrm->addr = 0;
  585. pfrm->wr_cnt = cpu_to_be32(wr_cnt);
  586. /*fix nonce data to 0*/
  587. /* LUN */
  588. swpcb->lun= (partition - 1);
  589. /* Data length */
  590. if ( partition == UFS_LU_BOOT1 || partition == UFS_LU_BOOT2)
  591. swpcb->data_length = WP_ENTRY_SIZE; //Boot partition only needs one secure write protect block entry
  592. else {
  593. if (skip_new_entry)
  594. swpcb->data_length = WP_ENTRY_SIZE * wp_entry;
  595. else
  596. swpcb->data_length = WP_ENTRY_SIZE * (wp_entry + 1);
  597. }
  598. /* WP entries configuration */
  599. /* Protect entire BOOT1 & BOOT2 area */
  600. if ( partition == UFS_LU_BOOT1 || partition == UFS_LU_BOOT2) {
  601. if (type == WP_DISABLE)
  602. swpcb->wp_entry[0].wpt_wpf = WP_WPF_DISABLE;
  603. else
  604. swpcb->wp_entry[0].wpt_wpf = WP_WPF_EN | (type << WPT_BIT);
  605. //Number of Logical Blocks : 0x0 protect all blocks
  606. swpcb->wp_entry[0].block_num = 0;
  607. swpcb->wp_entry[0].upper_addr = 0;
  608. swpcb->wp_entry[0].lower_addr = 0;
  609. } else { //only update latest wp_entry
  610. if (!skip_new_entry) {
  611. if (type == WP_DISABLE)
  612. swpcb->wp_entry[wp_entry].wpt_wpf = WP_WPF_DISABLE;
  613. else
  614. swpcb->wp_entry[wp_entry].wpt_wpf = WP_WPF_EN | (type << WPT_BIT);
  615. //Logical Block Address
  616. //swpcb->wp_entry[wp_entry].upper_addr = ((blknr>>56) & 0xFF) | (((blknr>>48) & 0xFF) <<8) | (((blknr>>40) & 0xFF) <<16) | (((blknr>>32) & 0xFF) <<24); /* unsigned long in lk is only 32bits */
  617. swpcb->wp_entry[wp_entry].lower_addr = ((blknr>>24) & 0xFF) | (((blknr>>16) & 0xFF) <<8) | (((blknr>>8) & 0xFF) <<16) | ((blknr& 0xFF) <<24);
  618. //Number of Logical Blocks
  619. swpcb->wp_entry[wp_entry].block_num = ((blkcnt>>24) & 0xFF) | (((blkcnt>>16) & 0xFF) <<8) | (((blkcnt>>8) & 0xFF) <<16) | ((blkcnt & 0xFF) <<24);
  620. }
  621. }
  622. UFS_DBG_LOGE("[%s]: Write swpcb\n", __func__);
  623. dump_swpcb(swpcb);
  624. /* Copy entire "data_buf" to "pfrm->data" before calculate HMAC */
  625. memcpy(pfrm->data, data_buf, WP_CONF_BLOCK_SIZE);
  626. #if defined(MTK_UFS_DRV_LK)
  627. // Calculate MAC
  628. err = rpmb_get_mac(pfrm);
  629. if (err) {
  630. UFS_DBG_LOGE("[%s]: RPMB rpmb_get_mac fail, ret = %d\r\n", __func__, err);
  631. return -1;
  632. }
  633. memcpy(pfrm->key_MAC, shared_hmac_addr1, RPMB_FRM_KEY_MAC_LEN);
  634. #endif
  635. #if defined(MTK_UFS_DRV_PRELOADER)
  636. err = rpmb_get_key(&rpmb_key[0], RPMB_KEY_SIZE);
  637. if (err) {
  638. print("\n RPMB storage get key fail err = %d\n", err);
  639. return err;
  640. }
  641. rpmb_req_copy_data_for_hmac(rpmb_hmac_data, pfrm);
  642. err = hmac_sha256(rpmb_key, 32, rpmb_hmac_data, HMAC_TEXT_LEN, rpmb_hmac_derived);
  643. if (err) {
  644. UFS_DBG_LOGE("[%s]: RPMB rpmb_get_mac fail, ret = %d\r\n", __func__, err);
  645. return -1;
  646. }
  647. memcpy(pfrm->key_MAC, rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN);
  648. #endif
  649. #if defined(MTK_UFS_DRV_DA)
  650. rpmb_req_copy_data_for_hmac(rpmb_hmac_data, pfrm);
  651. err = rpmb_hmac(rpmb_hmac_data, HMAC_TEXT_LEN, rpmb_hmac_derived);
  652. if (err) {
  653. UFS_DBG_LOGE("[%s]: RPMB rpmb_get_mac fail, ret = %d\r\n", __func__, err);
  654. return -1;
  655. }
  656. memcpy(pfrm->key_MAC, rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN);
  657. #endif
  658. return err;
  659. }
  660. static int ufshcd_swp_conf_block_read_prepare(u32 host_id, struct ufs_aio_scsi_cmd *cmd,
  661. u16 blk_num,
  662. u8 *nonce, unsigned int nonce_len, ufs_logical_unit partition)
  663. {
  664. struct rpmb_data_frame *pfrm = NULL;
  665. unsigned int i = 0;
  666. int ret = 0;
  667. if (cmd == NULL) {
  668. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  669. return -1;
  670. }
  671. if (nonce == NULL) {
  672. UFS_DBG_LOGE("[%s]: RPMB nonce pointer NULL\n", __func__);
  673. return -1;
  674. }
  675. pfrm = cmd->data_buf;
  676. if (pfrm == NULL) {
  677. UFS_DBG_LOGE("[%s]: RPMB pfrm pointer NULL\n", __func__);
  678. return -1;
  679. }
  680. memset(pfrm, 0, sizeof(struct rpmb_data_frame));
  681. pfrm->req_resp = cpu_to_be16(RPMB_REQ_SEC_WPCB_READ);
  682. pfrm->blk_cnt = cpu_to_be16(blk_num);
  683. pfrm->addr = 0;
  684. /* Prepare the max 16 bytes nonce */
  685. for (i = 0; i < nonce_len; i++)
  686. nonce[i] = (u8)i & 0xFF; /* ToDO: get random nonce */
  687. memcpy(pfrm->nonce, nonce, nonce_len);
  688. pfrm->data[0] = partition - 1;
  689. return ret;
  690. }
  691. static int ufshcd_authen_data_write_rsp_check(u32 host_id, struct ufs_aio_scsi_cmd *cmd, u32 wcnt,
  692. enum enum_rpmb_msg type)
  693. {
  694. struct rpmb_data_frame *rpmb_frame = NULL;
  695. unsigned int idx = 0;
  696. int ret = 0;
  697. #if (defined(MTK_UFS_DRV_DA) || defined(MTK_UFS_DRV_PRELOADER))
  698. u8 rpmb_hmac_data[HMAC_TEXT_LEN] = {0};
  699. u8 rpmb_hmac_derived[RPMB_FRM_KEY_MAC_LEN] = {0};
  700. #endif
  701. #if defined(MTK_UFS_DRV_PRELOADER)
  702. char rpmb_key[RPMB_KEY_SIZE] = {0};
  703. #endif
  704. if (cmd == NULL) {
  705. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  706. return -1;
  707. }
  708. rpmb_frame = cmd->data_buf;
  709. if (rpmb_frame == NULL) {
  710. UFS_DBG_LOGE("[%s]: RPMB rpmb_frame pointer NULL\n", __func__);
  711. return -1;
  712. }
  713. if ( rpmb_frame->req_resp != cpu_to_be16(type)) {
  714. /* Check response type */
  715. UFS_DBG_LOGE("[%s]: RPMB Fail in checking response type : 0x%x\r\n", __func__, cpu_to_be16(rpmb_frame->req_resp));
  716. return -1;
  717. } else if ((idx = (cpu_to_be16(rpmb_frame->result) & 0x7F))) {
  718. /* Check response type */
  719. UFS_DBG_LOGE("[%s]: RPMB Fail in checking result : %s \r\n", __func__, rpmb_oper_result[idx]);
  720. return -1;
  721. } else if (cpu_to_be16(rpmb_frame->result) & 0x80) {
  722. /*Check Write Counter*/
  723. UFS_DBG_LOGE("[%s]: RPMB write counter is expired\r\n", __func__);
  724. }
  725. #if defined(MTK_UFS_DRV_LK)
  726. // Then check MAC
  727. ret = rpmb_get_mac(rpmb_frame);
  728. if (ret) {
  729. UFS_DBG_LOGE("[%s]: RPMB ufshcd_authen_data_write_rsp_check rpmb_get_mac fail, ret = %d\r\n", __func__, ret);
  730. return -1;
  731. }
  732. if (memcmp(rpmb_frame->key_MAC, shared_hmac_addr1, RPMB_FRM_KEY_MAC_LEN)) {
  733. UFS_DBG_LOGE("[%s]: RPMB Fail in Mac Check!\n", __func__);
  734. UFS_DBG_LOGE("Device Return ");
  735. ufshcd_rpmb_mac_dump((const u8*)rpmb_frame->key_MAC, RPMB_FRM_KEY_MAC_LEN);
  736. UFS_DBG_LOGE("Host Recalc");
  737. ufshcd_rpmb_mac_dump((const u8*)shared_hmac_addr1, RPMB_FRM_KEY_MAC_LEN);
  738. return -1;
  739. }
  740. #endif
  741. #if defined(MTK_UFS_DRV_PRELOADER)
  742. ret = rpmb_get_key(&rpmb_key[0], RPMB_KEY_SIZE);
  743. if (ret) {
  744. print("\n RPMB storage get key fail err = %d\n", ret);
  745. return ret;
  746. }
  747. rpmb_req_copy_data_for_hmac(rpmb_hmac_data, rpmb_frame);
  748. ret = hmac_sha256(rpmb_key, 32, rpmb_hmac_data, HMAC_TEXT_LEN, rpmb_hmac_derived);
  749. if (ret) {
  750. UFS_DBG_LOGE("[%s]: RPMB rpmb_get_mac fail, ret = %d\r\n", __func__, ret);
  751. return -1;
  752. }
  753. if (memcmp(rpmb_frame->key_MAC, rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN)) {
  754. UFS_DBG_LOGE("[%s]: RPMB Fail in Mac Check!\n", __func__);
  755. UFS_DBG_LOGE("Device Return ");
  756. ufshcd_rpmb_mac_dump((const u8*)rpmb_frame->key_MAC, RPMB_FRM_KEY_MAC_LEN);
  757. UFS_DBG_LOGE("Host Recalc");
  758. ufshcd_rpmb_mac_dump((const u8*)rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN);
  759. return -1;
  760. }
  761. #endif
  762. #if defined(MTK_UFS_DRV_DA)
  763. rpmb_req_copy_data_for_hmac(rpmb_hmac_data, rpmb_frame);
  764. ret = rpmb_hmac(rpmb_hmac_data, HMAC_TEXT_LEN, rpmb_hmac_derived);
  765. if (ret) {
  766. UFS_DBG_LOGE("%s, rpmb_hmac error.\n", __func__);
  767. return -1;
  768. }
  769. if (memcmp(rpmb_frame->key_MAC, rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN)) {
  770. UFS_DBG_LOGE("[%s]: RPMB Fail in Mac Check!\n", __func__);
  771. UFS_DBG_LOGE("Device Return ");
  772. ufshcd_rpmb_mac_dump((const u8*)rpmb_frame->key_MAC, RPMB_FRM_KEY_MAC_LEN);
  773. UFS_DBG_LOGE("Host Recalc");
  774. ufshcd_rpmb_mac_dump((const u8*)rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN);
  775. return -1;
  776. }
  777. #endif
  778. // Check Wr_cnt increasement
  779. if (rpmb_frame->wr_cnt != cpu_to_be32(wcnt + 1)) {
  780. UFS_DBG_LOGE("[%s]: RPMB Fail in Write Counter Increasement!\n", __func__);
  781. return -1;
  782. }
  783. return ret;
  784. }
  785. static int ufshcd_authen_data_read_rsp_check(u32 host_id, struct ufs_aio_scsi_cmd *cmd,
  786. const u8 *nonce_buf, unsigned int nonce_len, u8 *data_buf,
  787. enum enum_rpmb_msg type)
  788. {
  789. struct rpmb_data_frame *pfrm = NULL;
  790. unsigned int idx = 0;
  791. int ret = 0;
  792. #if (defined(MTK_UFS_DRV_DA) || defined(MTK_UFS_DRV_PRELOADER))
  793. u8 rpmb_hmac_data[HMAC_TEXT_LEN] = {0};
  794. u8 rpmb_hmac_derived[RPMB_FRM_KEY_MAC_LEN] = {0};
  795. #endif
  796. #if defined(MTK_UFS_DRV_PRELOADER)
  797. char rpmb_key[RPMB_KEY_SIZE] = {0};
  798. #endif
  799. if (cmd == NULL) {
  800. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  801. return -1;
  802. }
  803. if (nonce_buf == NULL) {
  804. UFS_DBG_LOGE("[%s]: RPMB nonce_buf pointer NULL\n", __func__);
  805. return -1;
  806. }
  807. if (data_buf == NULL) {
  808. UFS_DBG_LOGE("[%s]: RPMB ata_buf pointer NULL\n", __func__);
  809. return -1;
  810. }
  811. pfrm = cmd->data_buf;
  812. if (pfrm == NULL) {
  813. UFS_DBG_LOGE("[%s]: RPMB pfrm pointer NULL\n", __func__);
  814. return -1;
  815. }
  816. if (pfrm->req_resp != cpu_to_be16(type)) {
  817. /* Check response type */
  818. UFS_DBG_LOGE("[%s]: RPMB Fail in checking response type : 0x%x\r\n", __func__, cpu_to_be16(pfrm->req_resp));
  819. return -1;
  820. } else if ((idx = (cpu_to_be16(pfrm->result) & 0x7F))) {
  821. /* Check response type */
  822. UFS_DBG_LOGE("[%s]: RPMB Fail in checking result : %s \r\n", __func__, rpmb_oper_result[idx]);
  823. return -1;
  824. } else if (cpu_to_be16(pfrm->result) & 0x80) {
  825. /*Check Write Counter*/
  826. UFS_DBG_LOGE("[%s]: RPMB write counter is expired\r\n", __func__);
  827. }
  828. if (memcmp(pfrm->nonce, nonce_buf, nonce_len) ) {
  829. /*for other response type noce will be "0"*/
  830. UFS_DBG_LOGE("[%s]: RPMB Fail in checking nonce\r\n", __func__);
  831. return -1;
  832. }
  833. #if defined(MTK_UFS_DRV_LK)
  834. ret = rpmb_get_mac(pfrm);
  835. if (ret) {
  836. UFS_DBG_LOGE("[%s]: RPMB rpmb_get_mac fail, ret = %d \r\n", __func__, ret);
  837. return -1;
  838. }
  839. if (memcmp(pfrm->key_MAC, shared_hmac_addr1, RPMB_FRM_KEY_MAC_LEN) ) {
  840. /*for other response type noce will be "0"*/
  841. UFS_DBG_LOGE("[%s]: RPMB Fail in checking MAC\r\n", __func__);
  842. UFS_DBG_LOGE("Device Return");
  843. ufshcd_rpmb_mac_dump((const u8*)pfrm->key_MAC, RPMB_FRM_KEY_MAC_LEN);
  844. UFS_DBG_LOGE("Host Recalc");
  845. ufshcd_rpmb_mac_dump((const u8*)shared_hmac_addr1, RPMB_FRM_KEY_MAC_LEN);
  846. return -1;
  847. }
  848. #endif
  849. #if defined(MTK_UFS_DRV_PRELOADER)
  850. ret = rpmb_get_key(&rpmb_key[0], RPMB_KEY_SIZE);
  851. if (ret) {
  852. print("\n RPMB storage get key fail err = %d\n", ret);
  853. return ret;
  854. }
  855. rpmb_req_copy_data_for_hmac(rpmb_hmac_data, pfrm);
  856. ret = hmac_sha256(rpmb_key, 32, rpmb_hmac_data, HMAC_TEXT_LEN, rpmb_hmac_derived);
  857. if (ret) {
  858. UFS_DBG_LOGE("[%s]: RPMB rpmb_get_mac fail, ret = %d\r\n", __func__, ret);
  859. return -1;
  860. }
  861. if (memcmp(pfrm->key_MAC, rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN)) {
  862. UFS_DBG_LOGE("[%s]: RPMB Fail in checking MAC\r\n", __func__);
  863. UFS_DBG_LOGE("Device Return");
  864. ufshcd_rpmb_mac_dump((const u8*)pfrm->key_MAC, RPMB_FRM_KEY_MAC_LEN);
  865. UFS_DBG_LOGE("Host Recalc");
  866. ufshcd_rpmb_mac_dump((const u8*)rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN);
  867. return -1;
  868. }
  869. #endif
  870. #if defined(MTK_UFS_DRV_DA)
  871. rpmb_req_copy_data_for_hmac(rpmb_hmac_data, pfrm);
  872. ret = rpmb_hmac(rpmb_hmac_data, HMAC_TEXT_LEN, rpmb_hmac_derived);
  873. if (ret) {
  874. UFS_DBG_LOGE("%s, rpmb_hmac error.\n", __func__);
  875. return -1;
  876. }
  877. if (memcmp(pfrm->key_MAC, rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN)) {
  878. UFS_DBG_LOGE("[%s]: RPMB Fail in checking MAC\r\n", __func__);
  879. UFS_DBG_LOGE("Device Return");
  880. ufshcd_rpmb_mac_dump((const u8*)pfrm->key_MAC, RPMB_FRM_KEY_MAC_LEN);
  881. UFS_DBG_LOGE("Host Recalc");
  882. ufshcd_rpmb_mac_dump((const u8*)rpmb_hmac_derived, RPMB_FRM_KEY_MAC_LEN);
  883. return -1;
  884. }
  885. #endif
  886. memcpy(data_buf, pfrm->data, WP_CONF_BLOCK_SIZE); //Copy Secure Write Protect Block to data_buf
  887. return 0;
  888. }
  889. static int rpmb_authen_secure_write_protect_conf_block_write(u32 host_id, u32 wr_cnt,
  890. const u8 *dat_buf,
  891. u32 blk_num, STORAGE_WP_TYPE type, unsigned long blknr, u32 blkcnt, ufs_logical_unit partition, u8 wp_entry)
  892. {
  893. struct ufs_aio_scsi_cmd cmd;
  894. struct ufs_hba *hba;
  895. int ret = 0;
  896. int tag;
  897. if (dat_buf == NULL) {
  898. UFS_DBG_LOGE("[%s]: RPMB data_buf pointer NULL\n", __func__);
  899. return -1;
  900. }
  901. cmd.data_buf = ufs_rpmb_buf;
  902. hba = ufs_aio_get_host(host_id);
  903. if (!ufshcd_get_free_tag(hba, &tag))
  904. return -1;
  905. /*Step1 write counter read request */
  906. cmd_scsi_security_protocol_out(&cmd, tag, blk_num,
  907. UFS_SECURITY_PROTOCOL,
  908. RPMB_PROTOCOL_ID);
  909. //cmd.cmd_data[4] = 0x80; //INC_512 = 1
  910. ufshcd_swp_conf_block_write_prepare(host_id, &cmd,
  911. blk_num, wr_cnt, type, blknr, blkcnt, partition, wp_entry, dat_buf);
  912. ufshcd_rpmb_mac_dump(dat_buf, RPMB_SWP_CB_VALID_DATA_SIZE);
  913. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  914. UFS_DBG_LOGE("[%s]: RPMB Fail in Sending Secure Write Protect Conf. Block write request, ret = %d \n", __func__, ret);
  915. goto exit;
  916. }
  917. /*Step2. Result Register Read Request*/
  918. cmd_scsi_security_protocol_out(&cmd, tag, 1,
  919. UFS_SECURITY_PROTOCOL,
  920. RPMB_PROTOCOL_ID);
  921. ufshcd_authen_result_read_req_prepare(&cmd);
  922. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  923. UFS_DBG_LOGE("[%s]: RPMB Fail in Sending result register read request, ret = %d \n", __func__, ret);
  924. return ret;
  925. }
  926. /*Step3 Check Response for Result Read Request*/
  927. cmd_scsi_security_protocol_in(&cmd, tag, 1, UFS_SECURITY_PROTOCOL, RPMB_PROTOCOL_ID);
  928. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  929. UFS_DBG_LOGE("[%s]: RPMB Fail in Sending request get result register response, ret = %d \n", __func__, ret);
  930. goto exit;
  931. }
  932. /*Step3. Response frame check*/
  933. if ((ret = ufshcd_authen_data_write_rsp_check(host_id, &cmd, wr_cnt,
  934. RPMB_RSP_SEC_WPCB_WRITE))) {
  935. UFS_DBG_LOGE("[%s]: RPMB WriteCounter Read Resp Check Fail, ret = %d \n", __func__, ret);
  936. goto exit;
  937. }
  938. exit:
  939. ufshcd_put_tag(hba, tag);
  940. return ret;
  941. }
  942. static int rpmb_authen_secure_write_protect_conf_block_read(u32 host_id,u8 * data_buf,
  943. u8 *nonce_buf, u32 nonce_len,
  944. u32 blk_num, ufs_logical_unit partition)
  945. {
  946. struct ufs_aio_scsi_cmd cmd;
  947. struct ufs_hba *hba;
  948. int ret = 0;
  949. int tag;
  950. if (data_buf == NULL) {
  951. UFS_DBG_LOGE("[%s]: RPMB data_buf pointer NULL\n", __func__);
  952. return -1;
  953. }
  954. if (nonce_buf == NULL) {
  955. UFS_DBG_LOGE("[%s]: RPMB nonce_buf pointer NULL\n", __func__);
  956. return -1;
  957. }
  958. cmd.data_buf = ufs_rpmb_buf;
  959. hba = ufs_aio_get_host(host_id);
  960. if (!ufshcd_get_free_tag(hba, &tag))
  961. return -1;
  962. /*Step1 authen data read request */
  963. cmd_scsi_security_protocol_out(&cmd, tag, 1,
  964. UFS_SECURITY_PROTOCOL,
  965. RPMB_PROTOCOL_ID);
  966. //cmd.cmd_data[4] = 0x80; //INC_512 = 1
  967. ufshcd_swp_conf_block_read_prepare(host_id, &cmd,
  968. blk_num, nonce_buf, nonce_len, partition);
  969. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  970. UFS_DBG_LOGE("[%s]: RPMB Fail in Sending Secure Write Protect Conf. Block read request, ret = %d \n", __func__, ret);
  971. goto exit;
  972. }
  973. /*Step2 Send protocol in cmd for data read*/
  974. cmd_scsi_security_protocol_in(&cmd, tag, blk_num, UFS_SECURITY_PROTOCOL, RPMB_PROTOCOL_ID);
  975. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  976. UFS_DBG_LOGE("[%s]: RPMB Fail in Sending request get result register response, ret = %d \n", __func__, ret);
  977. goto exit;
  978. }
  979. /*Step3 Check Response and parser data*/
  980. if ((ret = ufshcd_authen_data_read_rsp_check(host_id, &cmd,
  981. nonce_buf, nonce_len, data_buf, RPMB_RSP_SEC_WPCB_READ))) {
  982. UFS_DBG_LOGE("[%s]: RPMB Data Read Resp Check Fail, ret = %d \n", __func__, ret);
  983. goto exit;
  984. }
  985. /* ufshcd_rpmb_mac_dump(data_buf, RPMB_SWP_CB_VALID_DATA_SIZE); */
  986. exit:
  987. ufshcd_put_tag(hba, tag);
  988. return ret;
  989. }
  990. static int rpmb_authen_secure_write_protect_conf_block_check(u8 *data_buf, u8 *wp_entry , unsigned long blknr, u32 blkcnt, ufs_logical_unit partition, STORAGE_WP_TYPE type)
  991. {
  992. static int round = 0;
  993. #ifdef MTK_UFS_OTP
  994. u8 i = 0;
  995. #endif
  996. struct secure_wp_config_block *swpcb = (void *)data_buf;
  997. if (data_buf == NULL) {
  998. UFS_DBG_LOGE("[%s]: RPMB data_buf pointer NULL\n", __func__);
  999. return -1;
  1000. }
  1001. if (wp_entry==NULL) {
  1002. UFS_DBG_LOGE("[%s]: RPMB wp_entry pointer NULL\n", __func__);
  1003. return -1;
  1004. }
  1005. UFS_DBG_LOGE("[%s]: Read swpcb\n", __func__);
  1006. dump_swpcb(swpcb);
  1007. /* For Boot1/Boot2, only lock all region. And only have one wp_entry */
  1008. if (partition == UFS_LU_BOOT1 || partition == UFS_LU_BOOT2 || type == WP_DISABLE) {
  1009. memset(&(swpcb->wp_entry[0]), 0, WP_ENTRY_SIZE * SWPWP_ENTRY_NUM);
  1010. *wp_entry = 0;
  1011. return 0;
  1012. }
  1013. /* For USER partition */
  1014. /* For OTP: Each Boot, we re-write secure write protect Entries. Only keep OTP entry. */
  1015. /* Because protect start & size may change, SW have no idea how they change. */
  1016. #ifdef MTK_UFS_OTP
  1017. /* First enter write protect secure write protect entries, need to keep OTP entery if any */
  1018. if (round == 0) {
  1019. UFS_DBG_LOGD("[%s] Finding OTP entry ...\n", __func__);
  1020. for (i = 0 ; i < (swpcb->data_length / WP_ENTRY_SIZE); i++) {
  1021. UFS_DBG_LOGD("[%s] Checking entry %d, wpt_wtf: 0x%x\n", __func__, i, swpcb->wp_entry[i].wpt_wpf);
  1022. /* If find OTP entries, copy OTP to entry 0, clear other entries, set wp_entry to 1 */
  1023. if ((swpcb->wp_entry[i].wpt_wpf & 0x7) == 0x1) { /* WPT = 0, WPF = 1 */
  1024. UFS_DBG_LOGD("[%s] OTP entry is found in index %d\n", __func__, i);
  1025. if (i != 0) {
  1026. /* only need copy i to 0 if i != 0 */
  1027. UFS_DBG_LOGD("[%s] Copy OTP entry %d -> 0\n", __func__, i);
  1028. memcpy(&(swpcb->wp_entry[0]), &(swpcb->wp_entry[i]), sizeof(struct secure_wp_entry));
  1029. memset(&(swpcb->wp_entry[i]), 0, WP_ENTRY_SIZE * (SWPWP_ENTRY_NUM - 1));
  1030. }
  1031. otp_found++;
  1032. } else {
  1033. /* clear all other entries */
  1034. memset(&(swpcb->wp_entry[i]), 0, sizeof(struct secure_wp_entry));
  1035. }
  1036. }
  1037. if (otp_found > 1) {
  1038. UFS_DBG_LOGE("[%s] Found multiple OTP entries, ERROR!\n", __func__);
  1039. return UFS_OTP_INVALID_ENTRY;
  1040. }
  1041. if (otp_found)
  1042. *wp_entry = 1;
  1043. else
  1044. *wp_entry = 0;
  1045. } else { /* Not first enter, just write to last free entry later */
  1046. if (swpcb->data_length == WP_MAX_ENTRY_SIZE) {
  1047. UFS_DBG_LOGE("[%s]: RPMB exceed WP entries size!!! \n", __func__);
  1048. return UFS_POWER_ON_WP_ENTRY_FULL;
  1049. }
  1050. *wp_entry = swpcb->data_length / WP_ENTRY_SIZE;
  1051. }
  1052. round++;
  1053. if (otp_found > 0 && round > 1 && type == WP_PERMANENT) {
  1054. /*
  1055. * If we want to lock OTP but OTP entry is found in configruation block,
  1056. * do not modify original entry, just write it (old one) to configuration block.
  1057. *
  1058. * For round == 1, we still need to write modified configuration block (after clean job)
  1059. * anyway, so do not return error code here to let programming flow continue.
  1060. *
  1061. * For round > 1, just return error code because we do not need any programming.
  1062. */
  1063. UFS_DBG_LOGD("[%s]: OTP already locked previously! Skipped.\n", __func__);
  1064. return UFS_OTP_ALREADY_LOCKED;
  1065. }
  1066. #else
  1067. /*
  1068. * For non OTP project, always clean wp entries at first time.
  1069. *
  1070. * Note: OTP protected region will be clear and reset by this job!
  1071. */
  1072. if (round == 0) {
  1073. memset(&(swpcb->wp_entry[0]), 0, WP_ENTRY_SIZE * SWPWP_ENTRY_NUM);
  1074. *wp_entry = 0;
  1075. } else {
  1076. if (swpcb->data_length == WP_MAX_ENTRY_SIZE) {
  1077. UFS_DBG_LOGE("[%s]: RPMB exceed WP entries size!!! \n", __func__);
  1078. return UFS_POWER_ON_WP_ENTRY_FULL;
  1079. }
  1080. *wp_entry = swpcb->data_length/WP_ENTRY_SIZE;
  1081. }
  1082. round++;
  1083. #endif
  1084. return 0;
  1085. }
  1086. int rpmb_ufs_set_wp(u32 host_id, STORAGE_WP_TYPE type, unsigned long blknr,
  1087. u32 blkcnt,ufs_logical_unit partition)
  1088. {
  1089. u8 *nonce_buf = NULL;
  1090. u8 *data_buf = NULL;
  1091. u32 wr_cnt = 0;
  1092. int ret = 0;
  1093. u8 wp_entry = 0;
  1094. nonce_buf = rpmb_nonce_buf;
  1095. memset(nonce_buf, 0, RPMB_FRM_NONCE_LEN);
  1096. data_buf = rpmb_frame_buf;
  1097. memset(data_buf, 0, RPMB_FRM_DATA_LEN);
  1098. /* Read Old Secure Write Protect Conf Block */
  1099. ret = rpmb_authen_read_counter(host_id, nonce_buf, RPMB_FRM_NONCE_LEN,
  1100. &wr_cnt);
  1101. if (ret) {
  1102. UFS_DBG_LOGE("[%s]: RPMB rpmb_authen_read_counter fail! ret = %d\n", __func__, ret);
  1103. goto exit;
  1104. }
  1105. ret = rpmb_authen_secure_write_protect_conf_block_read(host_id, data_buf, nonce_buf, RPMB_FRM_NONCE_LEN, 1, partition);
  1106. if (ret ) {
  1107. UFS_DBG_LOGE("[%s]: RPMB rpmb_authen_secure_write_protect_conf_block_read fail! ret = %d\n", __func__, ret);
  1108. goto exit;
  1109. } else
  1110. UFS_DBG_LOGD("Authenticated Data Read Success!\n");
  1111. ret = rpmb_authen_secure_write_protect_conf_block_check(data_buf, &wp_entry, blknr, blkcnt, partition, type);
  1112. if (ret) {
  1113. UFS_DBG_LOGE("[%s]: RPMB rpmb_authen_secure_write_protect_conf_block_check fail! ret = %d\n", __func__, ret);
  1114. goto exit;
  1115. }
  1116. /* Get Current Write Counter */
  1117. ret = rpmb_authen_read_counter(host_id, nonce_buf, RPMB_FRM_NONCE_LEN,
  1118. &wr_cnt);
  1119. if (ret) {
  1120. UFS_DBG_LOGE("[%s]: RPMB rpmb_authen_read_counter fail! ret = %d\n", __func__, ret);
  1121. goto exit;
  1122. }
  1123. /* Authenticated Data Write */
  1124. ret = rpmb_authen_secure_write_protect_conf_block_write(host_id, wr_cnt,
  1125. data_buf, 1, type, blknr, blkcnt, partition, wp_entry);
  1126. if (ret ) {
  1127. UFS_DBG_LOGE("[%s]: RPMB rpmb_authen_secure_write_protect_conf_block_write Fail! ret = %d\n", __func__, ret);
  1128. goto exit;
  1129. } else
  1130. UFS_DBG_LOGD("Authenticated Data Write Success 1 blks\n");
  1131. exit:
  1132. return ret;
  1133. }
  1134. int rpmb_ufs_clr_wp(u32 host_id, ufs_logical_unit partition)
  1135. {
  1136. u8 *nonce_buf = NULL;
  1137. u8 *data_buf = NULL;
  1138. u32 wr_cnt = 0;
  1139. int ret = 0;
  1140. u8 wp_entry = 0;
  1141. struct secure_wp_config_block *swpcb;
  1142. nonce_buf = rpmb_nonce_buf;
  1143. memset(nonce_buf, 0, RPMB_FRM_NONCE_LEN);
  1144. data_buf = rpmb_frame_buf;
  1145. memset(data_buf, 0, RPMB_FRM_DATA_LEN);
  1146. swpcb = (void *)data_buf;
  1147. swpcb->data_length = 16;
  1148. wp_entry = 0;
  1149. /* Get Current Write Counter */
  1150. ret = rpmb_authen_read_counter(host_id, nonce_buf, RPMB_FRM_NONCE_LEN,
  1151. &wr_cnt);
  1152. if (ret) {
  1153. UFS_DBG_LOGE("[%s]: RPMB rpmb_authen_read_counter fail! ret = %d\n", __func__, ret);
  1154. goto exit;
  1155. }
  1156. /* Authenticated Data Write */
  1157. ret = rpmb_authen_secure_write_protect_conf_block_write(host_id, wr_cnt,
  1158. data_buf, 1, WP_DISABLE, 0, 0, partition, wp_entry);
  1159. if (ret ) {
  1160. UFS_DBG_LOGE("[%s]: RPMB rpmb_authen_secure_write_protect_conf_block_write Fail! ret = %d\n", __func__, ret);
  1161. goto exit;
  1162. } else
  1163. UFS_DBG_LOGD("Authenticated Data Write Success 1 blks\n");
  1164. exit:
  1165. return ret;
  1166. }
  1167. #if 0 /* Test code only */
  1168. int ts_secure_write_protect(u32 host_id)
  1169. {
  1170. int ret = 0;
  1171. off_t offset = 0;
  1172. size_t size = 32;
  1173. u8 *buf_test[32] = {1};
  1174. ret = ufs_set_write_protect(host_id, UFS_LU_USER, 0x0, 0x100, WP_POWER_ON);
  1175. if (ret)
  1176. goto exit;
  1177. ret = ufs_set_write_protect(host_id, UFS_LU_USER, 0x100, 0x100, WP_POWER_ON);
  1178. if (ret)
  1179. goto exit;
  1180. ret = ufs_set_write_protect(host_id, UFS_LU_USER, 0x200, 0x100, WP_POWER_ON);
  1181. if (ret)
  1182. goto exit;
  1183. /* Note: Different for other projects need to contain nvram region */
  1184. if (ret)
  1185. ret = ufs_set_write_protect(host_id, UFS_LU_USER, 0xf000, 0xc000, WP_POWER_ON);
  1186. goto exit;
  1187. ret = ufs_set_write_protect(host_id, UFS_LU_BOOT1, 0x0, 0x200, WP_POWER_ON);
  1188. if (ret)
  1189. goto exit;
  1190. if (32!= partition_write("nvram", offset, buf_test, size))
  1191. UFS_DBG_LOGE("[%s]: RPMB write nvram fail!\n", __func__);
  1192. if (32!= partition_write("preloader", offset, buf_test, size))
  1193. UFS_DBG_LOGE("[%s]: RPMB write preloader fail!\n", __func__);
  1194. exit:
  1195. return ret;
  1196. }
  1197. #endif
  1198. int ufs_set_write_protect(int dev_num, ufs_logical_unit partition, unsigned long blknr, u32 blkcnt, STORAGE_WP_TYPE type)
  1199. {
  1200. int err = UFS_POWER_ON_WP_ERR;
  1201. UFS_DBG_LOGI("[%s]: RPMB partition = %d, wp_type = %d, blknr = 0x%lx, blkcnt = 0x%x\n",
  1202. __func__, partition, type, blknr, blkcnt);
  1203. if ((type == WP_POWER_ON || type == WP_PERMANENT || type == WP_PERMANENT_AWP) && partition == UFS_LU_USER) {
  1204. UFS_DBG_LOGD("[%s]: blknr: 0x%lx blkcnt: 0x%x\n",__func__ , blknr, blkcnt);
  1205. err = rpmb_ufs_set_wp(dev_num,type, blknr, blkcnt, partition);
  1206. if (err) {
  1207. UFS_DBG_LOGE("[%s]: RPMB rpmb_ufs_set_wp err! ret = %d\n", __func__, err);
  1208. return err;
  1209. }
  1210. } else if (((type == WP_POWER_ON || type == WP_PERMANENT_AWP) && partition == UFS_LU_BOOT1) ||
  1211. ((type == WP_POWER_ON || type == WP_PERMANENT_AWP) && partition == UFS_LU_BOOT2)) {
  1212. if (partition == UFS_LU_BOOT1) {
  1213. err = rpmb_ufs_set_wp(dev_num, type, blknr, blkcnt, UFS_LU_BOOT1);
  1214. if (err) {
  1215. UFS_DBG_LOGE("[%s]: RPMB rpmb_ufs_set_wp boot1 partition err ret= %d\n", __func__, err);
  1216. return err;
  1217. }
  1218. } else if (partition == UFS_LU_BOOT2) {
  1219. err = rpmb_ufs_set_wp(dev_num, type, blknr, blkcnt, UFS_LU_BOOT2);
  1220. if (err) {
  1221. UFS_DBG_LOGE("[%s]: RPMB rpmb_ufs_set_wp boot2 partition err%d\n", __func__,err);
  1222. return err;
  1223. }
  1224. }
  1225. } else if (type == WP_TEMPORARY) {
  1226. UFS_DBG_LOGE("[%s]: RPMB WP Type Not Support\n", __func__);
  1227. return 0;
  1228. } else if (type == WP_DISABLE) {
  1229. err = rpmb_ufs_clr_wp(dev_num, partition);
  1230. if (err) {
  1231. UFS_DBG_LOGE("[%s]: RPMB rpmb_ufs_clear_wp err%d\n", __func__, err);
  1232. return err;
  1233. }
  1234. return 0;
  1235. } else if (partition == UFS_LU_UNKNOWN ||partition == UFS_LU_RPMB
  1236. ||partition == UFS_LU_END) {
  1237. UFS_DBG_LOGE("[%s]: RPMB partition Not Support\n", __func__);
  1238. return 0;
  1239. } else {
  1240. return err;
  1241. }
  1242. return err;
  1243. }
  1244. int ufs_clr_write_protect(void)
  1245. {
  1246. int err = 0;
  1247. err = ufs_set_write_protect(0, UFS_LU_BOOT1, 0, 0, WP_DISABLE);
  1248. if (err) {
  1249. UFS_DBG_LOGE("[%s]: Clear UFS_LU_BOOT1 write protect fail\n", __func__);
  1250. goto out;
  1251. }
  1252. err = ufs_set_write_protect(0, UFS_LU_BOOT2, 0, 0, WP_DISABLE);
  1253. if (err) {
  1254. UFS_DBG_LOGE("[%s]: Clear UFS_LU_BOOT2 write protect fail\n", __func__);
  1255. goto out;
  1256. }
  1257. err |= ufs_set_write_protect(0, UFS_LU_USER, 0, 0, WP_DISABLE);
  1258. if (err) {
  1259. UFS_DBG_LOGE("[%s]: Clear UFS_LU_USER write protect fail\n", __func__);
  1260. goto out;
  1261. }
  1262. out:
  1263. return err;
  1264. }
  1265. #if defined(MTK_UFS_DRV_LK)
  1266. static int ufshcd_rpmb_read_data_req_prepare(struct ufs_aio_scsi_cmd *cmd,
  1267. u32 size, u16 addr)
  1268. {
  1269. struct rpmb_data_frame *pfrm = NULL;
  1270. if (cmd == NULL) {
  1271. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  1272. return -1;
  1273. }
  1274. pfrm = cmd->data_buf;
  1275. if (pfrm == NULL) {
  1276. UFS_DBG_LOGE("[%s]: RPMB pfrm pointer NULL\n", __func__);
  1277. return -1;
  1278. }
  1279. memset(pfrm, 0, sizeof(struct rpmb_data_frame));
  1280. /* Prepare write frame */
  1281. pfrm->addr = cpu_to_be16(addr);
  1282. pfrm->blk_cnt = cpu_to_be16(1);
  1283. pfrm->req_resp = cpu_to_be16(RPMB_REQ_AUTHEN_READ);
  1284. return 0;
  1285. }
  1286. int ufs_rpmb_read_data(u32 addr, u32 *buf, u32 buf_len)
  1287. {
  1288. struct ufs_aio_scsi_cmd cmd;
  1289. struct ufs_hba *hba;
  1290. int tag;
  1291. u8 *nonce_buf = NULL;
  1292. u8 *data_buf;
  1293. u32 host_id = 0;
  1294. u32 blk_len;
  1295. u32 left_size = buf_len;
  1296. u32 tran_size;
  1297. u32 i;
  1298. int ret = 0;
  1299. cmd.data_buf = ufs_rpmb_buf;
  1300. hba = ufs_aio_get_host(0);
  1301. if (buf_len % RPMB_FRM_DATA_LEN != 0) {
  1302. UFS_DBG_LOGE("[%s]: RPMB read write need 256 ytes align\n", __func__);
  1303. return -1;
  1304. }
  1305. blk_len = buf_len / RPMB_FRM_DATA_LEN;
  1306. data_buf = (u8 *)buf;
  1307. if (!ufshcd_get_free_tag(hba, &tag))
  1308. return -1;
  1309. nonce_buf = rpmb_nonce_buf;
  1310. memset(nonce_buf, 0, RPMB_FRM_NONCE_LEN);
  1311. for (i = 0; i < blk_len; i++) {
  1312. /* Step 1. Authen data read request */
  1313. if (left_size >= RPMB_FRM_DATA_LEN)
  1314. tran_size = RPMB_FRM_DATA_LEN;
  1315. else
  1316. tran_size = left_size;
  1317. cmd_scsi_security_protocol_out(&cmd, tag, 1,
  1318. UFS_SECURITY_PROTOCOL,
  1319. RPMB_PROTOCOL_ID);
  1320. ret = ufshcd_rpmb_read_data_req_prepare(&cmd, tran_size, addr + i);
  1321. if (ret) {
  1322. UFS_DBG_LOGE("[%s]: RPMB Fail in prepare frame, ret = %d \n", __func__, ret);
  1323. goto exit;
  1324. }
  1325. ret = ufshcd_queuecommand(hba, &cmd);
  1326. if (ret) {
  1327. UFS_DBG_LOGE("[%s]: RPMB Fail in send read frame, ret = %d \n", __func__, ret);
  1328. goto exit;
  1329. }
  1330. /* Step 2. Authen data read response */
  1331. cmd_scsi_security_protocol_in(&cmd, tag, 1,
  1332. UFS_SECURITY_PROTOCOL,
  1333. RPMB_PROTOCOL_ID);
  1334. ret = ufshcd_queuecommand(hba, &cmd);
  1335. if (ret) {
  1336. UFS_DBG_LOGE("[%s]: RPMB Fail in get read response, ret = %d \n", __func__, ret);
  1337. goto exit;
  1338. }
  1339. /* Step3. Check Response and parser data*/
  1340. ret = ufshcd_authen_data_read_rsp_check(host_id, &cmd,
  1341. nonce_buf, RPMB_FRM_NONCE_LEN, (data_buf + i * RPMB_FRM_DATA_LEN), RPMB_RSP_AUTHEN_READ);
  1342. if (ret) {
  1343. UFS_DBG_LOGE("[%s]: RPMB Data Read Resp Check Fail, ret = %d \n", __func__, ret);
  1344. goto exit;
  1345. }
  1346. left_size -= tran_size;
  1347. }
  1348. exit:
  1349. ufshcd_put_tag(hba, tag);
  1350. return ret;
  1351. }
  1352. static int ufshcd_rpmb_write_data_req_prepare(struct ufs_aio_scsi_cmd *cmd,
  1353. const u8 *data_buf, u32 size, u32 wr_cnt, u16 addr)
  1354. {
  1355. struct rpmb_data_frame *pfrm = NULL;
  1356. int ret = 0;
  1357. if (cmd == NULL) {
  1358. UFS_DBG_LOGE("[%s]: RPMB cmd pointer NULL\n", __func__);
  1359. return -1;
  1360. }
  1361. if (data_buf == NULL) {
  1362. UFS_DBG_LOGE("[%s]: RPMB data pointer NULL\n", __func__);
  1363. return -1;
  1364. }
  1365. pfrm = cmd->data_buf;
  1366. if (pfrm == NULL) {
  1367. UFS_DBG_LOGE("[%s]: RPMB pfrm pointer NULL\n", __func__);
  1368. return -1;
  1369. }
  1370. memset(pfrm, 0, sizeof(struct rpmb_data_frame));
  1371. /* Prepare write frame */
  1372. memcpy(pfrm->data, data_buf, size);
  1373. pfrm->wr_cnt = cpu_to_be32(wr_cnt);
  1374. pfrm->addr = cpu_to_be16(addr);
  1375. pfrm->blk_cnt = cpu_to_be16(1);
  1376. pfrm->req_resp = cpu_to_be16(RPMB_REQ_AUTHEN_WRITE);
  1377. /* Compute hmac. */
  1378. ret = rpmb_get_mac(pfrm);
  1379. if (ret) {
  1380. UFS_DBG_LOGE("[%s]: rpmb_get_mac fail\r\n", __func__);
  1381. return -1;
  1382. }
  1383. memcpy(pfrm->key_MAC, shared_hmac_addr1, RPMB_FRM_KEY_MAC_LEN);
  1384. return 0;
  1385. }
  1386. int ufs_rpmb_write_data(u32 addr, u32 *buf, u32 buf_len)
  1387. {
  1388. struct ufs_aio_scsi_cmd cmd;
  1389. struct ufs_hba *hba;
  1390. int tag;
  1391. u8 *nonce_buf = NULL;
  1392. u8 *data_buf;
  1393. u32 wr_cnt = 0;
  1394. u32 host_id = 0;
  1395. u32 blk_len;
  1396. u32 left_size = buf_len;
  1397. u32 tran_size;
  1398. u32 i;
  1399. int ret = 0;
  1400. cmd.data_buf = ufs_rpmb_buf;
  1401. hba = ufs_aio_get_host(0);
  1402. if (buf_len % RPMB_FRM_DATA_LEN != 0) {
  1403. UFS_DBG_LOGE("[%s]: RPMB read write need 256 ytes align\n", __func__);
  1404. return -1;
  1405. }
  1406. blk_len = buf_len / RPMB_FRM_DATA_LEN;
  1407. data_buf = (u8 *)buf;
  1408. /* Read RPMB write counter */
  1409. nonce_buf = rpmb_nonce_buf;
  1410. memset(nonce_buf, 0, RPMB_FRM_NONCE_LEN);
  1411. ret = rpmb_authen_read_counter(host_id, nonce_buf, RPMB_FRM_NONCE_LEN,
  1412. &wr_cnt);
  1413. if (ret) {
  1414. UFS_DBG_LOGE("[%s]: RPMB rpmb_authen_read_counter fail! ret = %d\n", __func__, ret);
  1415. goto free_nonce_buf;
  1416. }
  1417. if (!ufshcd_get_free_tag(hba, &tag)) {
  1418. ret = -1;
  1419. goto free_nonce_buf;
  1420. }
  1421. for (i = 0; i < blk_len; i++) {
  1422. /* Step 1. Authen data write request */
  1423. if (left_size >= RPMB_FRM_DATA_LEN)
  1424. tran_size = RPMB_FRM_DATA_LEN;
  1425. else
  1426. tran_size = left_size;
  1427. cmd_scsi_security_protocol_out(&cmd, tag, 1,
  1428. UFS_SECURITY_PROTOCOL,
  1429. RPMB_PROTOCOL_ID);
  1430. ret = ufshcd_rpmb_write_data_req_prepare(&cmd, (data_buf + i * RPMB_FRM_DATA_LEN), tran_size, wr_cnt, addr + i);
  1431. if (ret) {
  1432. UFS_DBG_LOGE("[%s]: RPMB Fail in prepare frame, ret = %d \n", __func__, ret);
  1433. goto exit;
  1434. }
  1435. ret = ufshcd_queuecommand(hba, &cmd);
  1436. if (ret) {
  1437. UFS_DBG_LOGE("[%s]: RPMB Fail in send write frame, ret = %d \n", __func__, ret);
  1438. goto exit;
  1439. }
  1440. /* Step 2. Result Register Read Request */
  1441. cmd_scsi_security_protocol_out(&cmd, tag, 1,
  1442. UFS_SECURITY_PROTOCOL,
  1443. RPMB_PROTOCOL_ID);
  1444. ufshcd_authen_result_read_req_prepare(&cmd);
  1445. ret = ufshcd_queuecommand(hba, &cmd);
  1446. if (ret) {
  1447. UFS_DBG_LOGE("[%s]: RPMB Fail in sending result register read request, ret = %d \n", __func__, ret);
  1448. goto exit;
  1449. }
  1450. /* Step3. Check Response for Result Read Request */
  1451. cmd_scsi_security_protocol_in(&cmd, tag, 1,
  1452. UFS_SECURITY_PROTOCOL,
  1453. RPMB_PROTOCOL_ID);
  1454. if ((ret = ufshcd_queuecommand(hba, &cmd))) {
  1455. UFS_DBG_LOGE("[%s]: RPMB Fail in sending request get result register response, ret = %d \n", __func__, ret);
  1456. goto exit;
  1457. }
  1458. /* Step3. Response frame check */
  1459. if ((ret = ufshcd_authen_data_write_rsp_check(host_id, &cmd, wr_cnt,
  1460. RPMB_RSP_AUTHEN_WRITE))) {
  1461. UFS_DBG_LOGE("[%s]: RPMB WriteCounter Read Resp Check Fail, ret = %d \n", __func__, ret);
  1462. goto exit;
  1463. }
  1464. left_size -= tran_size;
  1465. wr_cnt++;
  1466. }
  1467. exit:
  1468. ufshcd_put_tag(hba, tag);
  1469. free_nonce_buf:
  1470. return ret;
  1471. }
  1472. #endif //#if defined(MTK_UFS_DRV_LK)