OpalDriver.c 82 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970
  1. /** @file
  2. Entrypoint of Opal UEFI Driver and contains all the logic to
  3. register for new Opal device instances.
  4. Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. // This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an
  8. // HII GUI to manage Opal features if the device is Opal capable
  9. // If the Opal device is being managed by the UEFI Driver, it shall provide a popup
  10. // window during boot requesting a user password
  11. #include "OpalDriver.h"
  12. #include "OpalHii.h"
  13. EFI_GUID mOpalDeviceLockBoxGuid = OPAL_DEVICE_LOCKBOX_GUID;
  14. BOOLEAN mOpalEndOfDxe = FALSE;
  15. OPAL_REQUEST_VARIABLE *mOpalRequestVariable = NULL;
  16. UINTN mOpalRequestVariableSize = 0;
  17. CHAR16 mPopUpString[100];
  18. OPAL_DRIVER mOpalDriver;
  19. //
  20. // Globals
  21. //
  22. EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding = {
  23. OpalEfiDriverBindingSupported,
  24. OpalEfiDriverBindingStart,
  25. OpalEfiDriverBindingStop,
  26. 0x1b,
  27. NULL,
  28. NULL
  29. };
  30. /**
  31. The function determines the available actions for the OPAL_DISK provided.
  32. @param[in] SupportedAttributes The supported attributes for the device.
  33. @param[in] LockingFeature The locking status for the device.
  34. @param[in] OwnerShip The ownership for the device.
  35. @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.
  36. **/
  37. TCG_RESULT
  38. EFIAPI
  39. OpalSupportGetAvailableActions(
  40. IN OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,
  41. IN TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature,
  42. IN UINT16 OwnerShip,
  43. OUT OPAL_DISK_ACTIONS *AvalDiskActions
  44. )
  45. {
  46. BOOLEAN ExistingPassword;
  47. NULL_CHECK(AvalDiskActions);
  48. AvalDiskActions->AdminPass = 1;
  49. AvalDiskActions->UserPass = 0;
  50. AvalDiskActions->DisableUser = 0;
  51. AvalDiskActions->Unlock = 0;
  52. //
  53. // Revert is performed on locking sp, so only allow if locking sp is enabled
  54. //
  55. if (LockingFeature->LockingEnabled) {
  56. AvalDiskActions->Revert = 1;
  57. }
  58. //
  59. // Psid revert is available for any device with media encryption support or pyrite 2.0 type support.
  60. //
  61. if (SupportedAttributes->PyriteSscV2 || SupportedAttributes->MediaEncryption) {
  62. //
  63. // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..
  64. // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
  65. // intact and accessible
  66. //
  67. AvalDiskActions->PsidRevert = 1;
  68. AvalDiskActions->RevertKeepDataForced = 0;
  69. //
  70. // Secure erase is performed by generating a new encryption key
  71. // this is only available if encryption is supported
  72. //
  73. AvalDiskActions->SecureErase = 1;
  74. } else {
  75. AvalDiskActions->PsidRevert = 0;
  76. AvalDiskActions->SecureErase = 0;
  77. //
  78. // If no media encryption is supported, then a revert (using password) will not
  79. // erase the Data (since you can't generate a new encryption key)
  80. //
  81. AvalDiskActions->RevertKeepDataForced = 1;
  82. }
  83. if (LockingFeature->Locked) {
  84. AvalDiskActions->Unlock = 1;
  85. } else {
  86. AvalDiskActions->Unlock = 0;
  87. }
  88. //
  89. // Only allow user to set password if an admin password exists
  90. //
  91. ExistingPassword = OpalUtilAdminPasswordExists(OwnerShip, LockingFeature);
  92. AvalDiskActions->UserPass = ExistingPassword;
  93. //
  94. // This will still show up even if there isn't a user, which is fine
  95. //
  96. AvalDiskActions->DisableUser = ExistingPassword;
  97. return TcgResultSuccess;
  98. }
  99. /**
  100. Enable Opal Feature for the input device.
  101. @param[in] Session The opal session for the opal device.
  102. @param[in] Msid Msid
  103. @param[in] MsidLength Msid Length
  104. @param[in] Password Admin password
  105. @param[in] PassLength Length of password in bytes
  106. **/
  107. TCG_RESULT
  108. EFIAPI
  109. OpalSupportEnableOpalFeature (
  110. IN OPAL_SESSION *Session,
  111. IN VOID *Msid,
  112. IN UINT32 MsidLength,
  113. IN VOID *Password,
  114. IN UINT32 PassLength
  115. )
  116. {
  117. TCG_RESULT Ret;
  118. NULL_CHECK(Session);
  119. NULL_CHECK(Msid);
  120. NULL_CHECK(Password);
  121. Ret = OpalUtilSetAdminPasswordAsSid(
  122. Session,
  123. Msid,
  124. MsidLength,
  125. Password,
  126. PassLength
  127. );
  128. if (Ret == TcgResultSuccess) {
  129. //
  130. // Enable global locking range
  131. //
  132. Ret = OpalUtilSetOpalLockingRange(
  133. Session,
  134. Password,
  135. PassLength,
  136. OPAL_LOCKING_SP_LOCKING_GLOBALRANGE,
  137. 0,
  138. 0,
  139. TRUE,
  140. TRUE,
  141. FALSE,
  142. FALSE
  143. );
  144. }
  145. return Ret;
  146. }
  147. /**
  148. Update password for the Opal disk.
  149. @param[in, out] OpalDisk The disk to update password.
  150. @param[in] Password The input password.
  151. @param[in] PasswordLength The input password length.
  152. **/
  153. VOID
  154. OpalSupportUpdatePassword (
  155. IN OUT OPAL_DISK *OpalDisk,
  156. IN VOID *Password,
  157. IN UINT32 PasswordLength
  158. )
  159. {
  160. CopyMem (OpalDisk->Password, Password, PasswordLength);
  161. OpalDisk->PasswordLength = (UINT8) PasswordLength;
  162. }
  163. /**
  164. Extract device info from the device path.
  165. @param[in] DevicePath Device path info for the device.
  166. @param[out] DevInfoLength Device information length needed.
  167. @param[out] DevInfo Device information extracted.
  168. **/
  169. VOID
  170. ExtractDeviceInfoFromDevicePath (
  171. IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
  172. OUT UINT32 *DevInfoLength,
  173. OUT OPAL_DEVICE_LOCKBOX_DATA *DevInfo OPTIONAL
  174. )
  175. {
  176. EFI_DEVICE_PATH_PROTOCOL *TmpDevPath;
  177. EFI_DEVICE_PATH_PROTOCOL *TmpDevPath2;
  178. PCI_DEVICE_PATH *PciDevPath;
  179. UINT8 DeviceType;
  180. UINT8 BusNum;
  181. OPAL_PCI_DEVICE *PciDevice;
  182. ASSERT (DevicePath != NULL);
  183. ASSERT (DevInfoLength != NULL);
  184. DeviceType = OPAL_DEVICE_TYPE_UNKNOWN;
  185. *DevInfoLength = 0;
  186. TmpDevPath = DevicePath;
  187. //
  188. // Get device type.
  189. //
  190. while (!IsDevicePathEnd (TmpDevPath)) {
  191. if ((TmpDevPath->Type == MESSAGING_DEVICE_PATH) &&
  192. (TmpDevPath->SubType == MSG_SATA_DP || TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP)) {
  193. if (DevInfo != NULL) {
  194. DevInfo->DevicePathLength = (UINT32) GetDevicePathSize (DevicePath);
  195. CopyMem (DevInfo->DevicePath, DevicePath, DevInfo->DevicePathLength);
  196. }
  197. DeviceType = (TmpDevPath->SubType == MSG_SATA_DP) ? OPAL_DEVICE_TYPE_ATA : OPAL_DEVICE_TYPE_NVME;
  198. *DevInfoLength = sizeof (OPAL_DEVICE_LOCKBOX_DATA) + (UINT32) GetDevicePathSize (DevicePath);
  199. break;
  200. }
  201. TmpDevPath = NextDevicePathNode (TmpDevPath);
  202. }
  203. //
  204. // Get device info.
  205. //
  206. BusNum = 0;
  207. TmpDevPath = DevicePath;
  208. TmpDevPath2 = NextDevicePathNode (DevicePath);
  209. while (!IsDevicePathEnd (TmpDevPath2)) {
  210. if (TmpDevPath->Type == HARDWARE_DEVICE_PATH && TmpDevPath->SubType == HW_PCI_DP) {
  211. PciDevPath = (PCI_DEVICE_PATH *) TmpDevPath;
  212. if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH) &&
  213. (TmpDevPath2->SubType == MSG_SATA_DP || TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)) {
  214. if (DevInfo != NULL) {
  215. PciDevice = &DevInfo->Device;
  216. PciDevice->Segment = 0;
  217. PciDevice->Bus = BusNum;
  218. PciDevice->Device = PciDevPath->Device;
  219. PciDevice->Function = PciDevPath->Function;
  220. }
  221. } else {
  222. if (TmpDevPath2->Type == HARDWARE_DEVICE_PATH && TmpDevPath2->SubType == HW_PCI_DP) {
  223. BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath->Device, PciDevPath->Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
  224. }
  225. }
  226. }
  227. TmpDevPath = NextDevicePathNode (TmpDevPath);
  228. TmpDevPath2 = NextDevicePathNode (TmpDevPath2);
  229. }
  230. ASSERT (DeviceType != OPAL_DEVICE_TYPE_UNKNOWN);
  231. return;
  232. }
  233. /**
  234. Build OPAL device info and save them to LockBox.
  235. **/
  236. VOID
  237. BuildOpalDeviceInfo (
  238. VOID
  239. )
  240. {
  241. EFI_STATUS Status;
  242. OPAL_DEVICE_LOCKBOX_DATA *DevInfo;
  243. OPAL_DEVICE_LOCKBOX_DATA *TempDevInfo;
  244. UINTN TotalDevInfoLength;
  245. UINT32 DevInfoLength;
  246. OPAL_DRIVER_DEVICE *TmpDev;
  247. UINT8 DummyData;
  248. BOOLEAN S3InitDevicesExist;
  249. UINTN S3InitDevicesLength;
  250. EFI_DEVICE_PATH_PROTOCOL *S3InitDevices;
  251. EFI_DEVICE_PATH_PROTOCOL *S3InitDevicesBak;
  252. //
  253. // Build OPAL device info and save them to LockBox.
  254. //
  255. TotalDevInfoLength = 0;
  256. TmpDev = mOpalDriver.DeviceList;
  257. while (TmpDev != NULL) {
  258. ExtractDeviceInfoFromDevicePath (
  259. TmpDev->OpalDisk.OpalDevicePath,
  260. &DevInfoLength,
  261. NULL
  262. );
  263. TotalDevInfoLength += DevInfoLength;
  264. TmpDev = TmpDev->Next;
  265. }
  266. if (TotalDevInfoLength == 0) {
  267. return;
  268. }
  269. S3InitDevicesLength = sizeof (DummyData);
  270. Status = RestoreLockBox (
  271. &gS3StorageDeviceInitListGuid,
  272. &DummyData,
  273. &S3InitDevicesLength
  274. );
  275. ASSERT ((Status == EFI_NOT_FOUND) || (Status == EFI_BUFFER_TOO_SMALL));
  276. if (Status == EFI_NOT_FOUND) {
  277. S3InitDevices = NULL;
  278. S3InitDevicesExist = FALSE;
  279. } else if (Status == EFI_BUFFER_TOO_SMALL) {
  280. S3InitDevices = AllocatePool (S3InitDevicesLength);
  281. ASSERT (S3InitDevices != NULL);
  282. if (S3InitDevices == NULL) {
  283. return;
  284. }
  285. Status = RestoreLockBox (
  286. &gS3StorageDeviceInitListGuid,
  287. S3InitDevices,
  288. &S3InitDevicesLength
  289. );
  290. ASSERT_EFI_ERROR (Status);
  291. S3InitDevicesExist = TRUE;
  292. } else {
  293. return;
  294. }
  295. DevInfo = AllocateZeroPool (TotalDevInfoLength);
  296. ASSERT (DevInfo != NULL);
  297. if (DevInfo == NULL) {
  298. return;
  299. }
  300. TempDevInfo = DevInfo;
  301. TmpDev = mOpalDriver.DeviceList;
  302. while (TmpDev != NULL) {
  303. ExtractDeviceInfoFromDevicePath (
  304. TmpDev->OpalDisk.OpalDevicePath,
  305. &DevInfoLength,
  306. TempDevInfo
  307. );
  308. TempDevInfo->Length = DevInfoLength;
  309. TempDevInfo->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId;
  310. CopyMem (
  311. TempDevInfo->Password,
  312. TmpDev->OpalDisk.Password,
  313. TmpDev->OpalDisk.PasswordLength
  314. );
  315. TempDevInfo->PasswordLength = TmpDev->OpalDisk.PasswordLength;
  316. S3InitDevicesBak = S3InitDevices;
  317. S3InitDevices = AppendDevicePathInstance (
  318. S3InitDevicesBak,
  319. TmpDev->OpalDisk.OpalDevicePath
  320. );
  321. if (S3InitDevicesBak != NULL) {
  322. FreePool (S3InitDevicesBak);
  323. }
  324. ASSERT (S3InitDevices != NULL);
  325. if (S3InitDevices == NULL) {
  326. return;
  327. }
  328. TempDevInfo = (OPAL_DEVICE_LOCKBOX_DATA *) ((UINTN) TempDevInfo + DevInfoLength);
  329. TmpDev = TmpDev->Next;
  330. }
  331. Status = SaveLockBox (
  332. &mOpalDeviceLockBoxGuid,
  333. DevInfo,
  334. TotalDevInfoLength
  335. );
  336. ASSERT_EFI_ERROR (Status);
  337. Status = SetLockBoxAttributes (
  338. &mOpalDeviceLockBoxGuid,
  339. LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
  340. );
  341. ASSERT_EFI_ERROR (Status);
  342. S3InitDevicesLength = GetDevicePathSize (S3InitDevices);
  343. if (S3InitDevicesExist) {
  344. Status = UpdateLockBox (
  345. &gS3StorageDeviceInitListGuid,
  346. 0,
  347. S3InitDevices,
  348. S3InitDevicesLength
  349. );
  350. ASSERT_EFI_ERROR (Status);
  351. } else {
  352. Status = SaveLockBox (
  353. &gS3StorageDeviceInitListGuid,
  354. S3InitDevices,
  355. S3InitDevicesLength
  356. );
  357. ASSERT_EFI_ERROR (Status);
  358. Status = SetLockBoxAttributes (
  359. &gS3StorageDeviceInitListGuid,
  360. LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
  361. );
  362. ASSERT_EFI_ERROR (Status);
  363. }
  364. ZeroMem (DevInfo, TotalDevInfoLength);
  365. FreePool (DevInfo);
  366. FreePool (S3InitDevices);
  367. }
  368. /**
  369. Send BlockSid command if needed.
  370. **/
  371. VOID
  372. SendBlockSidCommand (
  373. VOID
  374. )
  375. {
  376. OPAL_DRIVER_DEVICE *Itr;
  377. TCG_RESULT Result;
  378. OPAL_SESSION Session;
  379. UINT32 PpStorageFlag;
  380. PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();
  381. if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {
  382. //
  383. // Send BlockSID command to each Opal disk
  384. //
  385. Itr = mOpalDriver.DeviceList;
  386. while (Itr != NULL) {
  387. if (Itr->OpalDisk.SupportedAttributes.BlockSid) {
  388. ZeroMem(&Session, sizeof(Session));
  389. Session.Sscp = Itr->OpalDisk.Sscp;
  390. Session.MediaId = Itr->OpalDisk.MediaId;
  391. Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId;
  392. DEBUG ((DEBUG_INFO, "OpalPassword: EndOfDxe point, send BlockSid command to device!\n"));
  393. Result = OpalBlockSid (&Session, TRUE); // HardwareReset must always be TRUE
  394. if (Result != TcgResultSuccess) {
  395. DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n"));
  396. break;
  397. }
  398. //
  399. // Record BlockSID command has been sent.
  400. //
  401. Itr->OpalDisk.SentBlockSID = TRUE;
  402. }
  403. Itr = Itr->Next;
  404. }
  405. }
  406. }
  407. /**
  408. Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
  409. This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
  410. @param Event Event whose notification function is being invoked.
  411. @param Context Pointer to the notification function's context.
  412. **/
  413. VOID
  414. EFIAPI
  415. OpalEndOfDxeEventNotify (
  416. EFI_EVENT Event,
  417. VOID *Context
  418. )
  419. {
  420. OPAL_DRIVER_DEVICE *TmpDev;
  421. DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));
  422. mOpalEndOfDxe = TRUE;
  423. if (mOpalRequestVariable != NULL) {
  424. //
  425. // Free the OPAL request variable buffer here
  426. // as the OPAL requests should have been processed.
  427. //
  428. FreePool (mOpalRequestVariable);
  429. mOpalRequestVariable = NULL;
  430. mOpalRequestVariableSize = 0;
  431. }
  432. //
  433. // If no any device, return directly.
  434. //
  435. if (mOpalDriver.DeviceList == NULL) {
  436. gBS->CloseEvent (Event);
  437. return;
  438. }
  439. BuildOpalDeviceInfo ();
  440. //
  441. // Zero passsword.
  442. //
  443. TmpDev = mOpalDriver.DeviceList;
  444. while (TmpDev != NULL) {
  445. ZeroMem (TmpDev->OpalDisk.Password, TmpDev->OpalDisk.PasswordLength);
  446. TmpDev = TmpDev->Next;
  447. }
  448. //
  449. // Send BlockSid command if needed.
  450. //
  451. SendBlockSidCommand ();
  452. DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));
  453. gBS->CloseEvent (Event);
  454. }
  455. /**
  456. Get Psid input from the popup window.
  457. @param[in] Dev The device which need Psid to process Psid Revert
  458. OPAL request.
  459. @param[in] PopUpString Pop up string.
  460. @param[in] PopUpString2 Pop up string in line 2.
  461. @param[in] PopUpString3 Pop up string in line 3.
  462. @param[out] PressEsc Whether user escape function through Press ESC.
  463. @retval Psid string if success. NULL if failed.
  464. **/
  465. CHAR8 *
  466. OpalDriverPopUpPsidInput (
  467. IN OPAL_DRIVER_DEVICE *Dev,
  468. IN CHAR16 *PopUpString,
  469. IN CHAR16 *PopUpString2,
  470. IN CHAR16 *PopUpString3,
  471. OUT BOOLEAN *PressEsc
  472. )
  473. {
  474. EFI_INPUT_KEY InputKey;
  475. UINTN InputLength;
  476. CHAR16 Mask[PSID_CHARACTER_LENGTH + 1];
  477. CHAR16 Unicode[PSID_CHARACTER_LENGTH + 1];
  478. CHAR8 *Ascii;
  479. ZeroMem(Unicode, sizeof(Unicode));
  480. ZeroMem(Mask, sizeof(Mask));
  481. *PressEsc = FALSE;
  482. gST->ConOut->ClearScreen(gST->ConOut);
  483. InputLength = 0;
  484. while (TRUE) {
  485. Mask[InputLength] = L'_';
  486. if (PopUpString2 == NULL) {
  487. CreatePopUp (
  488. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  489. &InputKey,
  490. PopUpString,
  491. L"---------------------",
  492. Mask,
  493. NULL
  494. );
  495. } else {
  496. if (PopUpString3 == NULL) {
  497. CreatePopUp (
  498. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  499. &InputKey,
  500. PopUpString,
  501. PopUpString2,
  502. L"---------------------",
  503. Mask,
  504. NULL
  505. );
  506. } else {
  507. CreatePopUp (
  508. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  509. &InputKey,
  510. PopUpString,
  511. PopUpString2,
  512. PopUpString3,
  513. L"---------------------",
  514. Mask,
  515. NULL
  516. );
  517. }
  518. }
  519. //
  520. // Check key.
  521. //
  522. if (InputKey.ScanCode == SCAN_NULL) {
  523. //
  524. // password finished
  525. //
  526. if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  527. //
  528. // Add the null terminator.
  529. //
  530. Unicode[InputLength] = 0;
  531. Mask[InputLength] = 0;
  532. break;
  533. } else if ((InputKey.UnicodeChar == CHAR_NULL) ||
  534. (InputKey.UnicodeChar == CHAR_TAB) ||
  535. (InputKey.UnicodeChar == CHAR_LINEFEED)
  536. ) {
  537. continue;
  538. } else {
  539. //
  540. // delete last key entered
  541. //
  542. if (InputKey.UnicodeChar == CHAR_BACKSPACE) {
  543. if (InputLength > 0) {
  544. Unicode[InputLength] = 0;
  545. Mask[InputLength] = 0;
  546. InputLength--;
  547. }
  548. } else {
  549. //
  550. // add Next key entry
  551. //
  552. Unicode[InputLength] = InputKey.UnicodeChar;
  553. Mask[InputLength] = InputKey.UnicodeChar;
  554. InputLength++;
  555. if (InputLength == PSID_CHARACTER_LENGTH) {
  556. //
  557. // Add the null terminator.
  558. //
  559. Unicode[InputLength] = 0;
  560. Mask[InputLength] = 0;
  561. break;
  562. }
  563. }
  564. }
  565. }
  566. //
  567. // exit on ESC
  568. //
  569. if (InputKey.ScanCode == SCAN_ESC) {
  570. *PressEsc = TRUE;
  571. break;
  572. }
  573. }
  574. gST->ConOut->ClearScreen(gST->ConOut);
  575. if (InputLength == 0 || InputKey.ScanCode == SCAN_ESC) {
  576. ZeroMem (Unicode, sizeof (Unicode));
  577. ZeroMem (Mask, sizeof (Mask));
  578. return NULL;
  579. }
  580. Ascii = AllocateZeroPool (PSID_CHARACTER_LENGTH + 1);
  581. if (Ascii == NULL) {
  582. ZeroMem (Unicode, sizeof (Unicode));
  583. ZeroMem (Mask, sizeof (Mask));
  584. return NULL;
  585. }
  586. UnicodeStrToAsciiStrS (Unicode, Ascii, PSID_CHARACTER_LENGTH + 1);
  587. ZeroMem (Unicode, sizeof (Unicode));
  588. ZeroMem (Mask, sizeof (Mask));
  589. return Ascii;
  590. }
  591. /**
  592. Get password input from the popup window.
  593. @param[in] Dev The device which need password to unlock or
  594. process OPAL request.
  595. @param[in] PopUpString1 Pop up string 1.
  596. @param[in] PopUpString2 Pop up string 2.
  597. @param[in] PopUpString3 Pop up string 3.
  598. @param[out] PressEsc Whether user escape function through Press ESC.
  599. @retval Password string if success. NULL if failed.
  600. **/
  601. CHAR8 *
  602. OpalDriverPopUpPasswordInput (
  603. IN OPAL_DRIVER_DEVICE *Dev,
  604. IN CHAR16 *PopUpString1,
  605. IN CHAR16 *PopUpString2,
  606. IN CHAR16 *PopUpString3,
  607. OUT BOOLEAN *PressEsc
  608. )
  609. {
  610. EFI_INPUT_KEY InputKey;
  611. UINTN InputLength;
  612. CHAR16 Mask[OPAL_MAX_PASSWORD_SIZE + 1];
  613. CHAR16 Unicode[OPAL_MAX_PASSWORD_SIZE + 1];
  614. CHAR8 *Ascii;
  615. ZeroMem(Unicode, sizeof(Unicode));
  616. ZeroMem(Mask, sizeof(Mask));
  617. *PressEsc = FALSE;
  618. gST->ConOut->ClearScreen(gST->ConOut);
  619. InputLength = 0;
  620. while (TRUE) {
  621. Mask[InputLength] = L'_';
  622. if (PopUpString2 == NULL) {
  623. CreatePopUp (
  624. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  625. &InputKey,
  626. PopUpString1,
  627. L"---------------------",
  628. Mask,
  629. NULL
  630. );
  631. } else {
  632. if (PopUpString3 == NULL) {
  633. CreatePopUp (
  634. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  635. &InputKey,
  636. PopUpString1,
  637. PopUpString2,
  638. L"---------------------",
  639. Mask,
  640. NULL
  641. );
  642. } else {
  643. CreatePopUp (
  644. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  645. &InputKey,
  646. PopUpString1,
  647. PopUpString2,
  648. PopUpString3,
  649. L"---------------------",
  650. Mask,
  651. NULL
  652. );
  653. }
  654. }
  655. //
  656. // Check key.
  657. //
  658. if (InputKey.ScanCode == SCAN_NULL) {
  659. //
  660. // password finished
  661. //
  662. if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  663. //
  664. // Add the null terminator.
  665. //
  666. Unicode[InputLength] = 0;
  667. Mask[InputLength] = 0;
  668. break;
  669. } else if ((InputKey.UnicodeChar == CHAR_NULL) ||
  670. (InputKey.UnicodeChar == CHAR_TAB) ||
  671. (InputKey.UnicodeChar == CHAR_LINEFEED)
  672. ) {
  673. continue;
  674. } else {
  675. //
  676. // delete last key entered
  677. //
  678. if (InputKey.UnicodeChar == CHAR_BACKSPACE) {
  679. if (InputLength > 0) {
  680. Unicode[InputLength] = 0;
  681. Mask[InputLength] = 0;
  682. InputLength--;
  683. }
  684. } else {
  685. //
  686. // add Next key entry
  687. //
  688. Unicode[InputLength] = InputKey.UnicodeChar;
  689. Mask[InputLength] = L'*';
  690. InputLength++;
  691. if (InputLength == OPAL_MAX_PASSWORD_SIZE) {
  692. //
  693. // Add the null terminator.
  694. //
  695. Unicode[InputLength] = 0;
  696. Mask[InputLength] = 0;
  697. break;
  698. }
  699. }
  700. }
  701. }
  702. //
  703. // exit on ESC
  704. //
  705. if (InputKey.ScanCode == SCAN_ESC) {
  706. *PressEsc = TRUE;
  707. break;
  708. }
  709. }
  710. gST->ConOut->ClearScreen(gST->ConOut);
  711. if (InputLength == 0 || InputKey.ScanCode == SCAN_ESC) {
  712. ZeroMem (Unicode, sizeof (Unicode));
  713. return NULL;
  714. }
  715. Ascii = AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE + 1);
  716. if (Ascii == NULL) {
  717. ZeroMem (Unicode, sizeof (Unicode));
  718. return NULL;
  719. }
  720. UnicodeStrToAsciiStrS (Unicode, Ascii, OPAL_MAX_PASSWORD_SIZE + 1);
  721. ZeroMem (Unicode, sizeof (Unicode));
  722. return Ascii;
  723. }
  724. /**
  725. Get pop up string.
  726. @param[in] Dev The OPAL device.
  727. @param[in] RequestString Request string.
  728. @return Pop up string.
  729. **/
  730. CHAR16 *
  731. OpalGetPopUpString (
  732. IN OPAL_DRIVER_DEVICE *Dev,
  733. IN CHAR16 *RequestString
  734. )
  735. {
  736. if (Dev->Name16 == NULL) {
  737. UnicodeSPrint (mPopUpString, sizeof (mPopUpString), L"%s Disk", RequestString);
  738. } else {
  739. UnicodeSPrint (mPopUpString, sizeof (mPopUpString), L"%s %s", RequestString, Dev->Name16);
  740. }
  741. return mPopUpString;
  742. }
  743. /**
  744. Check if disk is locked, show popup window and ask for password if it is.
  745. @param[in] Dev The device which need to be unlocked.
  746. @param[in] RequestString Request string.
  747. **/
  748. VOID
  749. OpalDriverRequestPassword (
  750. IN OPAL_DRIVER_DEVICE *Dev,
  751. IN CHAR16 *RequestString
  752. )
  753. {
  754. UINT8 Count;
  755. BOOLEAN IsEnabled;
  756. BOOLEAN IsLocked;
  757. CHAR8 *Password;
  758. UINT32 PasswordLen;
  759. OPAL_SESSION Session;
  760. BOOLEAN PressEsc;
  761. EFI_INPUT_KEY Key;
  762. TCG_RESULT Ret;
  763. CHAR16 *PopUpString;
  764. if (Dev == NULL) {
  765. return;
  766. }
  767. DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
  768. PopUpString = OpalGetPopUpString (Dev, RequestString);
  769. Count = 0;
  770. IsEnabled = OpalFeatureEnabled (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);
  771. if (IsEnabled) {
  772. ZeroMem(&Session, sizeof(Session));
  773. Session.Sscp = Dev->OpalDisk.Sscp;
  774. Session.MediaId = Dev->OpalDisk.MediaId;
  775. Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
  776. IsLocked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);
  777. if (IsLocked && PcdGetBool (PcdSkipOpalDxeUnlock)) {
  778. return;
  779. }
  780. while (Count < MAX_PASSWORD_TRY_COUNT) {
  781. Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);
  782. if (PressEsc) {
  783. if (IsLocked) {
  784. //
  785. // Current device in the lock status and
  786. // User not input password and press ESC,
  787. // keep device in lock status and continue boot.
  788. //
  789. do {
  790. CreatePopUp (
  791. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  792. &Key,
  793. L"Press ENTER to skip the request and continue boot,",
  794. L"Press ESC to input password again",
  795. NULL
  796. );
  797. } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
  798. if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  799. gST->ConOut->ClearScreen(gST->ConOut);
  800. //
  801. // Keep lock and continue boot.
  802. //
  803. return;
  804. } else {
  805. //
  806. // Let user input password again.
  807. //
  808. continue;
  809. }
  810. } else {
  811. //
  812. // Current device in the unlock status and
  813. // User not input password and press ESC,
  814. // Shutdown the device.
  815. //
  816. do {
  817. CreatePopUp (
  818. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  819. &Key,
  820. L"Press ENTER to shutdown, Press ESC to input password again",
  821. NULL
  822. );
  823. } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
  824. if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  825. gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
  826. } else {
  827. //
  828. // Let user input password again.
  829. //
  830. continue;
  831. }
  832. }
  833. }
  834. if (Password == NULL) {
  835. Count ++;
  836. continue;
  837. }
  838. PasswordLen = (UINT32) AsciiStrLen(Password);
  839. if (IsLocked) {
  840. Ret = OpalUtilUpdateGlobalLockingRange(&Session, Password, PasswordLen, FALSE, FALSE);
  841. } else {
  842. Ret = OpalUtilUpdateGlobalLockingRange(&Session, Password, PasswordLen, TRUE, TRUE);
  843. if (Ret == TcgResultSuccess) {
  844. Ret = OpalUtilUpdateGlobalLockingRange(&Session, Password, PasswordLen, FALSE, FALSE);
  845. }
  846. }
  847. if (Ret == TcgResultSuccess) {
  848. OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
  849. DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
  850. } else {
  851. DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
  852. }
  853. if (Password != NULL) {
  854. ZeroMem (Password, PasswordLen);
  855. FreePool (Password);
  856. }
  857. if (Ret == TcgResultSuccess) {
  858. break;
  859. }
  860. //
  861. // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
  862. // before accept new password.
  863. //
  864. if (Ret == TcgResultFailureInvalidType) {
  865. Count = MAX_PASSWORD_TRY_COUNT;
  866. break;
  867. }
  868. Count++;
  869. do {
  870. CreatePopUp (
  871. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  872. &Key,
  873. L"Invalid password.",
  874. L"Press ENTER to retry",
  875. NULL
  876. );
  877. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  878. }
  879. if (Count >= MAX_PASSWORD_TRY_COUNT) {
  880. do {
  881. CreatePopUp (
  882. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  883. &Key,
  884. L"Opal password retry count exceeds the limit. Must shutdown!",
  885. L"Press ENTER to shutdown",
  886. NULL
  887. );
  888. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  889. gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
  890. }
  891. }
  892. }
  893. /**
  894. Process Enable Feature OPAL request.
  895. @param[in] Dev The device which has Enable Feature OPAL request.
  896. @param[in] RequestString Request string.
  897. **/
  898. VOID
  899. ProcessOpalRequestEnableFeature (
  900. IN OPAL_DRIVER_DEVICE *Dev,
  901. IN CHAR16 *RequestString
  902. )
  903. {
  904. UINT8 Count;
  905. CHAR8 *Password;
  906. UINT32 PasswordLen;
  907. CHAR8 *PasswordConfirm;
  908. UINT32 PasswordLenConfirm;
  909. OPAL_SESSION Session;
  910. BOOLEAN PressEsc;
  911. EFI_INPUT_KEY Key;
  912. TCG_RESULT Ret;
  913. CHAR16 *PopUpString;
  914. if (Dev == NULL) {
  915. return;
  916. }
  917. DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
  918. PopUpString = OpalGetPopUpString (Dev, RequestString);
  919. Count = 0;
  920. ZeroMem(&Session, sizeof(Session));
  921. Session.Sscp = Dev->OpalDisk.Sscp;
  922. Session.MediaId = Dev->OpalDisk.MediaId;
  923. Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
  924. while (Count < MAX_PASSWORD_TRY_COUNT) {
  925. Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);
  926. if (PressEsc) {
  927. do {
  928. CreatePopUp (
  929. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  930. &Key,
  931. L"Press ENTER to skip the request and continue boot,",
  932. L"Press ESC to input password again",
  933. NULL
  934. );
  935. } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
  936. if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  937. gST->ConOut->ClearScreen(gST->ConOut);
  938. return;
  939. } else {
  940. //
  941. // Let user input password again.
  942. //
  943. continue;
  944. }
  945. }
  946. if (Password == NULL) {
  947. Count ++;
  948. continue;
  949. }
  950. PasswordLen = (UINT32) AsciiStrLen(Password);
  951. PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);
  952. if (PasswordConfirm == NULL) {
  953. ZeroMem (Password, PasswordLen);
  954. FreePool (Password);
  955. Count ++;
  956. continue;
  957. }
  958. PasswordLenConfirm = (UINT32) AsciiStrLen(PasswordConfirm);
  959. if ((PasswordLen != PasswordLenConfirm) ||
  960. (CompareMem (Password, PasswordConfirm, PasswordLen) != 0)) {
  961. ZeroMem (Password, PasswordLen);
  962. FreePool (Password);
  963. ZeroMem (PasswordConfirm, PasswordLenConfirm);
  964. FreePool (PasswordConfirm);
  965. do {
  966. CreatePopUp (
  967. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  968. &Key,
  969. L"Passwords are not the same.",
  970. L"Press ENTER to retry",
  971. NULL
  972. );
  973. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  974. Count ++;
  975. continue;
  976. }
  977. if (PasswordConfirm != NULL) {
  978. ZeroMem (PasswordConfirm, PasswordLenConfirm);
  979. FreePool (PasswordConfirm);
  980. }
  981. Ret = OpalSupportEnableOpalFeature (&Session, Dev->OpalDisk.Msid, Dev->OpalDisk.MsidLength, Password, PasswordLen);
  982. if (Ret == TcgResultSuccess) {
  983. OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
  984. DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
  985. } else {
  986. DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
  987. }
  988. if (Password != NULL) {
  989. ZeroMem (Password, PasswordLen);
  990. FreePool (Password);
  991. }
  992. if (Ret == TcgResultSuccess) {
  993. break;
  994. }
  995. Count++;
  996. do {
  997. CreatePopUp (
  998. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  999. &Key,
  1000. L"Request failed.",
  1001. L"Press ENTER to retry",
  1002. NULL
  1003. );
  1004. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1005. }
  1006. if (Count >= MAX_PASSWORD_TRY_COUNT) {
  1007. do {
  1008. CreatePopUp (
  1009. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1010. &Key,
  1011. L"Opal password retry count exceeds the limit.",
  1012. L"Press ENTER to skip the request and continue boot",
  1013. NULL
  1014. );
  1015. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1016. gST->ConOut->ClearScreen(gST->ConOut);
  1017. }
  1018. }
  1019. /**
  1020. Process Disable User OPAL request.
  1021. @param[in] Dev The device which has Disable User OPAL request.
  1022. @param[in] RequestString Request string.
  1023. **/
  1024. VOID
  1025. ProcessOpalRequestDisableUser (
  1026. IN OPAL_DRIVER_DEVICE *Dev,
  1027. IN CHAR16 *RequestString
  1028. )
  1029. {
  1030. UINT8 Count;
  1031. CHAR8 *Password;
  1032. UINT32 PasswordLen;
  1033. OPAL_SESSION Session;
  1034. BOOLEAN PressEsc;
  1035. EFI_INPUT_KEY Key;
  1036. TCG_RESULT Ret;
  1037. BOOLEAN PasswordFailed;
  1038. CHAR16 *PopUpString;
  1039. if (Dev == NULL) {
  1040. return;
  1041. }
  1042. DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
  1043. PopUpString = OpalGetPopUpString (Dev, RequestString);
  1044. Count = 0;
  1045. ZeroMem(&Session, sizeof(Session));
  1046. Session.Sscp = Dev->OpalDisk.Sscp;
  1047. Session.MediaId = Dev->OpalDisk.MediaId;
  1048. Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
  1049. while (Count < MAX_PASSWORD_TRY_COUNT) {
  1050. Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);
  1051. if (PressEsc) {
  1052. do {
  1053. CreatePopUp (
  1054. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1055. &Key,
  1056. L"Press ENTER to skip the request and continue boot,",
  1057. L"Press ESC to input password again",
  1058. NULL
  1059. );
  1060. } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
  1061. if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  1062. gST->ConOut->ClearScreen(gST->ConOut);
  1063. return;
  1064. } else {
  1065. //
  1066. // Let user input password again.
  1067. //
  1068. continue;
  1069. }
  1070. }
  1071. if (Password == NULL) {
  1072. Count ++;
  1073. continue;
  1074. }
  1075. PasswordLen = (UINT32) AsciiStrLen(Password);
  1076. Ret = OpalUtilDisableUser(&Session, Password, PasswordLen, &PasswordFailed);
  1077. if (Ret == TcgResultSuccess) {
  1078. OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
  1079. DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
  1080. } else {
  1081. DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
  1082. }
  1083. if (Password != NULL) {
  1084. ZeroMem (Password, PasswordLen);
  1085. FreePool (Password);
  1086. }
  1087. if (Ret == TcgResultSuccess) {
  1088. break;
  1089. }
  1090. Count++;
  1091. do {
  1092. CreatePopUp (
  1093. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1094. &Key,
  1095. L"Invalid password, request failed.",
  1096. L"Press ENTER to retry",
  1097. NULL
  1098. );
  1099. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1100. }
  1101. if (Count >= MAX_PASSWORD_TRY_COUNT) {
  1102. do {
  1103. CreatePopUp (
  1104. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1105. &Key,
  1106. L"Opal password retry count exceeds the limit.",
  1107. L"Press ENTER to skip the request and continue boot",
  1108. NULL
  1109. );
  1110. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1111. gST->ConOut->ClearScreen(gST->ConOut);
  1112. }
  1113. }
  1114. /**
  1115. Process Psid Revert OPAL request.
  1116. @param[in] Dev The device which has Psid Revert OPAL request.
  1117. @param[in] RequestString Request string.
  1118. **/
  1119. VOID
  1120. ProcessOpalRequestPsidRevert (
  1121. IN OPAL_DRIVER_DEVICE *Dev,
  1122. IN CHAR16 *RequestString
  1123. )
  1124. {
  1125. UINT8 Count;
  1126. CHAR8 *Psid;
  1127. UINT32 PsidLen;
  1128. OPAL_SESSION Session;
  1129. BOOLEAN PressEsc;
  1130. EFI_INPUT_KEY Key;
  1131. TCG_RESULT Ret;
  1132. CHAR16 *PopUpString;
  1133. CHAR16 *PopUpString2;
  1134. CHAR16 *PopUpString3;
  1135. UINTN BufferSize;
  1136. if (Dev == NULL) {
  1137. return;
  1138. }
  1139. DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
  1140. PopUpString = OpalGetPopUpString (Dev, RequestString);
  1141. if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {
  1142. BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");
  1143. PopUpString2 = AllocateZeroPool (BufferSize);
  1144. ASSERT (PopUpString2 != NULL);
  1145. UnicodeSPrint (
  1146. PopUpString2,
  1147. BufferSize,
  1148. L"WARNING: Revert action will take about %d seconds",
  1149. Dev->OpalDisk.EstimateTimeCost
  1150. );
  1151. PopUpString3 = L"DO NOT power off system during the revert action!";
  1152. } else {
  1153. PopUpString2 = NULL;
  1154. PopUpString3 = NULL;
  1155. }
  1156. Count = 0;
  1157. ZeroMem(&Session, sizeof(Session));
  1158. Session.Sscp = Dev->OpalDisk.Sscp;
  1159. Session.MediaId = Dev->OpalDisk.MediaId;
  1160. Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
  1161. while (Count < MAX_PSID_TRY_COUNT) {
  1162. Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);
  1163. if (PressEsc) {
  1164. do {
  1165. CreatePopUp (
  1166. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1167. &Key,
  1168. L"Press ENTER to skip the request and continue boot,",
  1169. L"Press ESC to input Psid again",
  1170. NULL
  1171. );
  1172. } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
  1173. if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  1174. gST->ConOut->ClearScreen(gST->ConOut);
  1175. goto Done;
  1176. } else {
  1177. //
  1178. // Let user input Psid again.
  1179. //
  1180. continue;
  1181. }
  1182. }
  1183. if (Psid == NULL) {
  1184. Count ++;
  1185. continue;
  1186. }
  1187. PsidLen = (UINT32) AsciiStrLen(Psid);
  1188. Ret = OpalUtilPsidRevert(&Session, Psid, PsidLen);
  1189. if (Ret == TcgResultSuccess) {
  1190. DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
  1191. } else {
  1192. DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
  1193. }
  1194. if (Psid != NULL) {
  1195. ZeroMem (Psid, PsidLen);
  1196. FreePool (Psid);
  1197. }
  1198. if (Ret == TcgResultSuccess) {
  1199. break;
  1200. }
  1201. Count++;
  1202. do {
  1203. CreatePopUp (
  1204. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1205. &Key,
  1206. L"Invalid Psid, request failed.",
  1207. L"Press ENTER to retry",
  1208. NULL
  1209. );
  1210. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1211. }
  1212. if (Count >= MAX_PSID_TRY_COUNT) {
  1213. do {
  1214. CreatePopUp (
  1215. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1216. &Key,
  1217. L"Opal Psid retry count exceeds the limit.",
  1218. L"Press ENTER to skip the request and continue boot",
  1219. NULL
  1220. );
  1221. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1222. gST->ConOut->ClearScreen(gST->ConOut);
  1223. }
  1224. Done:
  1225. if (PopUpString2 != NULL) {
  1226. FreePool (PopUpString2);
  1227. }
  1228. }
  1229. /**
  1230. Process Admin Revert OPAL request.
  1231. @param[in] Dev The device which has Revert OPAL request.
  1232. @param[in] KeepUserData Whether to keep user data or not.
  1233. @param[in] RequestString Request string.
  1234. **/
  1235. VOID
  1236. ProcessOpalRequestRevert (
  1237. IN OPAL_DRIVER_DEVICE *Dev,
  1238. IN BOOLEAN KeepUserData,
  1239. IN CHAR16 *RequestString
  1240. )
  1241. {
  1242. UINT8 Count;
  1243. CHAR8 *Password;
  1244. UINT32 PasswordLen;
  1245. OPAL_SESSION Session;
  1246. BOOLEAN PressEsc;
  1247. EFI_INPUT_KEY Key;
  1248. TCG_RESULT Ret;
  1249. BOOLEAN PasswordFailed;
  1250. CHAR16 *PopUpString;
  1251. CHAR16 *PopUpString2;
  1252. CHAR16 *PopUpString3;
  1253. UINTN BufferSize;
  1254. if (Dev == NULL) {
  1255. return;
  1256. }
  1257. DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
  1258. PopUpString = OpalGetPopUpString (Dev, RequestString);
  1259. if ((!KeepUserData) &&
  1260. (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME)) {
  1261. BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");
  1262. PopUpString2 = AllocateZeroPool (BufferSize);
  1263. ASSERT (PopUpString2 != NULL);
  1264. UnicodeSPrint (
  1265. PopUpString2,
  1266. BufferSize,
  1267. L"WARNING: Revert action will take about %d seconds",
  1268. Dev->OpalDisk.EstimateTimeCost
  1269. );
  1270. PopUpString3 = L"DO NOT power off system during the revert action!";
  1271. } else {
  1272. PopUpString2 = NULL;
  1273. PopUpString3 = NULL;
  1274. }
  1275. Count = 0;
  1276. ZeroMem(&Session, sizeof(Session));
  1277. Session.Sscp = Dev->OpalDisk.Sscp;
  1278. Session.MediaId = Dev->OpalDisk.MediaId;
  1279. Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
  1280. while (Count < MAX_PASSWORD_TRY_COUNT) {
  1281. Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);
  1282. if (PressEsc) {
  1283. do {
  1284. CreatePopUp (
  1285. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1286. &Key,
  1287. L"Press ENTER to skip the request and continue boot,",
  1288. L"Press ESC to input password again",
  1289. NULL
  1290. );
  1291. } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
  1292. if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  1293. gST->ConOut->ClearScreen(gST->ConOut);
  1294. goto Done;
  1295. } else {
  1296. //
  1297. // Let user input password again.
  1298. //
  1299. continue;
  1300. }
  1301. }
  1302. if (Password == NULL) {
  1303. Count ++;
  1304. continue;
  1305. }
  1306. PasswordLen = (UINT32) AsciiStrLen(Password);
  1307. if ((Dev->OpalDisk.SupportedAttributes.PyriteSsc == 1) &&
  1308. (Dev->OpalDisk.LockingFeature.MediaEncryption == 0)) {
  1309. //
  1310. // For pyrite type device which does not support media encryption,
  1311. // it does not accept "Keep User Data" parameter.
  1312. // So here hardcode a FALSE for this case.
  1313. //
  1314. Ret = OpalUtilRevert(
  1315. &Session,
  1316. FALSE,
  1317. Password,
  1318. PasswordLen,
  1319. &PasswordFailed,
  1320. Dev->OpalDisk.Msid,
  1321. Dev->OpalDisk.MsidLength
  1322. );
  1323. } else {
  1324. Ret = OpalUtilRevert(
  1325. &Session,
  1326. KeepUserData,
  1327. Password,
  1328. PasswordLen,
  1329. &PasswordFailed,
  1330. Dev->OpalDisk.Msid,
  1331. Dev->OpalDisk.MsidLength
  1332. );
  1333. }
  1334. if (Ret == TcgResultSuccess) {
  1335. OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
  1336. DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
  1337. } else {
  1338. DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
  1339. }
  1340. if (Password != NULL) {
  1341. ZeroMem (Password, PasswordLen);
  1342. FreePool (Password);
  1343. }
  1344. if (Ret == TcgResultSuccess) {
  1345. break;
  1346. }
  1347. Count++;
  1348. do {
  1349. CreatePopUp (
  1350. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1351. &Key,
  1352. L"Invalid password, request failed.",
  1353. L"Press ENTER to retry",
  1354. NULL
  1355. );
  1356. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1357. }
  1358. if (Count >= MAX_PASSWORD_TRY_COUNT) {
  1359. do {
  1360. CreatePopUp (
  1361. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1362. &Key,
  1363. L"Opal password retry count exceeds the limit.",
  1364. L"Press ENTER to skip the request and continue boot",
  1365. NULL
  1366. );
  1367. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1368. gST->ConOut->ClearScreen(gST->ConOut);
  1369. }
  1370. Done:
  1371. if (PopUpString2 != NULL) {
  1372. FreePool (PopUpString2);
  1373. }
  1374. }
  1375. /**
  1376. Process Secure Erase OPAL request.
  1377. @param[in] Dev The device which has Secure Erase OPAL request.
  1378. @param[in] RequestString Request string.
  1379. **/
  1380. VOID
  1381. ProcessOpalRequestSecureErase (
  1382. IN OPAL_DRIVER_DEVICE *Dev,
  1383. IN CHAR16 *RequestString
  1384. )
  1385. {
  1386. UINT8 Count;
  1387. CHAR8 *Password;
  1388. UINT32 PasswordLen;
  1389. OPAL_SESSION Session;
  1390. BOOLEAN PressEsc;
  1391. EFI_INPUT_KEY Key;
  1392. TCG_RESULT Ret;
  1393. BOOLEAN PasswordFailed;
  1394. CHAR16 *PopUpString;
  1395. CHAR16 *PopUpString2;
  1396. CHAR16 *PopUpString3;
  1397. UINTN BufferSize;
  1398. if (Dev == NULL) {
  1399. return;
  1400. }
  1401. DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
  1402. PopUpString = OpalGetPopUpString (Dev, RequestString);
  1403. if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {
  1404. BufferSize = StrSize (L"Warning: Secure erase action will take about ####### seconds");
  1405. PopUpString2 = AllocateZeroPool (BufferSize);
  1406. ASSERT (PopUpString2 != NULL);
  1407. UnicodeSPrint (
  1408. PopUpString2,
  1409. BufferSize,
  1410. L"WARNING: Secure erase action will take about %d seconds",
  1411. Dev->OpalDisk.EstimateTimeCost
  1412. );
  1413. PopUpString3 = L"DO NOT power off system during the action!";
  1414. } else {
  1415. PopUpString2 = NULL;
  1416. PopUpString3 = NULL;
  1417. }
  1418. Count = 0;
  1419. ZeroMem(&Session, sizeof(Session));
  1420. Session.Sscp = Dev->OpalDisk.Sscp;
  1421. Session.MediaId = Dev->OpalDisk.MediaId;
  1422. Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
  1423. while (Count < MAX_PASSWORD_TRY_COUNT) {
  1424. Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);
  1425. if (PressEsc) {
  1426. do {
  1427. CreatePopUp (
  1428. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1429. &Key,
  1430. L"Press ENTER to skip the request and continue boot,",
  1431. L"Press ESC to input password again",
  1432. NULL
  1433. );
  1434. } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
  1435. if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  1436. gST->ConOut->ClearScreen(gST->ConOut);
  1437. goto Done;
  1438. } else {
  1439. //
  1440. // Let user input password again.
  1441. //
  1442. continue;
  1443. }
  1444. }
  1445. if (Password == NULL) {
  1446. Count ++;
  1447. continue;
  1448. }
  1449. PasswordLen = (UINT32) AsciiStrLen(Password);
  1450. Ret = OpalUtilSecureErase(&Session, Password, PasswordLen, &PasswordFailed);
  1451. if (Ret == TcgResultSuccess) {
  1452. OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
  1453. DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
  1454. } else {
  1455. DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
  1456. }
  1457. if (Password != NULL) {
  1458. ZeroMem (Password, PasswordLen);
  1459. FreePool (Password);
  1460. }
  1461. if (Ret == TcgResultSuccess) {
  1462. break;
  1463. }
  1464. Count++;
  1465. do {
  1466. CreatePopUp (
  1467. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1468. &Key,
  1469. L"Invalid password, request failed.",
  1470. L"Press ENTER to retry",
  1471. NULL
  1472. );
  1473. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1474. }
  1475. if (Count >= MAX_PASSWORD_TRY_COUNT) {
  1476. do {
  1477. CreatePopUp (
  1478. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1479. &Key,
  1480. L"Opal password retry count exceeds the limit.",
  1481. L"Press ENTER to skip the request and continue boot",
  1482. NULL
  1483. );
  1484. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1485. gST->ConOut->ClearScreen(gST->ConOut);
  1486. }
  1487. Done:
  1488. if (PopUpString2 != NULL) {
  1489. FreePool (PopUpString2);
  1490. }
  1491. }
  1492. /**
  1493. Process Set Admin Pwd OPAL request.
  1494. @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
  1495. @param[in] RequestString Request string.
  1496. **/
  1497. VOID
  1498. ProcessOpalRequestSetUserPwd (
  1499. IN OPAL_DRIVER_DEVICE *Dev,
  1500. IN CHAR16 *RequestString
  1501. )
  1502. {
  1503. UINT8 Count;
  1504. CHAR8 *OldPassword;
  1505. UINT32 OldPasswordLen;
  1506. CHAR8 *Password;
  1507. UINT32 PasswordLen;
  1508. CHAR8 *PasswordConfirm;
  1509. UINT32 PasswordLenConfirm;
  1510. OPAL_SESSION Session;
  1511. BOOLEAN PressEsc;
  1512. EFI_INPUT_KEY Key;
  1513. TCG_RESULT Ret;
  1514. CHAR16 *PopUpString;
  1515. if (Dev == NULL) {
  1516. return;
  1517. }
  1518. DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
  1519. PopUpString = OpalGetPopUpString (Dev, RequestString);
  1520. Count = 0;
  1521. while (Count < MAX_PASSWORD_TRY_COUNT) {
  1522. OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);
  1523. if (PressEsc) {
  1524. do {
  1525. CreatePopUp (
  1526. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1527. &Key,
  1528. L"Press ENTER to skip the request and continue boot,",
  1529. L"Press ESC to input password again",
  1530. NULL
  1531. );
  1532. } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
  1533. if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  1534. gST->ConOut->ClearScreen(gST->ConOut);
  1535. return;
  1536. } else {
  1537. //
  1538. // Let user input password again.
  1539. //
  1540. continue;
  1541. }
  1542. }
  1543. if (OldPassword == NULL) {
  1544. Count ++;
  1545. continue;
  1546. }
  1547. OldPasswordLen = (UINT32) AsciiStrLen(OldPassword);
  1548. ZeroMem(&Session, sizeof(Session));
  1549. Session.Sscp = Dev->OpalDisk.Sscp;
  1550. Session.MediaId = Dev->OpalDisk.MediaId;
  1551. Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
  1552. Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_USER1_AUTHORITY);
  1553. if (Ret == TcgResultSuccess) {
  1554. DEBUG ((DEBUG_INFO, "Verify with USER1 authority : Success\n"));
  1555. } else {
  1556. Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);
  1557. if (Ret == TcgResultSuccess) {
  1558. DEBUG ((DEBUG_INFO, "Verify with ADMIN1 authority: Success\n"));
  1559. } else {
  1560. ZeroMem (OldPassword, OldPasswordLen);
  1561. FreePool (OldPassword);
  1562. DEBUG ((DEBUG_INFO, "Verify: Failure\n"));
  1563. do {
  1564. CreatePopUp (
  1565. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1566. &Key,
  1567. L"Incorrect password.",
  1568. L"Press ENTER to retry",
  1569. NULL
  1570. );
  1571. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1572. Count ++;
  1573. continue;
  1574. }
  1575. }
  1576. Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);
  1577. if (Password == NULL) {
  1578. ZeroMem (OldPassword, OldPasswordLen);
  1579. FreePool (OldPassword);
  1580. Count ++;
  1581. continue;
  1582. }
  1583. PasswordLen = (UINT32) AsciiStrLen(Password);
  1584. PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);
  1585. if (PasswordConfirm == NULL) {
  1586. ZeroMem (OldPassword, OldPasswordLen);
  1587. FreePool (OldPassword);
  1588. ZeroMem (Password, PasswordLen);
  1589. FreePool (Password);
  1590. Count ++;
  1591. continue;
  1592. }
  1593. PasswordLenConfirm = (UINT32) AsciiStrLen(PasswordConfirm);
  1594. if ((PasswordLen != PasswordLenConfirm) ||
  1595. (CompareMem (Password, PasswordConfirm, PasswordLen) != 0)) {
  1596. ZeroMem (OldPassword, OldPasswordLen);
  1597. FreePool (OldPassword);
  1598. ZeroMem (Password, PasswordLen);
  1599. FreePool (Password);
  1600. ZeroMem (PasswordConfirm, PasswordLenConfirm);
  1601. FreePool (PasswordConfirm);
  1602. do {
  1603. CreatePopUp (
  1604. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1605. &Key,
  1606. L"Passwords are not the same.",
  1607. L"Press ENTER to retry",
  1608. NULL
  1609. );
  1610. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1611. Count ++;
  1612. continue;
  1613. }
  1614. if (PasswordConfirm != NULL) {
  1615. ZeroMem (PasswordConfirm, PasswordLenConfirm);
  1616. FreePool (PasswordConfirm);
  1617. }
  1618. ZeroMem(&Session, sizeof(Session));
  1619. Session.Sscp = Dev->OpalDisk.Sscp;
  1620. Session.MediaId = Dev->OpalDisk.MediaId;
  1621. Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
  1622. Ret = OpalUtilSetUserPassword(
  1623. &Session,
  1624. OldPassword,
  1625. OldPasswordLen,
  1626. Password,
  1627. PasswordLen
  1628. );
  1629. if (Ret == TcgResultSuccess) {
  1630. OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
  1631. DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
  1632. } else {
  1633. DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
  1634. }
  1635. if (OldPassword != NULL) {
  1636. ZeroMem (OldPassword, OldPasswordLen);
  1637. FreePool (OldPassword);
  1638. }
  1639. if (Password != NULL) {
  1640. ZeroMem (Password, PasswordLen);
  1641. FreePool (Password);
  1642. }
  1643. if (Ret == TcgResultSuccess) {
  1644. break;
  1645. }
  1646. Count++;
  1647. do {
  1648. CreatePopUp (
  1649. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1650. &Key,
  1651. L"Request failed.",
  1652. L"Press ENTER to retry",
  1653. NULL
  1654. );
  1655. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1656. }
  1657. if (Count >= MAX_PASSWORD_TRY_COUNT) {
  1658. do {
  1659. CreatePopUp (
  1660. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1661. &Key,
  1662. L"Opal password retry count exceeds the limit.",
  1663. L"Press ENTER to skip the request and continue boot",
  1664. NULL
  1665. );
  1666. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1667. gST->ConOut->ClearScreen(gST->ConOut);
  1668. }
  1669. }
  1670. /**
  1671. Process Set Admin Pwd OPAL request.
  1672. @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
  1673. @param[in] RequestString Request string.
  1674. **/
  1675. VOID
  1676. ProcessOpalRequestSetAdminPwd (
  1677. IN OPAL_DRIVER_DEVICE *Dev,
  1678. IN CHAR16 *RequestString
  1679. )
  1680. {
  1681. UINT8 Count;
  1682. CHAR8 *OldPassword;
  1683. UINT32 OldPasswordLen;
  1684. CHAR8 *Password;
  1685. UINT32 PasswordLen;
  1686. CHAR8 *PasswordConfirm;
  1687. UINT32 PasswordLenConfirm;
  1688. OPAL_SESSION Session;
  1689. BOOLEAN PressEsc;
  1690. EFI_INPUT_KEY Key;
  1691. TCG_RESULT Ret;
  1692. CHAR16 *PopUpString;
  1693. if (Dev == NULL) {
  1694. return;
  1695. }
  1696. DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
  1697. PopUpString = OpalGetPopUpString (Dev, RequestString);
  1698. Count = 0;
  1699. while (Count < MAX_PASSWORD_TRY_COUNT) {
  1700. OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);
  1701. if (PressEsc) {
  1702. do {
  1703. CreatePopUp (
  1704. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1705. &Key,
  1706. L"Press ENTER to skip the request and continue boot,",
  1707. L"Press ESC to input password again",
  1708. NULL
  1709. );
  1710. } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
  1711. if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
  1712. gST->ConOut->ClearScreen(gST->ConOut);
  1713. return;
  1714. } else {
  1715. //
  1716. // Let user input password again.
  1717. //
  1718. continue;
  1719. }
  1720. }
  1721. if (OldPassword == NULL) {
  1722. Count ++;
  1723. continue;
  1724. }
  1725. OldPasswordLen = (UINT32) AsciiStrLen(OldPassword);
  1726. ZeroMem(&Session, sizeof(Session));
  1727. Session.Sscp = Dev->OpalDisk.Sscp;
  1728. Session.MediaId = Dev->OpalDisk.MediaId;
  1729. Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
  1730. Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);
  1731. if (Ret == TcgResultSuccess) {
  1732. DEBUG ((DEBUG_INFO, "Verify: Success\n"));
  1733. } else {
  1734. ZeroMem (OldPassword, OldPasswordLen);
  1735. FreePool (OldPassword);
  1736. DEBUG ((DEBUG_INFO, "Verify: Failure\n"));
  1737. do {
  1738. CreatePopUp (
  1739. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1740. &Key,
  1741. L"Incorrect password.",
  1742. L"Press ENTER to retry",
  1743. NULL
  1744. );
  1745. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1746. Count ++;
  1747. continue;
  1748. }
  1749. Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);
  1750. if (Password == NULL) {
  1751. ZeroMem (OldPassword, OldPasswordLen);
  1752. FreePool (OldPassword);
  1753. Count ++;
  1754. continue;
  1755. }
  1756. PasswordLen = (UINT32) AsciiStrLen(Password);
  1757. PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);
  1758. if (PasswordConfirm == NULL) {
  1759. ZeroMem (OldPassword, OldPasswordLen);
  1760. FreePool (OldPassword);
  1761. ZeroMem (Password, PasswordLen);
  1762. FreePool (Password);
  1763. Count ++;
  1764. continue;
  1765. }
  1766. PasswordLenConfirm = (UINT32) AsciiStrLen(PasswordConfirm);
  1767. if ((PasswordLen != PasswordLenConfirm) ||
  1768. (CompareMem (Password, PasswordConfirm, PasswordLen) != 0)) {
  1769. ZeroMem (OldPassword, OldPasswordLen);
  1770. FreePool (OldPassword);
  1771. ZeroMem (Password, PasswordLen);
  1772. FreePool (Password);
  1773. ZeroMem (PasswordConfirm, PasswordLenConfirm);
  1774. FreePool (PasswordConfirm);
  1775. do {
  1776. CreatePopUp (
  1777. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1778. &Key,
  1779. L"Passwords are not the same.",
  1780. L"Press ENTER to retry",
  1781. NULL
  1782. );
  1783. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1784. Count ++;
  1785. continue;
  1786. }
  1787. if (PasswordConfirm != NULL) {
  1788. ZeroMem (PasswordConfirm, PasswordLenConfirm);
  1789. FreePool (PasswordConfirm);
  1790. }
  1791. ZeroMem(&Session, sizeof(Session));
  1792. Session.Sscp = Dev->OpalDisk.Sscp;
  1793. Session.MediaId = Dev->OpalDisk.MediaId;
  1794. Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
  1795. Ret = OpalUtilSetAdminPassword(
  1796. &Session,
  1797. OldPassword,
  1798. OldPasswordLen,
  1799. Password,
  1800. PasswordLen
  1801. );
  1802. if (Ret == TcgResultSuccess) {
  1803. OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
  1804. DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
  1805. } else {
  1806. DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
  1807. }
  1808. if (OldPassword != NULL) {
  1809. ZeroMem (OldPassword, OldPasswordLen);
  1810. FreePool (OldPassword);
  1811. }
  1812. if (Password != NULL) {
  1813. ZeroMem (Password, PasswordLen);
  1814. FreePool (Password);
  1815. }
  1816. if (Ret == TcgResultSuccess) {
  1817. break;
  1818. }
  1819. Count++;
  1820. do {
  1821. CreatePopUp (
  1822. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1823. &Key,
  1824. L"Request failed.",
  1825. L"Press ENTER to retry",
  1826. NULL
  1827. );
  1828. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1829. }
  1830. if (Count >= MAX_PASSWORD_TRY_COUNT) {
  1831. do {
  1832. CreatePopUp (
  1833. EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
  1834. &Key,
  1835. L"Opal password retry count exceeds the limit.",
  1836. L"Press ENTER to skip the request and continue boot",
  1837. NULL
  1838. );
  1839. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  1840. gST->ConOut->ClearScreen(gST->ConOut);
  1841. }
  1842. }
  1843. /**
  1844. Process OPAL request.
  1845. @param[in] Dev The device which has OPAL request.
  1846. **/
  1847. VOID
  1848. ProcessOpalRequest (
  1849. IN OPAL_DRIVER_DEVICE *Dev
  1850. )
  1851. {
  1852. EFI_STATUS Status;
  1853. OPAL_REQUEST_VARIABLE *TempVariable;
  1854. OPAL_REQUEST_VARIABLE *Variable;
  1855. UINTN VariableSize;
  1856. EFI_DEVICE_PATH_PROTOCOL *DevicePathInVariable;
  1857. UINTN DevicePathSizeInVariable;
  1858. EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  1859. UINTN DevicePathSize;
  1860. BOOLEAN KeepUserData;
  1861. DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));
  1862. if (mOpalRequestVariable == NULL) {
  1863. Status = GetVariable2 (
  1864. OPAL_REQUEST_VARIABLE_NAME,
  1865. &gHiiSetupVariableGuid,
  1866. (VOID **) &Variable,
  1867. &VariableSize
  1868. );
  1869. if (EFI_ERROR (Status) || (Variable == NULL)) {
  1870. return;
  1871. }
  1872. mOpalRequestVariable = Variable;
  1873. mOpalRequestVariableSize = VariableSize;
  1874. //
  1875. // Delete the OPAL request variable.
  1876. //
  1877. Status = gRT->SetVariable (
  1878. OPAL_REQUEST_VARIABLE_NAME,
  1879. (EFI_GUID *) &gHiiSetupVariableGuid,
  1880. 0,
  1881. 0,
  1882. NULL
  1883. );
  1884. ASSERT_EFI_ERROR (Status);
  1885. } else {
  1886. Variable = mOpalRequestVariable;
  1887. VariableSize = mOpalRequestVariableSize;
  1888. }
  1889. //
  1890. // Process the OPAL requests.
  1891. //
  1892. TempVariable = Variable;
  1893. while ((VariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&
  1894. (VariableSize >= TempVariable->Length) &&
  1895. (TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE))) {
  1896. DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
  1897. DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);
  1898. DevicePath = Dev->OpalDisk.OpalDevicePath;
  1899. DevicePathSize = GetDevicePathSize (DevicePath);
  1900. if ((DevicePathSize == DevicePathSizeInVariable) &&
  1901. (CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0)) {
  1902. //
  1903. // Found the node for the OPAL device.
  1904. //
  1905. if (TempVariable->OpalRequest.SetAdminPwd != 0) {
  1906. ProcessOpalRequestSetAdminPwd (Dev, L"Update Admin Pwd:");
  1907. }
  1908. if (TempVariable->OpalRequest.SetUserPwd != 0) {
  1909. ProcessOpalRequestSetUserPwd (Dev, L"Set User Pwd:");
  1910. }
  1911. if (TempVariable->OpalRequest.SecureErase!= 0) {
  1912. ProcessOpalRequestSecureErase (Dev, L"Secure Erase:");
  1913. }
  1914. if (TempVariable->OpalRequest.Revert != 0) {
  1915. KeepUserData = (BOOLEAN) TempVariable->OpalRequest.KeepUserData;
  1916. ProcessOpalRequestRevert (
  1917. Dev,
  1918. KeepUserData,
  1919. KeepUserData ? L"Admin Revert(keep):" : L"Admin Revert:"
  1920. );
  1921. }
  1922. if (TempVariable->OpalRequest.PsidRevert != 0) {
  1923. ProcessOpalRequestPsidRevert (Dev, L"Psid Revert:");
  1924. }
  1925. if (TempVariable->OpalRequest.DisableUser != 0) {
  1926. ProcessOpalRequestDisableUser (Dev, L"Disable User:");
  1927. }
  1928. if (TempVariable->OpalRequest.EnableFeature != 0) {
  1929. ProcessOpalRequestEnableFeature (Dev, L"Enable Feature:");
  1930. }
  1931. //
  1932. // Update Device ownership.
  1933. // Later BlockSID command may block the update.
  1934. //
  1935. OpalDiskUpdateOwnerShip (&Dev->OpalDisk);
  1936. break;
  1937. }
  1938. VariableSize -= TempVariable->Length;
  1939. TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) TempVariable + TempVariable->Length);
  1940. }
  1941. DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));
  1942. }
  1943. /**
  1944. Add new device to the global device list.
  1945. @param Dev New create device.
  1946. **/
  1947. VOID
  1948. AddDeviceToTail(
  1949. IN OPAL_DRIVER_DEVICE *Dev
  1950. )
  1951. {
  1952. OPAL_DRIVER_DEVICE *TmpDev;
  1953. if (mOpalDriver.DeviceList == NULL) {
  1954. mOpalDriver.DeviceList = Dev;
  1955. } else {
  1956. TmpDev = mOpalDriver.DeviceList;
  1957. while (TmpDev->Next != NULL) {
  1958. TmpDev = TmpDev->Next;
  1959. }
  1960. TmpDev->Next = Dev;
  1961. }
  1962. }
  1963. /**
  1964. Remove one device in the global device list.
  1965. @param Dev The device need to be removed.
  1966. **/
  1967. VOID
  1968. RemoveDevice (
  1969. IN OPAL_DRIVER_DEVICE *Dev
  1970. )
  1971. {
  1972. OPAL_DRIVER_DEVICE *TmpDev;
  1973. if (mOpalDriver.DeviceList == NULL) {
  1974. return;
  1975. }
  1976. if (mOpalDriver.DeviceList == Dev) {
  1977. mOpalDriver.DeviceList = NULL;
  1978. return;
  1979. }
  1980. TmpDev = mOpalDriver.DeviceList;
  1981. while (TmpDev->Next != NULL) {
  1982. if (TmpDev->Next == Dev) {
  1983. TmpDev->Next = Dev->Next;
  1984. break;
  1985. }
  1986. }
  1987. }
  1988. /**
  1989. Get current device count.
  1990. @retval return the current created device count.
  1991. **/
  1992. UINT8
  1993. GetDeviceCount (
  1994. VOID
  1995. )
  1996. {
  1997. UINT8 Count;
  1998. OPAL_DRIVER_DEVICE *TmpDev;
  1999. Count = 0;
  2000. TmpDev = mOpalDriver.DeviceList;
  2001. while (TmpDev != NULL) {
  2002. Count++;
  2003. TmpDev = TmpDev->Next;
  2004. }
  2005. return Count;
  2006. }
  2007. /**
  2008. Get devcie list info.
  2009. @retval return the device list pointer.
  2010. **/
  2011. OPAL_DRIVER_DEVICE*
  2012. OpalDriverGetDeviceList(
  2013. VOID
  2014. )
  2015. {
  2016. return mOpalDriver.DeviceList;
  2017. }
  2018. /**
  2019. Stop this Controller.
  2020. @param Dev The device need to be stopped.
  2021. **/
  2022. VOID
  2023. OpalDriverStopDevice (
  2024. OPAL_DRIVER_DEVICE *Dev
  2025. )
  2026. {
  2027. //
  2028. // free each name
  2029. //
  2030. FreePool(Dev->Name16);
  2031. //
  2032. // remove OPAL_DRIVER_DEVICE from the list
  2033. // it updates the controllerList pointer
  2034. //
  2035. RemoveDevice(Dev);
  2036. //
  2037. // close protocols that were opened
  2038. //
  2039. gBS->CloseProtocol(
  2040. Dev->Handle,
  2041. &gEfiStorageSecurityCommandProtocolGuid,
  2042. gOpalDriverBinding.DriverBindingHandle,
  2043. Dev->Handle
  2044. );
  2045. gBS->CloseProtocol(
  2046. Dev->Handle,
  2047. &gEfiBlockIoProtocolGuid,
  2048. gOpalDriverBinding.DriverBindingHandle,
  2049. Dev->Handle
  2050. );
  2051. FreePool(Dev);
  2052. }
  2053. /**
  2054. Get devcie name through the component name protocol.
  2055. @param[in] AllHandlesBuffer The handle buffer for current system.
  2056. @param[in] NumAllHandles The number of handles for the handle buffer.
  2057. @param[in] Dev The device which need to get name.
  2058. @param[in] UseComp1 Whether use component name or name2 protocol.
  2059. @retval TRUE Find the name for this device.
  2060. @retval FALSE Not found the name for this device.
  2061. **/
  2062. BOOLEAN
  2063. OpalDriverGetDeviceNameByProtocol(
  2064. EFI_HANDLE *AllHandlesBuffer,
  2065. UINTN NumAllHandles,
  2066. OPAL_DRIVER_DEVICE *Dev,
  2067. BOOLEAN UseComp1
  2068. )
  2069. {
  2070. EFI_HANDLE* ProtocolHandlesBuffer;
  2071. UINTN NumProtocolHandles;
  2072. EFI_STATUS Status;
  2073. EFI_COMPONENT_NAME2_PROTOCOL* Cnp1_2; // efi component name and componentName2 have same layout
  2074. EFI_GUID Protocol;
  2075. UINTN StrLength;
  2076. EFI_DEVICE_PATH_PROTOCOL* TmpDevPath;
  2077. UINTN Index1;
  2078. UINTN Index2;
  2079. EFI_HANDLE TmpHandle;
  2080. CHAR16 *DevName;
  2081. if (Dev == NULL || AllHandlesBuffer == NULL || NumAllHandles == 0) {
  2082. return FALSE;
  2083. }
  2084. Protocol = UseComp1 ? gEfiComponentNameProtocolGuid : gEfiComponentName2ProtocolGuid;
  2085. //
  2086. // Find all EFI_HANDLES with protocol
  2087. //
  2088. Status = gBS->LocateHandleBuffer(
  2089. ByProtocol,
  2090. &Protocol,
  2091. NULL,
  2092. &NumProtocolHandles,
  2093. &ProtocolHandlesBuffer
  2094. );
  2095. if (EFI_ERROR(Status)) {
  2096. return FALSE;
  2097. }
  2098. //
  2099. // Exit early if no supported devices
  2100. //
  2101. if (NumProtocolHandles == 0) {
  2102. return FALSE;
  2103. }
  2104. //
  2105. // Get printable name by iterating through all protocols
  2106. // using the handle as the child, and iterate through all handles for the controller
  2107. // exit loop early once found, if not found, then delete device
  2108. // storage security protocol instances already exist, add them to internal list
  2109. //
  2110. Status = EFI_DEVICE_ERROR;
  2111. for (Index1 = 0; Index1 < NumProtocolHandles; Index1++) {
  2112. DevName = NULL;
  2113. if (Dev->Name16 != NULL) {
  2114. return TRUE;
  2115. }
  2116. TmpHandle = ProtocolHandlesBuffer[Index1];
  2117. Status = gBS->OpenProtocol(
  2118. TmpHandle,
  2119. &Protocol,
  2120. (VOID**)&Cnp1_2,
  2121. gImageHandle,
  2122. NULL,
  2123. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  2124. );
  2125. if (EFI_ERROR(Status) || Cnp1_2 == NULL) {
  2126. continue;
  2127. }
  2128. //
  2129. // Use all handles array as controller handle
  2130. //
  2131. for (Index2 = 0; Index2 < NumAllHandles; Index2++) {
  2132. Status = Cnp1_2->GetControllerName(
  2133. Cnp1_2,
  2134. AllHandlesBuffer[Index2],
  2135. Dev->Handle,
  2136. LANGUAGE_ISO_639_2_ENGLISH,
  2137. &DevName
  2138. );
  2139. if (EFI_ERROR(Status)) {
  2140. Status = Cnp1_2->GetControllerName(
  2141. Cnp1_2,
  2142. AllHandlesBuffer[Index2],
  2143. Dev->Handle,
  2144. LANGUAGE_RFC_3066_ENGLISH,
  2145. &DevName
  2146. );
  2147. }
  2148. if (!EFI_ERROR(Status) && DevName != NULL) {
  2149. StrLength = StrLen(DevName) + 1; // Add one for NULL terminator
  2150. Dev->Name16 = AllocateZeroPool(StrLength * sizeof (CHAR16));
  2151. ASSERT (Dev->Name16 != NULL);
  2152. StrCpyS (Dev->Name16, StrLength, DevName);
  2153. Dev->NameZ = (CHAR8*)AllocateZeroPool(StrLength);
  2154. UnicodeStrToAsciiStrS (DevName, Dev->NameZ, StrLength);
  2155. //
  2156. // Retrieve bridge BDF info and port number or namespace depending on type
  2157. //
  2158. TmpDevPath = NULL;
  2159. Status = gBS->OpenProtocol(
  2160. Dev->Handle,
  2161. &gEfiDevicePathProtocolGuid,
  2162. (VOID**)&TmpDevPath,
  2163. gImageHandle,
  2164. NULL,
  2165. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  2166. );
  2167. if (!EFI_ERROR(Status)) {
  2168. Dev->OpalDevicePath = DuplicateDevicePath (TmpDevPath);
  2169. return TRUE;
  2170. }
  2171. if (Dev->Name16 != NULL) {
  2172. FreePool(Dev->Name16);
  2173. Dev->Name16 = NULL;
  2174. }
  2175. if (Dev->NameZ != NULL) {
  2176. FreePool(Dev->NameZ);
  2177. Dev->NameZ = NULL;
  2178. }
  2179. }
  2180. }
  2181. }
  2182. return FALSE;
  2183. }
  2184. /**
  2185. Get devcie name through the component name protocol.
  2186. @param[in] Dev The device which need to get name.
  2187. @retval TRUE Find the name for this device.
  2188. @retval FALSE Not found the name for this device.
  2189. **/
  2190. BOOLEAN
  2191. OpalDriverGetDriverDeviceName(
  2192. OPAL_DRIVER_DEVICE *Dev
  2193. )
  2194. {
  2195. EFI_HANDLE* AllHandlesBuffer;
  2196. UINTN NumAllHandles;
  2197. EFI_STATUS Status;
  2198. if (Dev == NULL) {
  2199. DEBUG((DEBUG_ERROR | DEBUG_INIT, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
  2200. return FALSE;
  2201. }
  2202. //
  2203. // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
  2204. //
  2205. if (Dev->Name16 == NULL) {
  2206. DEBUG((DEBUG_ERROR | DEBUG_INIT, "Name is null, update it\n"));
  2207. //
  2208. // Find all EFI_HANDLES
  2209. //
  2210. Status = gBS->LocateHandleBuffer(
  2211. AllHandles,
  2212. NULL,
  2213. NULL,
  2214. &NumAllHandles,
  2215. &AllHandlesBuffer
  2216. );
  2217. if (EFI_ERROR(Status)) {
  2218. DEBUG ((DEBUG_INFO, "LocateHandleBuffer for AllHandles failed %r\n", Status ));
  2219. return FALSE;
  2220. }
  2221. //
  2222. // Try component Name2
  2223. //
  2224. if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, FALSE)) {
  2225. DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName2 failed to get device name, try ComponentName\n"));
  2226. if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, TRUE)) {
  2227. DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName failed to get device name, skip device\n"));
  2228. return FALSE;
  2229. }
  2230. }
  2231. }
  2232. return TRUE;
  2233. }
  2234. /**
  2235. Main entry for this driver.
  2236. @param ImageHandle Image Handle this driver.
  2237. @param SystemTable Pointer to SystemTable.
  2238. @retval EFI_SUCESS This function always complete successfully.
  2239. **/
  2240. EFI_STATUS
  2241. EFIAPI
  2242. EfiDriverEntryPoint(
  2243. IN EFI_HANDLE ImageHandle,
  2244. IN EFI_SYSTEM_TABLE* SystemTable
  2245. )
  2246. {
  2247. EFI_STATUS Status;
  2248. EFI_EVENT EndOfDxeEvent;
  2249. Status = EfiLibInstallDriverBindingComponentName2 (
  2250. ImageHandle,
  2251. SystemTable,
  2252. &gOpalDriverBinding,
  2253. ImageHandle,
  2254. &gOpalComponentName,
  2255. &gOpalComponentName2
  2256. );
  2257. if (EFI_ERROR(Status)) {
  2258. DEBUG((DEBUG_ERROR, "Install protocols to Opal driver Handle failed\n"));
  2259. return Status ;
  2260. }
  2261. //
  2262. // Initialize Driver object
  2263. //
  2264. ZeroMem(&mOpalDriver, sizeof(mOpalDriver));
  2265. mOpalDriver.Handle = ImageHandle;
  2266. Status = gBS->CreateEventEx (
  2267. EVT_NOTIFY_SIGNAL,
  2268. TPL_CALLBACK,
  2269. OpalEndOfDxeEventNotify,
  2270. NULL,
  2271. &gEfiEndOfDxeEventGroupGuid,
  2272. &EndOfDxeEvent
  2273. );
  2274. ASSERT_EFI_ERROR (Status);
  2275. //
  2276. // Install Hii packages.
  2277. //
  2278. HiiInstall();
  2279. return Status;
  2280. }
  2281. /**
  2282. Tests to see if this driver supports a given controller.
  2283. This function checks to see if the controller contains an instance of the
  2284. EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
  2285. and returns EFI_SUCCESS if it does.
  2286. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  2287. @param[in] ControllerHandle The Handle of the controller to test. This Handle
  2288. must support a protocol interface that supplies
  2289. an I/O abstraction to the driver.
  2290. @param[in] RemainingDevicePath This parameter is ignored.
  2291. @retval EFI_SUCCESS The device contains required protocols
  2292. @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
  2293. RemainingDevicePath is already being managed by the driver
  2294. specified by This.
  2295. @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
  2296. RemainingDevicePath is already being managed by a different
  2297. driver or an application that requires exclusive access.
  2298. Currently not implemented.
  2299. @retval EFI_UNSUPPORTED The device does not contain requires protocols
  2300. **/
  2301. EFI_STATUS
  2302. EFIAPI
  2303. OpalEfiDriverBindingSupported(
  2304. IN EFI_DRIVER_BINDING_PROTOCOL* This,
  2305. IN EFI_HANDLE Controller,
  2306. IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath
  2307. )
  2308. {
  2309. EFI_STATUS Status;
  2310. EFI_STORAGE_SECURITY_COMMAND_PROTOCOL* SecurityCommand;
  2311. EFI_BLOCK_IO_PROTOCOL* BlkIo;
  2312. if (mOpalEndOfDxe) {
  2313. return EFI_UNSUPPORTED;
  2314. }
  2315. //
  2316. // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
  2317. //
  2318. Status = gBS->OpenProtocol(
  2319. Controller,
  2320. &gEfiStorageSecurityCommandProtocolGuid,
  2321. ( VOID ** )&SecurityCommand,
  2322. This->DriverBindingHandle,
  2323. Controller,
  2324. EFI_OPEN_PROTOCOL_BY_DRIVER
  2325. );
  2326. if (Status == EFI_ALREADY_STARTED) {
  2327. return EFI_SUCCESS;
  2328. }
  2329. if (EFI_ERROR(Status)) {
  2330. return Status;
  2331. }
  2332. //
  2333. // Close protocol and reopen in Start call
  2334. //
  2335. gBS->CloseProtocol(
  2336. Controller,
  2337. &gEfiStorageSecurityCommandProtocolGuid,
  2338. This->DriverBindingHandle,
  2339. Controller
  2340. );
  2341. //
  2342. // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
  2343. // function APIs
  2344. //
  2345. Status = gBS->OpenProtocol(
  2346. Controller,
  2347. &gEfiBlockIoProtocolGuid,
  2348. (VOID **)&BlkIo,
  2349. This->DriverBindingHandle,
  2350. Controller,
  2351. EFI_OPEN_PROTOCOL_BY_DRIVER
  2352. );
  2353. if (EFI_ERROR(Status)) {
  2354. DEBUG((DEBUG_INFO, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
  2355. return Status;
  2356. }
  2357. //
  2358. // Close protocol and reopen in Start call
  2359. //
  2360. gBS->CloseProtocol(
  2361. Controller,
  2362. &gEfiBlockIoProtocolGuid,
  2363. This->DriverBindingHandle,
  2364. Controller
  2365. );
  2366. return EFI_SUCCESS;
  2367. }
  2368. /**
  2369. Enables Opal Management on a supported device if available.
  2370. The start function is designed to be called after the Opal UEFI Driver has confirmed the
  2371. "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
  2372. This function will complete the other necessary checks, such as verifying the device supports
  2373. the correct version of Opal. Upon verification, it will add the device to the
  2374. Opal HII list in order to expose Opal managmeent options.
  2375. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  2376. @param[in] ControllerHandle The Handle of the controller to start. This Handle
  2377. must support a protocol interface that supplies
  2378. an I/O abstraction to the driver.
  2379. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
  2380. parameter is ignored by device drivers, and is optional for bus
  2381. drivers. For a bus driver, if this parameter is NULL, then handles
  2382. for all the children of Controller are created by this driver.
  2383. If this parameter is not NULL and the first Device Path Node is
  2384. not the End of Device Path Node, then only the Handle for the
  2385. child device specified by the first Device Path Node of
  2386. RemainingDevicePath is created by this driver.
  2387. If the first Device Path Node of RemainingDevicePath is
  2388. the End of Device Path Node, no child Handle is created by this
  2389. driver.
  2390. @retval EFI_SUCCESS Opal management was enabled.
  2391. @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
  2392. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
  2393. @retval Others The driver failed to start the device.
  2394. **/
  2395. EFI_STATUS
  2396. EFIAPI
  2397. OpalEfiDriverBindingStart(
  2398. IN EFI_DRIVER_BINDING_PROTOCOL* This,
  2399. IN EFI_HANDLE Controller,
  2400. IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath
  2401. )
  2402. {
  2403. EFI_STATUS Status;
  2404. EFI_BLOCK_IO_PROTOCOL *BlkIo;
  2405. OPAL_DRIVER_DEVICE *Dev;
  2406. OPAL_DRIVER_DEVICE *Itr;
  2407. BOOLEAN Result;
  2408. Itr = mOpalDriver.DeviceList;
  2409. while (Itr != NULL) {
  2410. if (Controller == Itr->Handle) {
  2411. return EFI_SUCCESS;
  2412. }
  2413. Itr = Itr->Next;
  2414. }
  2415. //
  2416. // Create internal device for tracking. This allows all disks to be tracked
  2417. // by same HII form
  2418. //
  2419. Dev = (OPAL_DRIVER_DEVICE*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE));
  2420. if (Dev == NULL) {
  2421. return EFI_OUT_OF_RESOURCES;
  2422. }
  2423. Dev->Handle = Controller;
  2424. //
  2425. // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
  2426. //
  2427. Status = gBS->OpenProtocol(
  2428. Controller,
  2429. &gEfiStorageSecurityCommandProtocolGuid,
  2430. (VOID **)&Dev->Sscp,
  2431. This->DriverBindingHandle,
  2432. Controller,
  2433. EFI_OPEN_PROTOCOL_BY_DRIVER
  2434. );
  2435. if (EFI_ERROR(Status)) {
  2436. FreePool(Dev);
  2437. return Status;
  2438. }
  2439. //
  2440. // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
  2441. // function APIs
  2442. //
  2443. Status = gBS->OpenProtocol(
  2444. Controller,
  2445. &gEfiBlockIoProtocolGuid,
  2446. (VOID **)&BlkIo,
  2447. This->DriverBindingHandle,
  2448. Controller,
  2449. EFI_OPEN_PROTOCOL_BY_DRIVER
  2450. );
  2451. if (EFI_ERROR(Status)) {
  2452. //
  2453. // Close storage security that was opened
  2454. //
  2455. gBS->CloseProtocol(
  2456. Controller,
  2457. &gEfiStorageSecurityCommandProtocolGuid,
  2458. This->DriverBindingHandle,
  2459. Controller
  2460. );
  2461. FreePool(Dev);
  2462. return Status;
  2463. }
  2464. //
  2465. // Save mediaId
  2466. //
  2467. Dev->MediaId = BlkIo->Media->MediaId;
  2468. gBS->CloseProtocol(
  2469. Controller,
  2470. &gEfiBlockIoProtocolGuid,
  2471. This->DriverBindingHandle,
  2472. Controller
  2473. );
  2474. //
  2475. // Acquire Ascii printable name of child, if not found, then ignore device
  2476. //
  2477. Result = OpalDriverGetDriverDeviceName (Dev);
  2478. if (!Result) {
  2479. goto Done;
  2480. }
  2481. Status = OpalDiskInitialize (Dev);
  2482. if (EFI_ERROR (Status)) {
  2483. goto Done;
  2484. }
  2485. AddDeviceToTail(Dev);
  2486. //
  2487. // Check if device is locked and prompt for password.
  2488. //
  2489. OpalDriverRequestPassword (Dev, L"Unlock:");
  2490. //
  2491. // Process OPAL request from last boot.
  2492. //
  2493. ProcessOpalRequest (Dev);
  2494. return EFI_SUCCESS;
  2495. Done:
  2496. //
  2497. // free device, close protocols and exit
  2498. //
  2499. gBS->CloseProtocol(
  2500. Controller,
  2501. &gEfiStorageSecurityCommandProtocolGuid,
  2502. This->DriverBindingHandle,
  2503. Controller
  2504. );
  2505. FreePool(Dev);
  2506. return EFI_DEVICE_ERROR;
  2507. }
  2508. /**
  2509. Stop this driver on Controller.
  2510. @param This Protocol instance pointer.
  2511. @param Controller Handle of device to stop driver on
  2512. @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
  2513. children is zero stop the entire bus driver.
  2514. @param ChildHandleBuffer List of Child Handles to Stop.
  2515. @retval EFI_SUCCESS This driver is removed Controller.
  2516. @retval other This driver could not be removed from this device.
  2517. **/
  2518. EFI_STATUS
  2519. EFIAPI
  2520. OpalEfiDriverBindingStop(
  2521. EFI_DRIVER_BINDING_PROTOCOL* This,
  2522. EFI_HANDLE Controller,
  2523. UINTN NumberOfChildren,
  2524. EFI_HANDLE* ChildHandleBuffer
  2525. )
  2526. {
  2527. OPAL_DRIVER_DEVICE* Itr;
  2528. Itr = mOpalDriver.DeviceList;
  2529. //
  2530. // does Controller match any of the devices we are managing for Opal
  2531. //
  2532. while (Itr != NULL) {
  2533. if (Itr->Handle == Controller) {
  2534. OpalDriverStopDevice (Itr);
  2535. return EFI_SUCCESS;
  2536. }
  2537. Itr = Itr->Next;
  2538. }
  2539. return EFI_NOT_FOUND;
  2540. }
  2541. /**
  2542. Unloads UEFI Driver. Very useful for debugging and testing.
  2543. @param ImageHandle Image Handle this driver.
  2544. @retval EFI_SUCCESS This function always complete successfully.
  2545. @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
  2546. **/
  2547. EFI_STATUS
  2548. EFIAPI
  2549. OpalEfiDriverUnload (
  2550. IN EFI_HANDLE ImageHandle
  2551. )
  2552. {
  2553. EFI_STATUS Status;
  2554. OPAL_DRIVER_DEVICE *Itr;
  2555. Status = EFI_SUCCESS;
  2556. if (ImageHandle != gImageHandle) {
  2557. return (EFI_INVALID_PARAMETER);
  2558. }
  2559. //
  2560. // Uninstall any interface added to each device by us
  2561. //
  2562. while (mOpalDriver.DeviceList) {
  2563. Itr = mOpalDriver.DeviceList;
  2564. //
  2565. // Remove OPAL_DRIVER_DEVICE from the list
  2566. // it updates the controllerList pointer
  2567. //
  2568. OpalDriverStopDevice(Itr);
  2569. }
  2570. //
  2571. // Uninstall the HII capability
  2572. //
  2573. Status = HiiUninstall();
  2574. return Status;
  2575. }