tpm2.c 154 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673
  1. /* SPDX-License-Identifier: BSD-3-Clause */
  2. #include <string.h>
  3. #include <tss2/tss2_mu.h>
  4. #include <tss2/tss2_sys.h>
  5. #include "log.h"
  6. #include "object.h"
  7. #include "tool_rc.h"
  8. #include "tpm2.h"
  9. #include "tpm2_alg_util.h"
  10. #include "tpm2_auth_util.h"
  11. #include "tpm2_openssl.h"
  12. #include "tpm2_session.h"
  13. #include "tpm2_tool.h"
  14. #include "config.h"
  15. #define TPM2_ERROR_TSS2_RC_ERROR_MASK 0xFFFF
  16. static inline UINT16 tpm2_error_get(TSS2_RC rc) {
  17. return ((rc & TPM2_ERROR_TSS2_RC_ERROR_MASK));
  18. }
  19. tool_rc tpm2_readpublic(ESYS_CONTEXT *esys_context, ESYS_TR object_handle,
  20. TPM2B_PUBLIC **out_public, TPM2B_NAME **name,
  21. TPM2B_NAME **qualified_name) {
  22. TSS2_RC rval = Esys_ReadPublic(esys_context, object_handle,
  23. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
  24. out_public, name, qualified_name);
  25. if (rval != TPM2_RC_SUCCESS) {
  26. LOG_PERR(Esys_ReadPublic, rval);
  27. return tool_rc_from_tpm(rval);
  28. }
  29. return tool_rc_success;
  30. }
  31. tool_rc tpm2_from_tpm_public(ESYS_CONTEXT *esys_context, TPM2_HANDLE tpm_handle,
  32. ESYS_TR optional_session1, ESYS_TR optional_session2,
  33. ESYS_TR optional_session3, ESYS_TR *object) {
  34. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, tpm_handle,
  35. optional_session1, optional_session2, optional_session3, object);
  36. if (rval != TSS2_RC_SUCCESS) {
  37. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  38. return tool_rc_from_tpm(rval);
  39. }
  40. return tool_rc_success;
  41. }
  42. tool_rc tpm2_tr_deserialize(ESYS_CONTEXT *esys_context, uint8_t const *buffer,
  43. size_t buffer_size, ESYS_TR *esys_handle) {
  44. TSS2_RC rval = Esys_TR_Deserialize(esys_context, buffer, buffer_size,
  45. esys_handle);
  46. if (rval != TSS2_RC_SUCCESS) {
  47. LOG_PERR(Esys_TR_Deserialize, rval);
  48. return tool_rc_from_tpm(rval);
  49. }
  50. return tool_rc_success;
  51. }
  52. tool_rc tpm2_tr_serialize(ESYS_CONTEXT *esys_context, ESYS_TR object,
  53. uint8_t **buffer, size_t *buffer_size) {
  54. TSS2_RC rval = Esys_TR_Serialize(esys_context, object, buffer, buffer_size);
  55. if (rval != TSS2_RC_SUCCESS) {
  56. LOG_PERR(Esys_TR_Serialize, rval);
  57. return tool_rc_from_tpm(rval);
  58. }
  59. return tool_rc_success;
  60. }
  61. tool_rc tpm2_tr_get_name(ESYS_CONTEXT *esys_context, ESYS_TR handle,
  62. TPM2B_NAME **name) {
  63. TSS2_RC rval = Esys_TR_GetName(esys_context, handle, name);
  64. if (rval != TSS2_RC_SUCCESS) {
  65. LOG_PERR(Esys_TR_GetName, rval);
  66. return tool_rc_from_tpm(rval);
  67. }
  68. return tool_rc_success;
  69. }
  70. tool_rc tpm2_close(ESYS_CONTEXT *esys_context, ESYS_TR *rsrc_handle) {
  71. TSS2_RC rval = Esys_TR_Close(esys_context, rsrc_handle);
  72. if (rval != TSS2_RC_SUCCESS) {
  73. LOG_PERR(Esys_TR_Close, rval);
  74. return tool_rc_from_tpm(rval);
  75. }
  76. return tool_rc_success;
  77. }
  78. tool_rc tpm2_nv_readpublic(ESYS_CONTEXT *esys_context, ESYS_TR nv_index,
  79. TPM2B_NV_PUBLIC **nv_public, TPM2B_NAME **nv_name) {
  80. TSS2_RC rval = Esys_NV_ReadPublic(esys_context, nv_index,
  81. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, nv_public, nv_name);
  82. if (rval != TSS2_RC_SUCCESS) {
  83. LOG_PERR(Esys_NV_ReadPublic, rval);
  84. return tool_rc_from_tpm(rval);
  85. }
  86. return tool_rc_success;
  87. }
  88. tool_rc tpm2_getcap(ESYS_CONTEXT *esys_context, TPM2_CAP capability,
  89. UINT32 property, UINT32 property_count, TPMI_YES_NO *more_data,
  90. TPMS_CAPABILITY_DATA **capability_data) {
  91. TSS2_RC rval = Esys_GetCapability(esys_context, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
  92. capability, property, property_count, more_data, capability_data);
  93. if (rval != TSS2_RC_SUCCESS) {
  94. LOG_PERR(Esys_NV_ReadPublic, rval);
  95. return tool_rc_from_tpm(rval);
  96. }
  97. return tool_rc_success;
  98. }
  99. tool_rc tpm2_nv_read(ESYS_CONTEXT *esys_context,
  100. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nv_index, UINT16 size,
  101. UINT16 offset, TPM2B_MAX_NV_BUFFER **data, TPM2B_DIGEST *cp_hash) {
  102. ESYS_TR esys_tr_nv_handle;
  103. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  104. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_handle);
  105. if (rval != TPM2_RC_SUCCESS) {
  106. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  107. return tool_rc_from_tpm(rval);
  108. }
  109. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  110. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  111. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  112. &auth_hierarchy_obj_session_handle);
  113. if (rc != tool_rc_success) {
  114. LOG_ERR("Failed to get shandle");
  115. return rc;
  116. }
  117. if (cp_hash) {
  118. /*
  119. * Need sys_context to be able to calculate CpHash
  120. */
  121. TSS2_SYS_CONTEXT *sys_context = NULL;
  122. rc = tpm2_getsapicontext(esys_context, &sys_context);
  123. if(rc != tool_rc_success) {
  124. LOG_ERR("Failed to acquire SAPI context.");
  125. return rc;
  126. }
  127. rval = Tss2_Sys_NV_Read_Prepare(sys_context, auth_hierarchy_obj->handle,
  128. nv_index, size, offset);
  129. if (rval != TPM2_RC_SUCCESS) {
  130. LOG_PERR(Tss2_Sys_NV_Read_Prepare, rval);
  131. return tool_rc_general_error;
  132. }
  133. TPM2B_NAME *name1 = NULL;
  134. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle, &name1);
  135. if (rc != tool_rc_success) {
  136. goto tpm2_nvread_free_name1;
  137. }
  138. TPM2B_NAME *name2 = NULL;
  139. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_handle, &name2);
  140. if (rc != tool_rc_success) {
  141. goto tpm2_nvread_free_name1_name2;
  142. }
  143. cp_hash->size = tpm2_alg_util_get_hash_size(
  144. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  145. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  146. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  147. /*
  148. * Exit here without making the ESYS call since we just need the cpHash
  149. */
  150. tpm2_nvread_free_name1_name2:
  151. Esys_Free(name2);
  152. tpm2_nvread_free_name1:
  153. Esys_Free(name1);
  154. goto tpm2_nvread_skip_esapi_call;
  155. }
  156. rval = Esys_NV_Read(esys_context, auth_hierarchy_obj->tr_handle,
  157. esys_tr_nv_handle, auth_hierarchy_obj_session_handle, ESYS_TR_NONE,
  158. ESYS_TR_NONE, size, offset, data);
  159. if (rval != TSS2_RC_SUCCESS) {
  160. LOG_PERR(Esys_NV_Read, rval);
  161. return tool_rc_from_tpm(rval);
  162. }
  163. tpm2_nvread_skip_esapi_call:
  164. return rc;
  165. }
  166. tool_rc tpm2_context_save(ESYS_CONTEXT *esys_context, ESYS_TR save_handle,
  167. TPMS_CONTEXT **context) {
  168. TSS2_RC rval = Esys_ContextSave(esys_context, save_handle, context);
  169. if (rval != TSS2_RC_SUCCESS) {
  170. LOG_PERR(Esys_ContextSave, rval);
  171. return tool_rc_from_tpm(rval);
  172. }
  173. return tool_rc_success;
  174. }
  175. tool_rc tpm2_context_load(ESYS_CONTEXT *esys_context,
  176. const TPMS_CONTEXT *context, ESYS_TR *loaded_handle) {
  177. TSS2_RC rval = Esys_ContextLoad(esys_context, context, loaded_handle);
  178. if (rval != TSS2_RC_SUCCESS) {
  179. LOG_PERR(Esys_ContextLoad, rval);
  180. return tool_rc_from_tpm(rval);
  181. }
  182. return tool_rc_success;
  183. }
  184. tool_rc tpm2_flush_context(ESYS_CONTEXT *esys_context, ESYS_TR flush_handle) {
  185. TSS2_RC rval = Esys_FlushContext(esys_context, flush_handle);
  186. if (rval != TSS2_RC_SUCCESS) {
  187. LOG_PERR(Esys_FlushContext, rval);
  188. return tool_rc_from_tpm(rval);
  189. }
  190. return tool_rc_success;
  191. }
  192. tool_rc tpm2_start_auth_session(ESYS_CONTEXT *esys_context, ESYS_TR tpm_key,
  193. ESYS_TR bind, const TPM2B_NONCE *nonce_caller, TPM2_SE session_type,
  194. const TPMT_SYM_DEF *symmetric, TPMI_ALG_HASH auth_hash,
  195. ESYS_TR *session_handle) {
  196. TSS2_RC rval = Esys_StartAuthSession(esys_context, tpm_key, bind,
  197. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, nonce_caller, session_type,
  198. symmetric, auth_hash, session_handle);
  199. if (rval != TSS2_RC_SUCCESS) {
  200. LOG_PERR(Esys_StartAuthSession, rval);
  201. return tool_rc_from_tpm(rval);
  202. }
  203. return tool_rc_success;
  204. }
  205. tool_rc tpm2_sess_set_attributes(ESYS_CONTEXT *esys_context, ESYS_TR session,
  206. TPMA_SESSION flags, TPMA_SESSION mask) {
  207. TSS2_RC rval = Esys_TRSess_SetAttributes(esys_context, session, flags, mask);
  208. if (rval != TSS2_RC_SUCCESS) {
  209. LOG_PERR(Esys_TRSess_SetAttributes, rval);
  210. return tool_rc_from_tpm(rval);
  211. }
  212. return tool_rc_success;
  213. }
  214. tool_rc tpm2_sess_get_attributes(ESYS_CONTEXT *esys_context, ESYS_TR session,
  215. TPMA_SESSION *flags) {
  216. TSS2_RC rval = Esys_TRSess_GetAttributes(esys_context, session, flags);
  217. if (rval != TSS2_RC_SUCCESS) {
  218. LOG_PERR(Esys_TRSess_GetAttributes, rval);
  219. return tool_rc_from_tpm(rval);
  220. }
  221. return tool_rc_success;
  222. }
  223. tool_rc tpm2_sess_get_noncetpm(ESYS_CONTEXT *esys_context,
  224. ESYS_TR session_handle, TPM2B_NONCE **nonce_tpm) {
  225. TSS2_RC rval = Esys_TRSess_GetNonceTPM(esys_context, session_handle,
  226. nonce_tpm);
  227. if (rval != TSS2_RC_SUCCESS) {
  228. LOG_PERR(Esys_TRSess_GetNonceTPM, rval);
  229. return tool_rc_from_tpm(rval);
  230. }
  231. return tool_rc_success;
  232. }
  233. tool_rc tpm2_policy_restart(ESYS_CONTEXT *esys_context, ESYS_TR session_handle,
  234. ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3) {
  235. TSS2_RC rval = Esys_PolicyRestart(esys_context, session_handle, shandle1,
  236. shandle2, shandle3);
  237. if (rval != TSS2_RC_SUCCESS) {
  238. LOG_PERR(Esys_PolicyRestart, rval);
  239. return tool_rc_from_tpm(rval);
  240. }
  241. return tool_rc_success;
  242. }
  243. tool_rc tpm2_get_capability(ESYS_CONTEXT *esys_context, ESYS_TR shandle1,
  244. ESYS_TR shandle2, ESYS_TR shandle3, TPM2_CAP capability,
  245. UINT32 property, UINT32 property_count, TPMI_YES_NO *more_data,
  246. TPMS_CAPABILITY_DATA **capability_data) {
  247. TSS2_RC rval = Esys_GetCapability(esys_context, shandle1, shandle2, shandle3,
  248. capability, property, property_count, more_data, capability_data);
  249. if (rval != TSS2_RC_SUCCESS) {
  250. LOG_PERR(Esys_GetCapability, rval);
  251. return tool_rc_from_tpm(rval);
  252. }
  253. return tool_rc_success;
  254. }
  255. tool_rc tpm2_create_primary(ESYS_CONTEXT *esys_context, ESYS_TR primary_handle,
  256. ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3,
  257. const TPM2B_SENSITIVE_CREATE *in_sensitive, const TPM2B_PUBLIC *in_public,
  258. const TPM2B_DATA *outside_info, const TPML_PCR_SELECTION *creation_pcr,
  259. ESYS_TR *object_handle, TPM2B_PUBLIC **out_public,
  260. TPM2B_CREATION_DATA **creation_data, TPM2B_DIGEST **creation_hash,
  261. TPMT_TK_CREATION **creation_ticket) {
  262. TSS2_RC rval = Esys_CreatePrimary(esys_context, primary_handle, shandle1,
  263. shandle2, shandle3, in_sensitive, in_public, outside_info, creation_pcr,
  264. object_handle, out_public, creation_data, creation_hash,
  265. creation_ticket);
  266. if (rval != TSS2_RC_SUCCESS) {
  267. LOG_PERR(Esys_CreatePrimary, rval);
  268. return tool_rc_from_tpm(rval);
  269. }
  270. return tool_rc_success;
  271. }
  272. tool_rc tpm2_pcr_read(ESYS_CONTEXT *esys_context, ESYS_TR shandle1,
  273. ESYS_TR shandle2, ESYS_TR shandle3,
  274. const TPML_PCR_SELECTION *pcr_selection_in, UINT32 *pcr_update_counter,
  275. TPML_PCR_SELECTION **pcr_selection_out, TPML_DIGEST **pcr_values) {
  276. TSS2_RC rval = Esys_PCR_Read(esys_context, shandle1, shandle2, shandle3,
  277. pcr_selection_in, pcr_update_counter, pcr_selection_out, pcr_values);
  278. if (rval != TSS2_RC_SUCCESS) {
  279. LOG_PERR(Esys_PCR_Read, rval);
  280. return tool_rc_from_tpm(rval);
  281. }
  282. return tool_rc_success;
  283. }
  284. tool_rc tpm2_policy_authorize(ESYS_CONTEXT *esys_context, ESYS_TR policy_session,
  285. ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3,
  286. const TPM2B_DIGEST *approved_policy, const TPM2B_NONCE *policy_ref,
  287. const TPM2B_NAME *key_sign, const TPMT_TK_VERIFIED *check_ticket) {
  288. TSS2_RC rval = Esys_PolicyAuthorize(esys_context, policy_session, shandle1,
  289. shandle2, shandle3, approved_policy, policy_ref, key_sign,
  290. check_ticket);
  291. if (rval != TSS2_RC_SUCCESS) {
  292. LOG_PERR(Esys_PolicyAuthorize, rval);
  293. return tool_rc_from_tpm(rval);
  294. }
  295. return tool_rc_success;
  296. }
  297. tool_rc tpm2_policy_or(ESYS_CONTEXT *esys_context, ESYS_TR policy_session,
  298. ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3,
  299. const TPML_DIGEST *p_hash_list) {
  300. TSS2_RC rval = Esys_PolicyOR(esys_context, policy_session, shandle1, shandle2,
  301. shandle3, p_hash_list);
  302. if (rval != TSS2_RC_SUCCESS) {
  303. LOG_PERR(Esys_PolicyAuthorize, rval);
  304. return tool_rc_from_tpm(rval);
  305. }
  306. return tool_rc_success;
  307. }
  308. tool_rc tpm2_policy_namehash(ESYS_CONTEXT *esys_context, ESYS_TR policy_session,
  309. const TPM2B_DIGEST *name_hash) {
  310. TSS2_RC rval = Esys_PolicyNameHash(esys_context, policy_session,
  311. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, name_hash);
  312. if (rval != TSS2_RC_SUCCESS) {
  313. LOG_PERR(Esys_PolicyNameHash, rval);
  314. return tool_rc_from_tpm(rval);
  315. }
  316. return tool_rc_success;
  317. }
  318. tool_rc tpm2_policy_template(ESYS_CONTEXT *esys_context, ESYS_TR policy_session,
  319. const TPM2B_DIGEST *template_hash) {
  320. TSS2_RC rval = Esys_PolicyTemplate(esys_context, policy_session,
  321. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, template_hash);
  322. if (rval != TSS2_RC_SUCCESS) {
  323. LOG_PERR(Esys_PolicyTemplate, rval);
  324. return tool_rc_from_tpm(rval);
  325. }
  326. return tool_rc_success;
  327. }
  328. tool_rc tpm2_policy_cphash(ESYS_CONTEXT *esys_context, ESYS_TR policy_session,
  329. const TPM2B_DIGEST *cphash) {
  330. TSS2_RC rval = Esys_PolicyCpHash(esys_context, policy_session,
  331. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, cphash);
  332. if (rval != TSS2_RC_SUCCESS) {
  333. LOG_PERR(Esys_PolicyCpHash, rval);
  334. return tool_rc_from_tpm(rval);
  335. }
  336. return tool_rc_success;
  337. }
  338. tool_rc tpm2_policy_pcr(ESYS_CONTEXT *esys_context, ESYS_TR policy_session,
  339. ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3,
  340. const TPM2B_DIGEST *pcr_digest, const TPML_PCR_SELECTION *pcrs) {
  341. TSS2_RC rval = Esys_PolicyPCR(esys_context, policy_session, shandle1,
  342. shandle2, shandle3, pcr_digest, pcrs);
  343. if (rval != TSS2_RC_SUCCESS) {
  344. LOG_PERR(Esys_PolicyPCR, rval);
  345. return tool_rc_from_tpm(rval);
  346. }
  347. return tool_rc_success;
  348. }
  349. tool_rc tpm2_policy_password(ESYS_CONTEXT *esys_context, ESYS_TR policy_session,
  350. ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3) {
  351. TSS2_RC rval = Esys_PolicyPassword(esys_context, policy_session, shandle1,
  352. shandle2, shandle3);
  353. if (rval != TSS2_RC_SUCCESS) {
  354. LOG_PERR(Esys_PolicyPassword, rval);
  355. return tool_rc_from_tpm(rval);
  356. }
  357. return tool_rc_success;
  358. }
  359. tool_rc tpm2_policy_signed(ESYS_CONTEXT *esys_context,
  360. tpm2_loaded_object *auth_entity_obj, ESYS_TR policy_session,
  361. const TPMT_SIGNATURE *signature, INT32 expiration,
  362. TPM2B_TIMEOUT **timeout, TPMT_TK_AUTH **policy_ticket,
  363. TPM2B_NONCE *policy_qualifier, TPM2B_NONCE *nonce_tpm,
  364. TPM2B_DIGEST *cphash) {
  365. TSS2_RC rval = Esys_PolicySigned(esys_context, auth_entity_obj->tr_handle,
  366. policy_session, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, nonce_tpm,
  367. cphash, policy_qualifier, expiration, signature, timeout, policy_ticket);
  368. if (rval != TSS2_RC_SUCCESS) {
  369. LOG_PERR(Esys_PolicySigned, rval);
  370. return tool_rc_from_tpm(rval);
  371. }
  372. return tool_rc_success;
  373. }
  374. tool_rc tpm2_policy_ticket(ESYS_CONTEXT *esys_context, ESYS_TR policy_session,
  375. const TPM2B_TIMEOUT *timeout, const TPM2B_NONCE *policyref,
  376. const TPM2B_NAME *authname, const TPMT_TK_AUTH *ticket) {
  377. TSS2_RC rval = Esys_PolicyTicket(esys_context, policy_session, ESYS_TR_NONE,
  378. ESYS_TR_NONE, ESYS_TR_NONE, timeout, NULL, policyref, authname, ticket);
  379. if (rval != TSS2_RC_SUCCESS) {
  380. LOG_PERR(Esys_PolicySigned, rval);
  381. return tool_rc_from_tpm(rval);
  382. }
  383. return tool_rc_success;
  384. }
  385. tool_rc tpm2_policy_authvalue(ESYS_CONTEXT *esys_context,
  386. ESYS_TR policy_session, ESYS_TR shandle1, ESYS_TR shandle2,
  387. ESYS_TR shandle3) {
  388. TSS2_RC rval = Esys_PolicyAuthValue(esys_context, policy_session, shandle1,
  389. shandle2, shandle3);
  390. if (rval != TSS2_RC_SUCCESS) {
  391. LOG_PERR(Esys_PolicyAuthValue, rval);
  392. return tool_rc_from_tpm(rval);
  393. }
  394. return tool_rc_success;
  395. }
  396. tool_rc tpm2_policy_authorize_nv(ESYS_CONTEXT *esys_context,
  397. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nv_index,
  398. ESYS_TR policy_session, TPM2B_DIGEST *cp_hash) {
  399. ESYS_TR esys_tr_nv_index;
  400. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  401. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_index);
  402. if (rval != TPM2_RC_SUCCESS) {
  403. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  404. return tool_rc_from_tpm(rval);
  405. }
  406. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  407. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  408. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  409. &auth_hierarchy_obj_session_handle);
  410. if (rc != tool_rc_success) {
  411. LOG_ERR("Failed to get auth entity obj session");
  412. return rc;
  413. }
  414. if (cp_hash) {
  415. /*
  416. * Need sys_context to be able to calculate CpHash
  417. */
  418. TSS2_SYS_CONTEXT *sys_context = NULL;
  419. rc = tpm2_getsapicontext(esys_context, &sys_context);
  420. if(rc != tool_rc_success) {
  421. LOG_ERR("Failed to acquire SAPI context.");
  422. return rc;
  423. }
  424. rval = Tss2_Sys_PolicyAuthorizeNV_Prepare(sys_context,
  425. auth_hierarchy_obj->handle, nv_index, policy_session);
  426. if (rval != TPM2_RC_SUCCESS) {
  427. LOG_PERR(Tss2_Sys_PolicyAuthorizeNV_Prepare, rval);
  428. return tool_rc_general_error;
  429. }
  430. TPM2B_NAME *name1 = NULL;
  431. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  432. &name1);
  433. if (rc != tool_rc_success) {
  434. goto tpm2_policyauthorizenv_free_name1;
  435. }
  436. TPM2B_NAME *name2 = NULL;
  437. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_index, &name2);
  438. if (rc != tool_rc_success) {
  439. goto tpm2_policyauthorizenv_free_name1_name2;
  440. }
  441. TPM2B_NAME *name3 = NULL;
  442. rc = tpm2_tr_get_name(esys_context, policy_session, &name3);
  443. if (rc != tool_rc_success) {
  444. goto tpm2_policyauthorizenv_free_name1_name2_name3;
  445. }
  446. cp_hash->size = tpm2_alg_util_get_hash_size(
  447. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  448. rc = tpm2_sapi_getcphash(sys_context, name1, name2, name3,
  449. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  450. /*
  451. * Exit here without making the ESYS call since we just need the cpHash
  452. */
  453. tpm2_policyauthorizenv_free_name1_name2_name3:
  454. Esys_Free(name3);
  455. tpm2_policyauthorizenv_free_name1_name2:
  456. Esys_Free(name2);
  457. tpm2_policyauthorizenv_free_name1:
  458. Esys_Free(name1);
  459. goto tpm2_policyauthorizenv_skip_esapi_call;
  460. }
  461. rval = Esys_PolicyAuthorizeNV(esys_context, auth_hierarchy_obj->tr_handle,
  462. esys_tr_nv_index, policy_session, auth_hierarchy_obj_session_handle,
  463. ESYS_TR_NONE, ESYS_TR_NONE);
  464. if (rval != TSS2_RC_SUCCESS) {
  465. LOG_PERR(Esys_PolicyAuthorizeNV, rval);
  466. return tool_rc_from_tpm(rval);
  467. }
  468. tpm2_policyauthorizenv_skip_esapi_call:
  469. return rc;
  470. }
  471. tool_rc tpm2_policy_nv(ESYS_CONTEXT *esys_context,
  472. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nv_index,
  473. ESYS_TR policy_session, const TPM2B_OPERAND *operand_b, UINT16 offset,
  474. TPM2_EO operation, TPM2B_DIGEST *cp_hash) {
  475. ESYS_TR esys_tr_nv_index;
  476. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  477. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_index);
  478. if (rval != TPM2_RC_SUCCESS) {
  479. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  480. return tool_rc_from_tpm(rval);
  481. }
  482. ESYS_TR auth_entity_obj_session_handle = ESYS_TR_NONE;
  483. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  484. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  485. &auth_entity_obj_session_handle);
  486. if (rc != tool_rc_success) {
  487. LOG_ERR("Failed to get auth entity obj session");
  488. return rc;
  489. }
  490. if (cp_hash) {
  491. /*
  492. * Need sys_context to be able to calculate CpHash
  493. */
  494. TSS2_SYS_CONTEXT *sys_context = NULL;
  495. rc = tpm2_getsapicontext(esys_context, &sys_context);
  496. if(rc != tool_rc_success) {
  497. LOG_ERR("Failed to acquire SAPI context.");
  498. return rc;
  499. }
  500. rval = Tss2_Sys_PolicyNV_Prepare(sys_context,
  501. auth_hierarchy_obj->handle, nv_index, policy_session, operand_b,
  502. offset, operation);
  503. if (rval != TPM2_RC_SUCCESS) {
  504. LOG_PERR(Tss2_Sys_PolicyNV_Prepare, rval);
  505. return tool_rc_general_error;
  506. }
  507. TPM2B_NAME *name1 = NULL;
  508. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  509. &name1);
  510. if (rc != tool_rc_success) {
  511. goto tpm2_policynv_free_name1;
  512. }
  513. TPM2B_NAME *name2 = NULL;
  514. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_index, &name2);
  515. if (rc != tool_rc_success) {
  516. goto tpm2_policynv_free_name1_name2;
  517. }
  518. TPM2B_NAME *name3 = NULL;
  519. rc = tpm2_tr_get_name(esys_context, policy_session, &name3);
  520. if (rc != tool_rc_success) {
  521. goto tpm2_policynv_free_name1_name2_name3;
  522. }
  523. cp_hash->size = tpm2_alg_util_get_hash_size(
  524. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  525. rc = tpm2_sapi_getcphash(sys_context, name1, name2, name3,
  526. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  527. /*
  528. * Exit here without making the ESYS call since we just need the cpHash
  529. */
  530. tpm2_policynv_free_name1_name2_name3:
  531. Esys_Free(name3);
  532. tpm2_policynv_free_name1_name2:
  533. Esys_Free(name2);
  534. tpm2_policynv_free_name1:
  535. Esys_Free(name1);
  536. goto tpm2_policynv_skip_esapi_out;
  537. }
  538. rval = Esys_PolicyNV(esys_context, auth_hierarchy_obj->tr_handle,
  539. esys_tr_nv_index, policy_session, auth_entity_obj_session_handle,
  540. ESYS_TR_NONE, ESYS_TR_NONE, operand_b, offset, operation);
  541. if (rval != TSS2_RC_SUCCESS) {
  542. LOG_PERR(Esys_PolicyNV, rval);
  543. return tool_rc_from_tpm(rval);
  544. }
  545. tpm2_policynv_skip_esapi_out:
  546. return rc;
  547. }
  548. tool_rc tpm2_policy_countertimer(ESYS_CONTEXT *esys_context,
  549. ESYS_TR policy_session, const TPM2B_OPERAND *operand_b, UINT16 offset,
  550. TPM2_EO operation) {
  551. TSS2_RC rval = Esys_PolicyCounterTimer(esys_context, policy_session,
  552. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, operand_b, offset, operation);
  553. if (rval != TSS2_RC_SUCCESS) {
  554. LOG_PERR(Esys_PolicyCounterTimer, rval);
  555. return tool_rc_from_tpm(rval);
  556. }
  557. return tool_rc_success;
  558. }
  559. tool_rc tpm2_policy_secret(ESYS_CONTEXT *esys_context,
  560. tpm2_loaded_object *auth_entity_obj, ESYS_TR policy_session,
  561. INT32 expiration, TPMT_TK_AUTH **policy_ticket,
  562. TPM2B_TIMEOUT **timeout, TPM2B_NONCE *nonce_tpm,
  563. TPM2B_NONCE *policy_qualifier, TPM2B_DIGEST *cp_hash) {
  564. const TPM2B_DIGEST *cphash = NULL;
  565. ESYS_TR auth_entity_obj_session_handle = ESYS_TR_NONE;
  566. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  567. auth_entity_obj->tr_handle, auth_entity_obj->session,
  568. &auth_entity_obj_session_handle);
  569. if (rc != tool_rc_success) {
  570. LOG_ERR("Failed to get auth entity obj session");
  571. return rc;
  572. }
  573. if (cp_hash) {
  574. /*
  575. * Need sys_context to be able to calculate CpHash
  576. */
  577. TSS2_SYS_CONTEXT *sys_context = NULL;
  578. rc = tpm2_getsapicontext(esys_context, &sys_context);
  579. if(rc != tool_rc_success) {
  580. LOG_ERR("Failed to acquire SAPI context.");
  581. return rc;
  582. }
  583. TSS2_RC rval = Tss2_Sys_PolicySecret_Prepare(sys_context,
  584. auth_entity_obj->handle, policy_session, nonce_tpm, cphash,
  585. policy_qualifier, expiration);
  586. if (rval != TPM2_RC_SUCCESS) {
  587. LOG_PERR(Tss2_Sys_PolicySecret_Prepare, rval);
  588. return tool_rc_general_error;
  589. }
  590. TPM2B_NAME *name1 = NULL;
  591. rc = tpm2_tr_get_name(esys_context, auth_entity_obj->tr_handle,
  592. &name1);
  593. if (rc != tool_rc_success) {
  594. goto tpm2_policysecret_free_name1;
  595. }
  596. TPM2B_NAME *name2 = NULL;
  597. rc = tpm2_tr_get_name(esys_context, policy_session, &name2);
  598. if (rc != tool_rc_success) {
  599. goto tpm2_policysecret_free_name1_name2;
  600. }
  601. cp_hash->size = tpm2_alg_util_get_hash_size(
  602. tpm2_session_get_authhash(auth_entity_obj->session));
  603. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  604. tpm2_session_get_authhash(auth_entity_obj->session), cp_hash);
  605. /*
  606. * Exit here without making the ESYS call since we just need the cpHash
  607. */
  608. tpm2_policysecret_free_name1_name2:
  609. Esys_Free(name2);
  610. tpm2_policysecret_free_name1:
  611. Esys_Free(name1);
  612. goto tpm2_policysecret_skip_esapi_call;
  613. }
  614. TSS2_RC rval = Esys_PolicySecret(esys_context, auth_entity_obj->tr_handle,
  615. policy_session, auth_entity_obj_session_handle, ESYS_TR_NONE,
  616. ESYS_TR_NONE, nonce_tpm, cphash, policy_qualifier, expiration, timeout,
  617. policy_ticket);
  618. if (rval != TSS2_RC_SUCCESS) {
  619. LOG_PERR(Esys_PolicySecret, rval);
  620. return tool_rc_from_tpm(rval);
  621. }
  622. tpm2_policysecret_skip_esapi_call:
  623. return rc;
  624. }
  625. tool_rc tpm2_policy_getdigest(ESYS_CONTEXT *esys_context, ESYS_TR policy_session,
  626. ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3,
  627. TPM2B_DIGEST **policy_digest) {
  628. TSS2_RC rval = Esys_PolicyGetDigest(esys_context, policy_session, shandle1,
  629. shandle2, shandle3, policy_digest);
  630. if (rval != TSS2_RC_SUCCESS) {
  631. LOG_PERR(Esys_PolicyGetDigest, rval);
  632. return tool_rc_from_tpm(rval);
  633. }
  634. return tool_rc_success;
  635. }
  636. tool_rc tpm2_policy_command_code(ESYS_CONTEXT *esys_context,
  637. ESYS_TR policy_session, ESYS_TR shandle1, ESYS_TR shandle2,
  638. ESYS_TR shandle3, TPM2_CC code) {
  639. TSS2_RC rval = Esys_PolicyCommandCode(esys_context, policy_session, shandle1,
  640. shandle2, shandle3, code);
  641. if (rval != TSS2_RC_SUCCESS) {
  642. LOG_PERR(Esys_PolicyCommandCode, rval);
  643. return tool_rc_from_tpm(rval);
  644. }
  645. return tool_rc_success;
  646. }
  647. tool_rc tpm2_setcommandcodeaudit(ESYS_CONTEXT *esys_context,
  648. tpm2_loaded_object *auth_entity_obj, TPMI_ALG_HASH hash_algorithm,
  649. const TPML_CC *setlist, const TPML_CC *clearlist) {
  650. ESYS_TR auth_entity_obj_session_handle = ESYS_TR_NONE;
  651. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  652. auth_entity_obj->tr_handle, auth_entity_obj->session,
  653. &auth_entity_obj_session_handle);
  654. if (rc != tool_rc_success) {
  655. LOG_ERR("Failed to get auth entity obj session");
  656. return rc;
  657. }
  658. TSS2_RC rval = Esys_SetCommandCodeAuditStatus(esys_context,
  659. auth_entity_obj->tr_handle, auth_entity_obj_session_handle, ESYS_TR_NONE,
  660. ESYS_TR_NONE, hash_algorithm, setlist, clearlist);
  661. if (rval != TSS2_RC_SUCCESS) {
  662. LOG_PERR(Esys_SetCommandCodeAuditStatus, rval);
  663. return tool_rc_from_tpm(rval);
  664. }
  665. return tool_rc_success;
  666. }
  667. tool_rc tpm2_getcommandauditdigest(ESYS_CONTEXT *esys_context,
  668. tpm2_loaded_object *privacy_object, tpm2_loaded_object *sign_object,
  669. TPMT_SIG_SCHEME *in_scheme, TPM2B_DATA *qualifying_data,
  670. TPM2B_ATTEST **audit_info, TPMT_SIGNATURE **signature) {
  671. ESYS_TR privacy_object_session_handle = ESYS_TR_NONE;
  672. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  673. privacy_object->tr_handle, privacy_object->session,
  674. &privacy_object_session_handle);
  675. if (rc != tool_rc_success) {
  676. LOG_ERR("Failed to get auth entity obj session");
  677. return rc;
  678. }
  679. ESYS_TR sign_object_session_handle = ESYS_TR_NONE;
  680. rc = tpm2_auth_util_get_shandle(esys_context,
  681. sign_object->tr_handle, sign_object->session,
  682. &sign_object_session_handle);
  683. if (rc != tool_rc_success) {
  684. LOG_ERR("Failed to get auth entity obj session");
  685. return rc;
  686. }
  687. TSS2_RC rval = Esys_GetCommandAuditDigest(esys_context,
  688. privacy_object->tr_handle, sign_object->tr_handle,
  689. privacy_object_session_handle, sign_object_session_handle,
  690. ESYS_TR_NONE, qualifying_data, in_scheme, audit_info, signature);
  691. if (rval != TSS2_RC_SUCCESS) {
  692. LOG_PERR(Esys_GetCommandAuditDigest, rval);
  693. return tool_rc_from_tpm(rval);
  694. }
  695. return tool_rc_success;
  696. }
  697. static tool_rc evaluate_sessions_for_audit(ESYS_CONTEXT *ectx,
  698. ESYS_TR audit_session_handle) {
  699. //Check if session is an audit session from the attributes
  700. TPMA_SESSION attrs;
  701. tool_rc rc = tpm2_sess_get_attributes(ectx, audit_session_handle,
  702. &attrs);
  703. if (rc != tool_rc_success) {
  704. return rc;
  705. }
  706. if (!(attrs & TPMA_SESSION_AUDIT)) {
  707. LOG_ERR("Session does not have audit attributes setup.");
  708. return tool_rc_general_error;
  709. }
  710. return tool_rc_success;
  711. }
  712. tool_rc tpm2_getsessionauditdigest(ESYS_CONTEXT *esys_context,
  713. tpm2_loaded_object *privacy_object, tpm2_loaded_object *sign_object,
  714. TPMT_SIG_SCHEME *in_scheme, TPM2B_DATA *qualifying_data,
  715. TPM2B_ATTEST **audit_info, TPMT_SIGNATURE **signature,
  716. ESYS_TR audit_session_handle) {
  717. tool_rc rc = audit_session_handle == ESYS_TR_NONE ? tool_rc_general_error :
  718. evaluate_sessions_for_audit(esys_context, audit_session_handle);
  719. if (rc != tool_rc_success) {
  720. return rc;
  721. }
  722. ESYS_TR privacy_object_session_handle = ESYS_TR_NONE;
  723. rc = tpm2_auth_util_get_shandle(esys_context,
  724. privacy_object->tr_handle, privacy_object->session,
  725. &privacy_object_session_handle);
  726. if (rc != tool_rc_success) {
  727. LOG_ERR("Failed to get auth entity obj session");
  728. return rc;
  729. }
  730. ESYS_TR sign_object_session_handle = ESYS_TR_NONE;
  731. rc = tpm2_auth_util_get_shandle(esys_context,
  732. sign_object->tr_handle, sign_object->session,
  733. &sign_object_session_handle);
  734. if (rc != tool_rc_success) {
  735. LOG_ERR("Failed to get auth entity obj session");
  736. return rc;
  737. }
  738. TSS2_RC rval = Esys_GetSessionAuditDigest(esys_context,
  739. privacy_object->tr_handle, sign_object->tr_handle,
  740. audit_session_handle, privacy_object_session_handle,
  741. sign_object_session_handle, ESYS_TR_NONE, qualifying_data, in_scheme,
  742. audit_info, signature);
  743. if (rval != TSS2_RC_SUCCESS) {
  744. LOG_PERR(Esys_GetCommandAuditDigest, rval);
  745. return tool_rc_from_tpm(rval);
  746. }
  747. return tool_rc_success;
  748. }
  749. tool_rc tpm2_policy_nv_written(ESYS_CONTEXT *esys_context,
  750. ESYS_TR policy_session, ESYS_TR shandle1, ESYS_TR shandle2,
  751. ESYS_TR shandle3, TPMI_YES_NO written_set) {
  752. TSS2_RC rval = Esys_PolicyNvWritten(esys_context, policy_session, shandle1,
  753. shandle2, shandle3, written_set);
  754. if (rval != TSS2_RC_SUCCESS) {
  755. LOG_PERR(Esys_PolicyNVWritten, rval);
  756. return tool_rc_from_tpm(rval);
  757. }
  758. return tool_rc_success;
  759. }
  760. tool_rc tpm2_policy_locality(ESYS_CONTEXT *esys_context, ESYS_TR policy_session,
  761. ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3,
  762. TPMA_LOCALITY locality) {
  763. TSS2_RC rval = Esys_PolicyLocality(esys_context, policy_session, shandle1,
  764. shandle2, shandle3, locality);
  765. if (rval != TSS2_RC_SUCCESS) {
  766. LOG_PERR(Esys_PolicyLocality, rval);
  767. return tool_rc_from_tpm(rval);
  768. }
  769. return tool_rc_success;
  770. }
  771. tool_rc tpm2_policy_duplication_select(ESYS_CONTEXT *esys_context,
  772. ESYS_TR policy_session, ESYS_TR shandle1, ESYS_TR shandle2,
  773. ESYS_TR shandle3, const TPM2B_NAME *object_name,
  774. const TPM2B_NAME *new_parent_name, TPMI_YES_NO include_object) {
  775. TSS2_RC rval = Esys_PolicyDuplicationSelect(esys_context, policy_session,
  776. shandle1, shandle2, shandle3, object_name, new_parent_name,
  777. include_object);
  778. if (rval != TSS2_RC_SUCCESS) {
  779. LOG_PERR(Esys_PolicyDuplicationSelect, rval);
  780. return tool_rc_from_tpm(rval);
  781. }
  782. return tool_rc_success;
  783. }
  784. tool_rc tpm2_mu_tpm2_handle_unmarshal(uint8_t const buffer[], size_t size,
  785. size_t *offset, TPM2_HANDLE *out) {
  786. TSS2_RC rval = Tss2_MU_TPM2_HANDLE_Unmarshal(buffer, size, offset, out);
  787. if (rval != TSS2_RC_SUCCESS) {
  788. LOG_PERR(Tss2_MU_TPM2_HANDLE_Unmarshal, rval);
  789. return tool_rc_from_tpm(rval);
  790. }
  791. return tool_rc_success;
  792. }
  793. tool_rc tpm2_mu_tpmt_public_marshal(TPMT_PUBLIC const *src, uint8_t buffer[],
  794. size_t buffer_size, size_t *offset) {
  795. TSS2_RC rval = Tss2_MU_TPMT_PUBLIC_Marshal(src, buffer, buffer_size,
  796. offset);
  797. if (rval != TSS2_RC_SUCCESS) {
  798. LOG_PERR(Tss2_MU_TPMT_PUBLIC_Marshal, rval);
  799. return tool_rc_from_tpm(rval);
  800. }
  801. return tool_rc_success;
  802. }
  803. tool_rc tpm2_evictcontrol(ESYS_CONTEXT *esys_context,
  804. tpm2_loaded_object *auth_hierarchy_obj,
  805. tpm2_loaded_object *to_persist_key_obj,
  806. TPMI_DH_PERSISTENT persistent_handle, ESYS_TR *new_object_handle,
  807. TPM2B_DIGEST *cp_hash) {
  808. ESYS_TR shandle1 = ESYS_TR_NONE;
  809. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  810. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  811. &shandle1);
  812. if (rc != tool_rc_success) {
  813. return rc;
  814. }
  815. if (cp_hash) {
  816. /*
  817. * Need sys_context to be able to calculate CpHash
  818. */
  819. TSS2_SYS_CONTEXT *sys_context = NULL;
  820. rc = tpm2_getsapicontext(esys_context, &sys_context);
  821. if(rc != tool_rc_success) {
  822. LOG_ERR("Failed to acquire SAPI context.");
  823. return rc;
  824. }
  825. TSS2_RC rval = Tss2_Sys_EvictControl_Prepare(sys_context,
  826. auth_hierarchy_obj->handle, to_persist_key_obj->handle,
  827. persistent_handle);
  828. if (rval != TPM2_RC_SUCCESS) {
  829. LOG_PERR(Tss2_Sys_EvictControl_Prepare, rval);
  830. return tool_rc_general_error;
  831. }
  832. TPM2B_NAME *name1 = NULL;
  833. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  834. &name1);
  835. if (rc != tool_rc_success) {
  836. goto tpm2_evictcontrol_free_name1;
  837. }
  838. TPM2B_NAME *name2 = NULL;
  839. rc = tpm2_tr_get_name(esys_context, to_persist_key_obj->tr_handle, &name2);
  840. if (rc != tool_rc_success) {
  841. goto tpm2_evictcontrol_free_name1_name2;
  842. }
  843. cp_hash->size = tpm2_alg_util_get_hash_size(
  844. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  845. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  846. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  847. /*
  848. * Exit here without making the ESYS call since we just need the cpHash
  849. */
  850. tpm2_evictcontrol_free_name1_name2:
  851. Esys_Free(name2);
  852. tpm2_evictcontrol_free_name1:
  853. Esys_Free(name1);
  854. goto tpm2_evictcontrol_skip_esapi_call;
  855. }
  856. TSS2_RC rval = Esys_EvictControl(esys_context, auth_hierarchy_obj->tr_handle,
  857. to_persist_key_obj->tr_handle, shandle1, ESYS_TR_NONE, ESYS_TR_NONE,
  858. persistent_handle, new_object_handle);
  859. if (rval != TSS2_RC_SUCCESS) {
  860. LOG_PERR(Esys_EvictControl, rval);
  861. return tool_rc_from_tpm(rval);
  862. }
  863. tpm2_evictcontrol_skip_esapi_call:
  864. return rc;
  865. }
  866. /* This function addresses ESAPI change that changes parameter type from
  867. * Esys_TR to TPMI_RH_HIERARCHY or TPMI_RH_ENABLES and breaks backwards
  868. * compatibility.
  869. * To keep the tools parameters consistent after v4.0 release we need to
  870. * map the values to appropriate type based on the version of the ESYS API.
  871. * Note: the mapping is based on the ESYS version recognized at compile time.
  872. * The TSS change can be found here:
  873. * https://github.com/tpm2-software/tpm2-tss/pull/1531
  874. */
  875. TSS2_RC fix_esys_hierarchy(uint32_t in, uint32_t *out)
  876. {
  877. #if defined(ESYS_3_0)
  878. switch (in) {
  879. case ESYS_TR_RH_NULL:
  880. /* FALLTHRU */
  881. case ESYS_TR_RH_OWNER:
  882. /* FALLTHRU */
  883. case ESYS_TR_RH_ENDORSEMENT:
  884. /* FALLTHRU */
  885. case ESYS_TR_RH_PLATFORM:
  886. /* FALLTHRU */
  887. case ESYS_TR_RH_PLATFORM_NV:
  888. *out = in;
  889. return TSS2_RC_SUCCESS;
  890. case TPM2_RH_NULL:
  891. *out = ESYS_TR_RH_NULL;
  892. return TSS2_RC_SUCCESS;
  893. case TPM2_RH_OWNER:
  894. *out = ESYS_TR_RH_OWNER;
  895. return TSS2_RC_SUCCESS;
  896. case TPM2_RH_ENDORSEMENT:
  897. *out = ESYS_TR_RH_ENDORSEMENT;
  898. return TSS2_RC_SUCCESS;
  899. case TPM2_RH_PLATFORM:
  900. *out = ESYS_TR_RH_PLATFORM;
  901. return TSS2_RC_SUCCESS;
  902. case TPM2_RH_PLATFORM_NV:
  903. *out = ESYS_TR_RH_PLATFORM_NV;
  904. return TSS2_RC_SUCCESS;
  905. default:
  906. LOG_ERR("An unknown hierarchy handle was passed: 0x%08x", in);
  907. return TSS2_ESYS_RC_BAD_VALUE;
  908. }
  909. #elif defined(ESYS_2_3)
  910. *out = in;
  911. return TSS2_RC_SUCCESS;
  912. #else
  913. #error "Need to define either ESYS_3_0 or ESYS_2_3"
  914. #endif
  915. }
  916. tool_rc tpm2_hash(ESYS_CONTEXT *esys_context, ESYS_TR shandle1, ESYS_TR shandle2,
  917. ESYS_TR shandle3, const TPM2B_MAX_BUFFER *data, TPMI_ALG_HASH hash_alg,
  918. TPMI_RH_HIERARCHY hierarchy, TPM2B_DIGEST **out_hash,
  919. TPMT_TK_HASHCHECK **validation) {
  920. TSS2_RC rval = fix_esys_hierarchy(hierarchy, &hierarchy);
  921. if (rval != TSS2_RC_SUCCESS) {
  922. LOG_ERR("Unknown hierarchy");
  923. return tool_rc_from_tpm(rval);
  924. }
  925. rval = Esys_Hash(esys_context, shandle1, shandle2, shandle3, data,
  926. hash_alg, hierarchy, out_hash, validation);
  927. if (rval != TSS2_RC_SUCCESS) {
  928. LOG_PERR(Esys_Hash, rval);
  929. return tool_rc_from_tpm(rval);
  930. }
  931. return tool_rc_success;
  932. }
  933. tool_rc tpm2_hash_sequence_start(ESYS_CONTEXT *esys_context, const TPM2B_AUTH *auth,
  934. TPMI_ALG_HASH hash_alg, ESYS_TR *sequence_handle) {
  935. TSS2_RC rval = Esys_HashSequenceStart(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
  936. ESYS_TR_NONE, auth, hash_alg, sequence_handle);
  937. if (rval != TSS2_RC_SUCCESS) {
  938. LOG_PERR(Esys_HashSequenceStart, rval);
  939. return tool_rc_from_tpm(rval);
  940. }
  941. return tpm2_tr_set_auth(esys_context, *sequence_handle, auth);
  942. }
  943. tool_rc tpm2_sequence_update(ESYS_CONTEXT *esys_context, ESYS_TR sequence_handle,
  944. const TPM2B_MAX_BUFFER *buffer) {
  945. TSS2_RC rval = Esys_SequenceUpdate(esys_context, sequence_handle, ESYS_TR_PASSWORD,
  946. ESYS_TR_NONE, ESYS_TR_NONE, buffer);
  947. if (rval != TSS2_RC_SUCCESS) {
  948. LOG_PERR(Esys_SequenceUpdate, rval);
  949. return tool_rc_from_tpm(rval);
  950. }
  951. return tool_rc_success;
  952. }
  953. tool_rc tpm2_sequence_complete(ESYS_CONTEXT *esys_context,
  954. ESYS_TR sequence_handle, const TPM2B_MAX_BUFFER *buffer,
  955. TPMI_RH_HIERARCHY hierarchy, TPM2B_DIGEST **result,
  956. TPMT_TK_HASHCHECK **validation) {
  957. TSS2_RC rval = fix_esys_hierarchy(hierarchy, &hierarchy);
  958. if (rval != TSS2_RC_SUCCESS) {
  959. LOG_ERR("Unknown hierarchy");
  960. return tool_rc_from_tpm(rval);
  961. }
  962. rval = Esys_SequenceComplete(esys_context, sequence_handle,
  963. ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, buffer,
  964. hierarchy, result, validation);
  965. if (rval != TSS2_RC_SUCCESS) {
  966. LOG_PERR(Esys_SequenceComplete, rval);
  967. return tool_rc_from_tpm(rval);
  968. }
  969. return tool_rc_success;
  970. }
  971. tool_rc tpm2_event_sequence_complete(ESYS_CONTEXT *ectx, ESYS_TR pcr,
  972. ESYS_TR sequence_handle, tpm2_session *session,
  973. const TPM2B_MAX_BUFFER *buffer, TPML_DIGEST_VALUES **results) {
  974. ESYS_TR shandle1 = ESYS_TR_NONE;
  975. tool_rc rc = tpm2_auth_util_get_shandle(ectx, pcr, session,
  976. &shandle1);
  977. if (rc != tool_rc_success) {
  978. return rc;
  979. }
  980. TSS2_RC rval = Esys_EventSequenceComplete(ectx, pcr, sequence_handle, shandle1,
  981. ESYS_TR_PASSWORD, ESYS_TR_NONE, buffer, results);
  982. if (rval != TSS2_RC_SUCCESS) {
  983. LOG_PERR(Esys_EventSequenceComplete, rval);
  984. return tool_rc_from_tpm(rval);
  985. }
  986. return tool_rc_success;
  987. }
  988. tool_rc tpm2_tr_set_auth(ESYS_CONTEXT *esys_context, ESYS_TR handle,
  989. TPM2B_AUTH const *auth_value) {
  990. TSS2_RC rval = Esys_TR_SetAuth(esys_context, handle, auth_value);
  991. if (rval != TSS2_RC_SUCCESS) {
  992. LOG_PERR(Esys_SequenceComplete, rval);
  993. return tool_rc_from_tpm(rval);
  994. }
  995. return tool_rc_success;
  996. }
  997. tool_rc tpm2_activatecredential(ESYS_CONTEXT *esys_context,
  998. tpm2_loaded_object *activatehandleobj, tpm2_loaded_object *keyhandleobj,
  999. const TPM2B_ID_OBJECT *credential_blob, const TPM2B_ENCRYPTED_SECRET *secret,
  1000. TPM2B_DIGEST **cert_info, TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
  1001. TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle3) {
  1002. TSS2_SYS_CONTEXT *sys_context = NULL;
  1003. tool_rc rc = tool_rc_success;
  1004. if (cp_hash->size || rp_hash->size) {
  1005. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1006. if(rc != tool_rc_success) {
  1007. LOG_ERR("Failed to acquire SAPI context.");
  1008. return rc;
  1009. }
  1010. }
  1011. if (cp_hash->size) {
  1012. TSS2_RC rval = Tss2_Sys_ActivateCredential_Prepare(sys_context,
  1013. activatehandleobj->handle, keyhandleobj->handle, credential_blob,
  1014. secret);
  1015. if (rval != TPM2_RC_SUCCESS) {
  1016. LOG_PERR(Tss2_Sys_ActivateCredential_Prepare, rval);
  1017. return tool_rc_general_error;
  1018. }
  1019. TPM2B_NAME *name1 = NULL;
  1020. rc = tpm2_tr_get_name(esys_context, activatehandleobj->tr_handle,
  1021. &name1);
  1022. if (rc != tool_rc_success) {
  1023. goto tpm2_activatecredential_free_name1;
  1024. }
  1025. TPM2B_NAME *name2 = NULL;
  1026. rc = tpm2_tr_get_name(esys_context, keyhandleobj->tr_handle, &name2);
  1027. if (rc != tool_rc_success) {
  1028. goto tpm2_activatecredential_free_name1_name2;
  1029. }
  1030. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  1031. parameter_hash_algorithm, cp_hash);
  1032. tpm2_activatecredential_free_name1_name2:
  1033. Esys_Free(name2);
  1034. tpm2_activatecredential_free_name1:
  1035. Esys_Free(name1);
  1036. /*
  1037. * Exit here without making the ESYS call since we just need the cpHash
  1038. */
  1039. if (!rp_hash->size) {
  1040. goto tpm2_activatecredential_skip_esapi_call;
  1041. }
  1042. }
  1043. ESYS_TR keyobj_session_handle = ESYS_TR_NONE;
  1044. rc = tpm2_auth_util_get_shandle(esys_context,
  1045. keyhandleobj->tr_handle, keyhandleobj->session,
  1046. &keyobj_session_handle); //shandle1
  1047. if (rc != tool_rc_success) {
  1048. return rc;
  1049. }
  1050. ESYS_TR activateobj_session_handle = ESYS_TR_NONE;
  1051. rc = tpm2_auth_util_get_shandle(esys_context, activatehandleobj->tr_handle,
  1052. activatehandleobj->session, &activateobj_session_handle);
  1053. if (rc != tool_rc_success) {
  1054. return rc;
  1055. }
  1056. TSS2_RC rval = Esys_ActivateCredential(esys_context,
  1057. activatehandleobj->tr_handle, keyhandleobj->tr_handle,
  1058. activateobj_session_handle, keyobj_session_handle, shandle3,
  1059. credential_blob, secret, cert_info);
  1060. if (rval != TPM2_RC_SUCCESS) {
  1061. LOG_PERR(Esys_ActivateCredential, rval);
  1062. rc = tool_rc_from_tpm(rval);
  1063. return rc;
  1064. }
  1065. if (rp_hash->size) {
  1066. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  1067. parameter_hash_algorithm);
  1068. }
  1069. tpm2_activatecredential_skip_esapi_call:
  1070. return rc;
  1071. }
  1072. tool_rc tpm2_create(ESYS_CONTEXT *esys_context, tpm2_loaded_object *parent_obj,
  1073. const TPM2B_SENSITIVE_CREATE *in_sensitive, const TPM2B_PUBLIC *in_public,
  1074. const TPM2B_DATA *outside_info, const TPML_PCR_SELECTION *creation_pcr,
  1075. TPM2B_PRIVATE **out_private, TPM2B_PUBLIC **out_public,
  1076. TPM2B_CREATION_DATA **creation_data, TPM2B_DIGEST **creation_hash,
  1077. TPMT_TK_CREATION **creation_ticket, TPM2B_DIGEST *cp_hash,
  1078. TPM2B_DIGEST *rp_hash, TPMI_ALG_HASH parameter_hash_algorithm,
  1079. ESYS_TR shandle2, ESYS_TR shandle3) {
  1080. TSS2_SYS_CONTEXT *sys_context = NULL;
  1081. tool_rc rc = tool_rc_success;
  1082. if (cp_hash->size || rp_hash->size) {
  1083. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1084. if(rc != tool_rc_success) {
  1085. LOG_ERR("Failed to acquire SAPI context.");
  1086. return rc;
  1087. }
  1088. }
  1089. if (cp_hash->size) {
  1090. TSS2_RC rval = Tss2_Sys_Create_Prepare(sys_context, parent_obj->handle,
  1091. in_sensitive, in_public, outside_info, creation_pcr);
  1092. if (rval != TPM2_RC_SUCCESS) {
  1093. LOG_PERR(Tss2_Sys_Create_Prepare, rval);
  1094. return tool_rc_general_error;
  1095. }
  1096. TPM2B_NAME *name1 = NULL;
  1097. rc = tpm2_tr_get_name(esys_context, parent_obj->tr_handle,
  1098. &name1);
  1099. if (rc != tool_rc_success) {
  1100. goto tpm2_create_free_name1;
  1101. }
  1102. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1103. parameter_hash_algorithm, cp_hash);
  1104. tpm2_create_free_name1:
  1105. Esys_Free(name1);
  1106. if (rc != tool_rc_success) {
  1107. return rc;
  1108. }
  1109. /*
  1110. * Exit here without making the ESYS call since we just need the cpHash
  1111. */
  1112. if (!rp_hash->size) {
  1113. goto tpm2_create_skip_esapi_call;
  1114. }
  1115. }
  1116. ESYS_TR shandle1 = ESYS_TR_NONE;
  1117. rc = tpm2_auth_util_get_shandle(esys_context, parent_obj->tr_handle,
  1118. parent_obj->session, &shandle1);
  1119. if (rc != tool_rc_success) {
  1120. return rc;
  1121. }
  1122. TSS2_RC rval = Esys_Create(esys_context, parent_obj->tr_handle, shandle1,
  1123. shandle2, shandle3, in_sensitive, in_public, outside_info,
  1124. creation_pcr, out_private, out_public, creation_data, creation_hash,
  1125. creation_ticket);
  1126. if (rval != TSS2_RC_SUCCESS) {
  1127. LOG_PERR(Esys_Create, rval);
  1128. return tool_rc_from_tpm(rval);
  1129. }
  1130. if (rp_hash->size) {
  1131. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  1132. parameter_hash_algorithm);
  1133. }
  1134. tpm2_create_skip_esapi_call:
  1135. return rc;
  1136. }
  1137. tool_rc tpm2_create_loaded(ESYS_CONTEXT *esys_context,
  1138. tpm2_loaded_object *parent_obj,
  1139. const TPM2B_SENSITIVE_CREATE *in_sensitive,
  1140. const TPM2B_TEMPLATE *in_public, ESYS_TR *object_handle,
  1141. TPM2B_PRIVATE **out_private, TPM2B_PUBLIC **out_public,
  1142. TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
  1143. TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle2,
  1144. ESYS_TR shandle3) {
  1145. TSS2_SYS_CONTEXT *sys_context = NULL;
  1146. tool_rc rc = tool_rc_success;
  1147. if (cp_hash->size || rp_hash->size) {
  1148. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1149. if(rc != tool_rc_success) {
  1150. LOG_ERR("Failed to acquire SAPI context.");
  1151. return rc;
  1152. }
  1153. }
  1154. if (cp_hash->size) {
  1155. TSS2_RC rval = Tss2_Sys_CreateLoaded_Prepare(sys_context,
  1156. parent_obj->handle, in_sensitive, in_public);
  1157. if (rval != TPM2_RC_SUCCESS) {
  1158. LOG_PERR(Tss2_Sys_CreateLoaded_Prepare, rval);
  1159. return tool_rc_general_error;
  1160. }
  1161. TPM2B_NAME *name1 = NULL;
  1162. rc = tpm2_tr_get_name(esys_context, parent_obj->tr_handle,
  1163. &name1);
  1164. if (rc != tool_rc_success) {
  1165. goto tpm2_createloaded_free_name1;
  1166. }
  1167. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1168. parameter_hash_algorithm, cp_hash);
  1169. tpm2_createloaded_free_name1:
  1170. Esys_Free(name1);
  1171. if (rc != tool_rc_success) {
  1172. return rc;
  1173. }
  1174. /*
  1175. * Exit here without making the ESYS call since we just need the cpHash
  1176. */
  1177. if (!rp_hash->size) {
  1178. goto tpm2_createloaded_skip_esapi_call;
  1179. }
  1180. }
  1181. ESYS_TR shandle1 = ESYS_TR_NONE;
  1182. rc = tpm2_auth_util_get_shandle(esys_context, parent_obj->tr_handle,
  1183. parent_obj->session, &shandle1);
  1184. if (rc != tool_rc_success) {
  1185. return rc;
  1186. }
  1187. TSS2_RC rval = Esys_CreateLoaded(esys_context, parent_obj->tr_handle,
  1188. shandle1, shandle2, shandle3, in_sensitive, in_public,
  1189. object_handle, out_private, out_public);
  1190. if (rval != TSS2_RC_SUCCESS) {
  1191. LOG_PERR(Esys_CreateLoaded, rval);
  1192. return tool_rc_from_tpm(rval);
  1193. }
  1194. if (rp_hash->size) {
  1195. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  1196. parameter_hash_algorithm);
  1197. }
  1198. tpm2_createloaded_skip_esapi_call:
  1199. return rc;
  1200. }
  1201. tool_rc tpm2_object_change_auth(ESYS_CONTEXT *esys_context,
  1202. tpm2_loaded_object *parent_object, tpm2_loaded_object *object,
  1203. const TPM2B_AUTH *new_auth, TPM2B_PRIVATE **out_private,
  1204. TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
  1205. TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle2,
  1206. ESYS_TR shandle3) {
  1207. TSS2_SYS_CONTEXT *sys_context = NULL;
  1208. tool_rc rc = tool_rc_success;
  1209. if (cp_hash->size || rp_hash->size) {
  1210. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1211. if(rc != tool_rc_success) {
  1212. LOG_ERR("Failed to acquire SAPI context.");
  1213. return rc;
  1214. }
  1215. }
  1216. if (cp_hash->size) {
  1217. TSS2_RC rval = Tss2_Sys_ObjectChangeAuth_Prepare(sys_context,
  1218. object->handle, parent_object->handle, new_auth);
  1219. if (rval != TPM2_RC_SUCCESS) {
  1220. LOG_PERR(Tss2_Sys_ObjectChangeAuth_Prepare, rval);
  1221. return tool_rc_general_error;
  1222. }
  1223. TPM2B_NAME *name1 = NULL;
  1224. rc = tpm2_tr_get_name(esys_context, object->tr_handle, &name1);
  1225. if (rc != tool_rc_success) {
  1226. goto tpm2_objectchangeauth_free_name1;
  1227. }
  1228. TPM2B_NAME *name2 = NULL;
  1229. rc = tpm2_tr_get_name(esys_context, parent_object->tr_handle,
  1230. &name2);
  1231. if (rc != tool_rc_success) {
  1232. goto tpm2_objectchangeauth_free_name1_name2;
  1233. }
  1234. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  1235. parameter_hash_algorithm, cp_hash);
  1236. tpm2_objectchangeauth_free_name1_name2:
  1237. Esys_Free(name2);
  1238. tpm2_objectchangeauth_free_name1:
  1239. Esys_Free(name1);
  1240. /*
  1241. * Exit here without making the ESYS call since we just need the cpHash
  1242. */
  1243. if (!rp_hash->size || rc != tool_rc_success) {
  1244. goto tpm2_objectchangeauth_skip_esapi_call;
  1245. }
  1246. }
  1247. ESYS_TR shandle1 = ESYS_TR_NONE;
  1248. rc = tpm2_auth_util_get_shandle(esys_context, object->tr_handle,
  1249. object->session, &shandle1);
  1250. if (rc != tool_rc_success) {
  1251. return rc;
  1252. }
  1253. TSS2_RC rval = Esys_ObjectChangeAuth(esys_context, object->tr_handle,
  1254. parent_object->tr_handle, shandle1, shandle2, shandle3,
  1255. new_auth, out_private);
  1256. if (rval != TPM2_RC_SUCCESS) {
  1257. LOG_PERR(Esys_ObjectChangeAuth, rval);
  1258. return tool_rc_from_tpm(rval);
  1259. }
  1260. if (rp_hash->size) {
  1261. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  1262. parameter_hash_algorithm);
  1263. }
  1264. tpm2_objectchangeauth_skip_esapi_call:
  1265. return rc;
  1266. }
  1267. tool_rc tpm2_nv_change_auth(ESYS_CONTEXT *esys_context, tpm2_loaded_object *nv,
  1268. const TPM2B_AUTH *new_auth, TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
  1269. TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle2,
  1270. ESYS_TR shandle3) {
  1271. TSS2_SYS_CONTEXT *sys_context = NULL;
  1272. tool_rc rc = (cp_hash->size || rp_hash->size) ?
  1273. tpm2_getsapicontext(esys_context, &sys_context) : tool_rc_success;
  1274. if(rc != tool_rc_success) {
  1275. LOG_ERR("Failed to acquire SAPI context.");
  1276. return rc;
  1277. }
  1278. if (cp_hash->size) {
  1279. TSS2_RC rval = Tss2_Sys_NV_ChangeAuth_Prepare(sys_context, nv->handle,
  1280. new_auth);
  1281. if (rval != TPM2_RC_SUCCESS) {
  1282. LOG_PERR(Tss2_Sys_NV_ChangeAuth_Prepare, rval);
  1283. return tool_rc_general_error;
  1284. }
  1285. TPM2B_NAME *name1 = NULL;
  1286. rc = tpm2_tr_get_name(esys_context, nv->tr_handle, &name1);
  1287. if (rc != tool_rc_success) {
  1288. goto tpm2_nvchangeauth_free_name1;
  1289. }
  1290. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1291. parameter_hash_algorithm, cp_hash);
  1292. tpm2_nvchangeauth_free_name1:
  1293. Esys_Free(name1);
  1294. /*
  1295. * Exit here without making the ESYS call since we just need the cpHash
  1296. */
  1297. if (!rp_hash->size || rc != tool_rc_success) {
  1298. goto tpm2_nvchangeauth_skip_esapi_call;
  1299. }
  1300. }
  1301. ESYS_TR shandle1 = ESYS_TR_NONE;
  1302. rc = tpm2_auth_util_get_shandle(esys_context, nv->tr_handle, nv->session,
  1303. &shandle1);
  1304. if (rc != tool_rc_success) {
  1305. return rc;
  1306. }
  1307. TSS2_RC rval = Esys_NV_ChangeAuth(esys_context, nv->tr_handle, shandle1,
  1308. shandle2, shandle3, new_auth);
  1309. if (rval != TPM2_RC_SUCCESS) {
  1310. LOG_PERR(Esys_NV_ChangeAuth, rval);
  1311. return tool_rc_from_tpm(rval);
  1312. }
  1313. if (rp_hash->size) {
  1314. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  1315. parameter_hash_algorithm);
  1316. }
  1317. tpm2_nvchangeauth_skip_esapi_call:
  1318. return rc;
  1319. }
  1320. tool_rc tpm2_hierarchy_change_auth(ESYS_CONTEXT *esys_context,
  1321. tpm2_loaded_object *hierarchy, const TPM2B_AUTH *new_auth,
  1322. TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
  1323. TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle2,
  1324. ESYS_TR shandle3) {
  1325. TSS2_SYS_CONTEXT *sys_context = NULL;
  1326. tool_rc rc = (cp_hash->size || rp_hash->size) ?
  1327. tpm2_getsapicontext(esys_context, &sys_context) : tool_rc_success;
  1328. if(rc != tool_rc_success) {
  1329. LOG_ERR("Failed to acquire SAPI context.");
  1330. return rc;
  1331. }
  1332. if (cp_hash->size) {
  1333. TSS2_RC rval = Tss2_Sys_HierarchyChangeAuth_Prepare(sys_context,
  1334. hierarchy->handle, new_auth);
  1335. if (rval != TPM2_RC_SUCCESS) {
  1336. LOG_PERR(Tss2_Sys_HierarchyChangeAuth_Prepare, rval);
  1337. return tool_rc_general_error;
  1338. }
  1339. TPM2B_NAME *name1 = NULL;
  1340. rc = tpm2_tr_get_name(esys_context, hierarchy->tr_handle, &name1);
  1341. if (rc != tool_rc_success) {
  1342. goto tpm2_hierarchychangeauth_free_name1;
  1343. }
  1344. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1345. parameter_hash_algorithm, cp_hash);
  1346. tpm2_hierarchychangeauth_free_name1:
  1347. Esys_Free(name1);
  1348. /*
  1349. * Exit here without making the ESYS call since we just need the cpHash
  1350. */
  1351. if (!rp_hash->size || rc != tool_rc_success) {
  1352. goto tpm2_hierarchychangeauth_skip_esapi_call;
  1353. }
  1354. }
  1355. ESYS_TR shandle1 = ESYS_TR_NONE;
  1356. rc = tpm2_auth_util_get_shandle(esys_context, hierarchy->tr_handle,
  1357. hierarchy->session, &shandle1);
  1358. if (rc != tool_rc_success) {
  1359. return rc;
  1360. }
  1361. TSS2_RC rval = Esys_HierarchyChangeAuth(esys_context, hierarchy->tr_handle,
  1362. shandle1, shandle2, shandle3, new_auth);
  1363. if (rval != TPM2_RC_SUCCESS) {
  1364. LOG_PERR(Esys_HierarchyChangeAuth, rval);
  1365. return tool_rc_from_tpm(rval);
  1366. }
  1367. if (rp_hash->size) {
  1368. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  1369. parameter_hash_algorithm);
  1370. }
  1371. tpm2_hierarchychangeauth_skip_esapi_call:
  1372. return rc;
  1373. }
  1374. tool_rc tpm2_certify(ESYS_CONTEXT *ectx, tpm2_loaded_object *certifiedkey_obj,
  1375. tpm2_loaded_object *signingkey_obj, TPM2B_DATA *qualifying_data,
  1376. TPMT_SIG_SCHEME *scheme, TPM2B_ATTEST **certify_info,
  1377. TPMT_SIGNATURE **signature, TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
  1378. TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle3) {
  1379. TSS2_SYS_CONTEXT *sys_context = NULL;
  1380. tool_rc rc = tool_rc_success;
  1381. if (cp_hash->size || rp_hash->size) {
  1382. rc = tpm2_getsapicontext(ectx, &sys_context);
  1383. if(rc != tool_rc_success) {
  1384. LOG_ERR("Failed to acquire SAPI context.");
  1385. return rc;
  1386. }
  1387. }
  1388. if (cp_hash->size) {
  1389. TSS2_RC rval = Tss2_Sys_Certify_Prepare(sys_context,
  1390. certifiedkey_obj->handle, signingkey_obj->handle, qualifying_data,
  1391. scheme);
  1392. if (rval != TPM2_RC_SUCCESS) {
  1393. LOG_PERR(Tss2_Sys_Certify_Prepare, rval);
  1394. return tool_rc_general_error;
  1395. }
  1396. TPM2B_NAME *name1 = NULL;
  1397. rc = tpm2_tr_get_name(ectx, certifiedkey_obj->tr_handle, &name1);
  1398. if (rc != tool_rc_success) {
  1399. goto tpm2_certify_free_name1;
  1400. }
  1401. TPM2B_NAME *name2 = NULL;
  1402. rc = tpm2_tr_get_name(ectx, signingkey_obj->tr_handle, &name2);
  1403. if (rc != tool_rc_success) {
  1404. goto tpm2_certify_free_name1_name2;
  1405. }
  1406. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  1407. parameter_hash_algorithm, cp_hash);
  1408. tpm2_certify_free_name1_name2:
  1409. Esys_Free(name2);
  1410. tpm2_certify_free_name1:
  1411. Esys_Free(name1);
  1412. /*
  1413. * Exit here without making the ESYS call since we just need the cpHash
  1414. */
  1415. if (!rp_hash->size || rc != tool_rc_success) {
  1416. goto tpm2_certify_skip_esapi_call;
  1417. }
  1418. }
  1419. ESYS_TR certifiedkey_session_handle = ESYS_TR_NONE;
  1420. rc = tpm2_auth_util_get_shandle(ectx, certifiedkey_obj->tr_handle,
  1421. certifiedkey_obj->session, &certifiedkey_session_handle);
  1422. if (rc != tool_rc_success) {
  1423. LOG_ERR("Failed to get session handle for TPM object");
  1424. return rc;
  1425. }
  1426. ESYS_TR signingkey_session_handle = ESYS_TR_NONE;
  1427. rc = tpm2_auth_util_get_shandle(ectx, signingkey_obj->tr_handle,
  1428. signingkey_obj->session, &signingkey_session_handle);
  1429. if (rc != tool_rc_success) {
  1430. LOG_ERR("Failed to get session handle for key");
  1431. return rc;
  1432. }
  1433. TSS2_RC rval = Esys_Certify(ectx, certifiedkey_obj->tr_handle,
  1434. signingkey_obj->tr_handle, certifiedkey_session_handle,
  1435. signingkey_session_handle, shandle3, qualifying_data, scheme,
  1436. certify_info, signature);
  1437. if (rval != TPM2_RC_SUCCESS) {
  1438. LOG_PERR(Eys_Certify, rval);
  1439. rc = tool_rc_from_tpm(rval);
  1440. return rc;
  1441. }
  1442. if (rp_hash->size) {
  1443. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  1444. parameter_hash_algorithm);
  1445. }
  1446. tpm2_certify_skip_esapi_call:
  1447. return rc;
  1448. }
  1449. tool_rc tpm2_rsa_decrypt(ESYS_CONTEXT *ectx, tpm2_loaded_object *keyobj,
  1450. const TPM2B_PUBLIC_KEY_RSA *cipher_text, const TPMT_RSA_DECRYPT *scheme,
  1451. const TPM2B_DATA *label, TPM2B_PUBLIC_KEY_RSA **message,
  1452. TPM2B_DIGEST *cp_hash) {
  1453. ESYS_TR keyobj_session_handle = ESYS_TR_NONE;
  1454. tool_rc rc = tpm2_auth_util_get_shandle(ectx, keyobj->tr_handle,
  1455. keyobj->session, &keyobj_session_handle);
  1456. if (rc != tool_rc_success) {
  1457. return rc;
  1458. }
  1459. if (cp_hash) {
  1460. /*
  1461. * Need sys_context to be able to calculate CpHash
  1462. */
  1463. TSS2_SYS_CONTEXT *sys_context = NULL;
  1464. rc = tpm2_getsapicontext(ectx, &sys_context);
  1465. if(rc != tool_rc_success) {
  1466. LOG_ERR("Failed to acquire SAPI context.");
  1467. return rc;
  1468. }
  1469. TSS2_RC rval = Tss2_Sys_RSA_Decrypt_Prepare(sys_context, keyobj->handle,
  1470. cipher_text, scheme, label);
  1471. if (rval != TPM2_RC_SUCCESS) {
  1472. LOG_PERR(Tss2_Sys_RSA_Decrypt_Prepare, rval);
  1473. return tool_rc_general_error;
  1474. }
  1475. TPM2B_NAME *name1 = NULL;
  1476. rc = tpm2_tr_get_name(ectx, keyobj->tr_handle, &name1);
  1477. if (rc != tool_rc_success) {
  1478. goto tpm2_rsadecrypt_free_name1;
  1479. }
  1480. cp_hash->size = tpm2_alg_util_get_hash_size(
  1481. tpm2_session_get_authhash(keyobj->session));
  1482. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1483. tpm2_session_get_authhash(keyobj->session), cp_hash);
  1484. /*
  1485. * Exit here without making the ESYS call since we just need the cpHash
  1486. */
  1487. tpm2_rsadecrypt_free_name1:
  1488. Esys_Free(name1);
  1489. goto tpm2_rsadecrypt_skip_esapi_call;
  1490. }
  1491. TSS2_RC rval = Esys_RSA_Decrypt(ectx, keyobj->tr_handle,
  1492. keyobj_session_handle, ESYS_TR_NONE, ESYS_TR_NONE, cipher_text,
  1493. scheme, label, message);
  1494. if (rval != TPM2_RC_SUCCESS) {
  1495. LOG_PERR(Esys_RSA_Decrypt, rval);
  1496. return tool_rc_from_tpm(rval);
  1497. }
  1498. tpm2_rsadecrypt_skip_esapi_call:
  1499. return rc;
  1500. }
  1501. tool_rc tpm2_rsa_encrypt(ESYS_CONTEXT *ectx, tpm2_loaded_object *keyobj,
  1502. const TPM2B_PUBLIC_KEY_RSA *message, const TPMT_RSA_DECRYPT *scheme,
  1503. const TPM2B_DATA *label, TPM2B_PUBLIC_KEY_RSA **cipher_text) {
  1504. TSS2_RC rval = Esys_RSA_Encrypt(ectx, keyobj->tr_handle,
  1505. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, message, scheme,
  1506. label, cipher_text);
  1507. if (rval != TPM2_RC_SUCCESS) {
  1508. LOG_PERR(Esys_RSA_Encrypt, rval);
  1509. return tool_rc_from_tpm(rval);
  1510. }
  1511. return tool_rc_success;
  1512. }
  1513. tool_rc tpm2_load(ESYS_CONTEXT *esys_context, tpm2_loaded_object *parentobj,
  1514. const TPM2B_PRIVATE *in_private, const TPM2B_PUBLIC *in_public,
  1515. ESYS_TR *object_handle, TPM2B_DIGEST *cp_hash) {
  1516. ESYS_TR parent_object_session_handle = ESYS_TR_NONE;
  1517. tool_rc rc = tpm2_auth_util_get_shandle(esys_context, parentobj->tr_handle,
  1518. parentobj->session, &parent_object_session_handle);
  1519. if (rc != tool_rc_success) {
  1520. LOG_ERR("Failed to get parent object session handle");
  1521. return rc;
  1522. }
  1523. if (cp_hash) {
  1524. /*
  1525. * Need sys_context to be able to calculate CpHash
  1526. */
  1527. TSS2_SYS_CONTEXT *sys_context = NULL;
  1528. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1529. if(rc != tool_rc_success) {
  1530. LOG_ERR("Failed to acquire SAPI context.");
  1531. return rc;
  1532. }
  1533. TSS2_RC rval = Tss2_Sys_Load_Prepare(sys_context, parentobj->handle,
  1534. in_private, in_public);
  1535. if (rval != TPM2_RC_SUCCESS) {
  1536. LOG_PERR(Tss2_Sys_Load_Prepare, rval);
  1537. return tool_rc_general_error;
  1538. }
  1539. TPM2B_NAME *name1 = NULL;
  1540. rc = tpm2_tr_get_name(esys_context, parentobj->tr_handle,
  1541. &name1);
  1542. if (rc != tool_rc_success) {
  1543. goto tpm2_load_free_name1;
  1544. }
  1545. cp_hash->size = tpm2_alg_util_get_hash_size(
  1546. tpm2_session_get_authhash(parentobj->session));
  1547. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1548. tpm2_session_get_authhash(parentobj->session), cp_hash);
  1549. /*
  1550. * Exit here without making the ESYS call since we just need the cpHash
  1551. */
  1552. tpm2_load_free_name1:
  1553. Esys_Free(name1);
  1554. goto tpm2_load_skip_esapi_call;
  1555. }
  1556. TSS2_RC rval = Esys_Load(esys_context, parentobj->tr_handle,
  1557. parent_object_session_handle, ESYS_TR_NONE, ESYS_TR_NONE, in_private,
  1558. in_public, object_handle);
  1559. if (rval != TPM2_RC_SUCCESS) {
  1560. LOG_PERR(Eys_Load, rval);
  1561. return tool_rc_from_tpm(rval);
  1562. }
  1563. tpm2_load_skip_esapi_call:
  1564. return rc;
  1565. }
  1566. tool_rc tpm2_clear(ESYS_CONTEXT *esys_context,
  1567. tpm2_loaded_object *auth_hierarchy, TPM2B_DIGEST *cp_hash) {
  1568. ESYS_TR shandle1 = ESYS_TR_NONE;
  1569. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  1570. auth_hierarchy->tr_handle, auth_hierarchy->session, &shandle1);
  1571. if (rc != tool_rc_success) {
  1572. LOG_ERR("Failed to get shandle for hierarchy");
  1573. return rc;
  1574. }
  1575. if (cp_hash) {
  1576. /*
  1577. * Need sys_context to be able to calculate CpHash
  1578. */
  1579. TSS2_SYS_CONTEXT *sys_context = NULL;
  1580. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1581. if(rc != tool_rc_success) {
  1582. LOG_ERR("Failed to acquire SAPI context.");
  1583. return rc;
  1584. }
  1585. TSS2_RC rval = Tss2_Sys_Clear_Prepare(sys_context,
  1586. auth_hierarchy->handle);
  1587. if (rval != TPM2_RC_SUCCESS) {
  1588. LOG_PERR(Tss2_Sys_Clear_Prepare, rval);
  1589. return tool_rc_general_error;
  1590. }
  1591. TPM2B_NAME *name1 = NULL;
  1592. rc = tpm2_tr_get_name(esys_context, auth_hierarchy->tr_handle,
  1593. &name1);
  1594. if (rc != tool_rc_success) {
  1595. goto tpm2_clear_free_name1;
  1596. }
  1597. cp_hash->size = tpm2_alg_util_get_hash_size(
  1598. tpm2_session_get_authhash(auth_hierarchy->session));
  1599. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1600. tpm2_session_get_authhash(auth_hierarchy->session), cp_hash);
  1601. /*
  1602. * Exit here without making the ESYS call since we just need the cpHash
  1603. */
  1604. tpm2_clear_free_name1:
  1605. Esys_Free(name1);
  1606. goto tpm2_clear_skip_esapi_call;
  1607. }
  1608. TSS2_RC rval = Esys_Clear(esys_context, auth_hierarchy->tr_handle, shandle1,
  1609. ESYS_TR_NONE, ESYS_TR_NONE);
  1610. if (rval != TPM2_RC_SUCCESS && rval != TPM2_RC_INITIALIZE) {
  1611. LOG_PERR(Esys_Clear, rval);
  1612. return tool_rc_from_tpm(rval);
  1613. }
  1614. tpm2_clear_skip_esapi_call:
  1615. return rc;
  1616. }
  1617. tool_rc tpm2_clearcontrol(ESYS_CONTEXT *esys_context,
  1618. tpm2_loaded_object *auth_hierarchy, TPMI_YES_NO disable_clear,
  1619. TPM2B_DIGEST *cp_hash) {
  1620. ESYS_TR shandle = ESYS_TR_NONE;
  1621. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  1622. auth_hierarchy->tr_handle, auth_hierarchy->session, &shandle);
  1623. if (rc != tool_rc_success) {
  1624. return rc;
  1625. }
  1626. if (cp_hash) {
  1627. /*
  1628. * Need sys_context to be able to calculate CpHash
  1629. */
  1630. TSS2_SYS_CONTEXT *sys_context = NULL;
  1631. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1632. if(rc != tool_rc_success) {
  1633. LOG_ERR("Failed to acquire SAPI context.");
  1634. return rc;
  1635. }
  1636. TSS2_RC rval = Tss2_Sys_ClearControl_Prepare(sys_context,
  1637. auth_hierarchy->handle, disable_clear);
  1638. if (rval != TPM2_RC_SUCCESS) {
  1639. LOG_PERR(Tss2_Sys_ClearControl_Prepare, rval);
  1640. return tool_rc_general_error;
  1641. }
  1642. TPM2B_NAME *name1 = NULL;
  1643. rc = tpm2_tr_get_name(esys_context, auth_hierarchy->tr_handle,
  1644. &name1);
  1645. if (rc != tool_rc_success) {
  1646. goto tpm2_clearcontrol_free_name1;
  1647. }
  1648. cp_hash->size = tpm2_alg_util_get_hash_size(
  1649. tpm2_session_get_authhash(auth_hierarchy->session));
  1650. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1651. tpm2_session_get_authhash(auth_hierarchy->session), cp_hash);
  1652. /*
  1653. * Exit here without making the ESYS call since we just need the cpHash
  1654. */
  1655. tpm2_clearcontrol_free_name1:
  1656. Esys_Free(name1);
  1657. goto tpm2_clearcontrol_skip_esapi_call;
  1658. }
  1659. TSS2_RC rval = Esys_ClearControl(esys_context, auth_hierarchy->tr_handle,
  1660. shandle, ESYS_TR_NONE, ESYS_TR_NONE, disable_clear);
  1661. if (rval != TPM2_RC_SUCCESS && rval != TPM2_RC_INITIALIZE) {
  1662. LOG_PERR(Esys_ClearControl, rval);
  1663. return tool_rc_from_tpm(rval);
  1664. }
  1665. tpm2_clearcontrol_skip_esapi_call:
  1666. return rc;
  1667. }
  1668. tool_rc tpm2_dictionarylockout_setup(ESYS_CONTEXT *esys_context,
  1669. tpm2_loaded_object *auth_hierarchy, UINT32 max_tries,
  1670. UINT32 recovery_time, UINT32 lockout_recovery_time,
  1671. TPM2B_DIGEST *cp_hash) {
  1672. ESYS_TR shandle1 = ESYS_TR_NONE;
  1673. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  1674. auth_hierarchy->tr_handle, auth_hierarchy->session, &shandle1);
  1675. if (rc != tool_rc_success) {
  1676. LOG_ERR("Couldn't get shandle for lockout hierarchy");
  1677. return rc;
  1678. }
  1679. if (cp_hash) {
  1680. /*
  1681. * Need sys_context to be able to calculate CpHash
  1682. */
  1683. TSS2_SYS_CONTEXT *sys_context = NULL;
  1684. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1685. if(rc != tool_rc_success) {
  1686. LOG_ERR("Failed to acquire SAPI context.");
  1687. return rc;
  1688. }
  1689. TSS2_RC rval = Tss2_Sys_DictionaryAttackParameters_Prepare(sys_context,
  1690. auth_hierarchy->handle, max_tries, recovery_time,
  1691. lockout_recovery_time);
  1692. if (rval != TPM2_RC_SUCCESS) {
  1693. LOG_PERR(Tss2_Sys_DictionaryAttackParameters_Prepare, rval);
  1694. return tool_rc_general_error;
  1695. }
  1696. TPM2B_NAME *name1 = NULL;
  1697. rc = tpm2_tr_get_name(esys_context, auth_hierarchy->tr_handle,
  1698. &name1);
  1699. if (rc != tool_rc_success) {
  1700. goto tpm2_dictionary_parameters_free_name1;
  1701. }
  1702. cp_hash->size = tpm2_alg_util_get_hash_size(
  1703. tpm2_session_get_authhash(auth_hierarchy->session));
  1704. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1705. tpm2_session_get_authhash(auth_hierarchy->session), cp_hash);
  1706. /*
  1707. * Exit here without making the ESYS call since we just need the cpHash
  1708. */
  1709. tpm2_dictionary_parameters_free_name1:
  1710. Esys_Free(name1);
  1711. goto tpm2_dictionary_parameters_skip_esapi_call;
  1712. }
  1713. LOG_INFO("Setting up Dictionary Lockout parameters.");
  1714. TPM2_RC rval = Esys_DictionaryAttackParameters(esys_context,
  1715. auth_hierarchy->tr_handle, shandle1, ESYS_TR_NONE, ESYS_TR_NONE,
  1716. max_tries, recovery_time, lockout_recovery_time);
  1717. if (rval != TPM2_RC_SUCCESS) {
  1718. LOG_PERR(Esys_DictionaryAttackParameters, rval);
  1719. return tool_rc_from_tpm(rval);
  1720. }
  1721. tpm2_dictionary_parameters_skip_esapi_call:
  1722. return rc;
  1723. }
  1724. tool_rc tpm2_dictionarylockout_reset(ESYS_CONTEXT *esys_context,
  1725. tpm2_loaded_object *auth_hierarchy, TPM2B_DIGEST *cp_hash) {
  1726. ESYS_TR shandle1 = ESYS_TR_NONE;
  1727. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  1728. auth_hierarchy->tr_handle, auth_hierarchy->session, &shandle1);
  1729. if (rc != tool_rc_success) {
  1730. LOG_ERR("Couldn't get shandle for lockout hierarchy");
  1731. return rc;
  1732. }
  1733. if (cp_hash) {
  1734. /*
  1735. * Need sys_context to be able to calculate CpHash
  1736. */
  1737. TSS2_SYS_CONTEXT *sys_context = NULL;
  1738. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1739. if(rc != tool_rc_success) {
  1740. LOG_ERR("Failed to acquire SAPI context.");
  1741. return rc;
  1742. }
  1743. TSS2_RC rval = Tss2_Sys_DictionaryAttackLockReset_Prepare(sys_context,
  1744. auth_hierarchy->handle);
  1745. if (rval != TPM2_RC_SUCCESS) {
  1746. LOG_PERR(Tss2_Sys_DictionaryAttackLockReset_Prepare, rval);
  1747. return tool_rc_general_error;
  1748. }
  1749. TPM2B_NAME *name1 = NULL;
  1750. rc = tpm2_tr_get_name(esys_context, auth_hierarchy->tr_handle,
  1751. &name1);
  1752. if (rc != tool_rc_success) {
  1753. goto tpm2_dictionary_attack_reset_free_name1;
  1754. }
  1755. cp_hash->size = tpm2_alg_util_get_hash_size(
  1756. tpm2_session_get_authhash(auth_hierarchy->session));
  1757. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1758. tpm2_session_get_authhash(auth_hierarchy->session), cp_hash);
  1759. /*
  1760. * Exit here without making the ESYS call since we just need the cpHash
  1761. */
  1762. tpm2_dictionary_attack_reset_free_name1:
  1763. Esys_Free(name1);
  1764. goto tpm2_dictionary_attack_reset_skip_esapi_call;
  1765. }
  1766. LOG_INFO("Resetting dictionary lockout state.");
  1767. TPM2_RC rval = Esys_DictionaryAttackLockReset(esys_context,
  1768. auth_hierarchy->tr_handle, shandle1, ESYS_TR_NONE,
  1769. ESYS_TR_NONE);
  1770. if (rval != TPM2_RC_SUCCESS) {
  1771. LOG_PERR(Esys_DictionaryAttackLockReset, rval);
  1772. return tool_rc_from_tpm(rval);
  1773. }
  1774. tpm2_dictionary_attack_reset_skip_esapi_call:
  1775. return rc;
  1776. }
  1777. tool_rc tpm2_duplicate(ESYS_CONTEXT *esys_context,
  1778. tpm2_loaded_object *duplicable_key, tpm2_loaded_object *new_parent,
  1779. const TPM2B_DATA *in_key, const TPMT_SYM_DEF_OBJECT *sym_alg,
  1780. TPM2B_DATA **out_key, TPM2B_PRIVATE **duplicate,
  1781. TPM2B_ENCRYPTED_SECRET **encrypted_seed, TPM2B_DIGEST *cp_hash) {
  1782. ESYS_TR shandle1 = ESYS_TR_NONE;
  1783. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  1784. duplicable_key->tr_handle, duplicable_key->session, &shandle1);
  1785. if (rc != tool_rc_success) {
  1786. LOG_ERR("Failed to get shandle");
  1787. return rc;
  1788. }
  1789. if (cp_hash) {
  1790. /*
  1791. * Need sys_context to be able to calculate CpHash
  1792. */
  1793. TSS2_SYS_CONTEXT *sys_context = NULL;
  1794. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1795. if(rc != tool_rc_success) {
  1796. LOG_ERR("Failed to acquire SAPI context.");
  1797. return rc;
  1798. }
  1799. TSS2_RC rval = Tss2_Sys_Duplicate_Prepare(sys_context,
  1800. duplicable_key->handle, new_parent->handle, in_key, sym_alg);
  1801. if (rval != TPM2_RC_SUCCESS) {
  1802. LOG_PERR(Tss2_Sys_Duplicate_Prepare, rval);
  1803. return tool_rc_general_error;
  1804. }
  1805. TPM2B_NAME *name1 = NULL;
  1806. rc = tpm2_tr_get_name(esys_context, duplicable_key->tr_handle, &name1);
  1807. if (rc != tool_rc_success) {
  1808. goto tpm2_duplicate_free_name1;
  1809. }
  1810. TPM2B_NAME *name2 = NULL;
  1811. rc = tpm2_tr_get_name(esys_context, new_parent->tr_handle, &name2);
  1812. if (rc != tool_rc_success) {
  1813. goto tpm2_duplicate_free_name1_name2;
  1814. }
  1815. cp_hash->size = tpm2_alg_util_get_hash_size(
  1816. tpm2_session_get_authhash(duplicable_key->session));
  1817. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  1818. tpm2_session_get_authhash(duplicable_key->session), cp_hash);
  1819. /*
  1820. * Exit here without making the ESYS call since we just need the cpHash
  1821. */
  1822. tpm2_duplicate_free_name1_name2:
  1823. Esys_Free(name2);
  1824. tpm2_duplicate_free_name1:
  1825. Esys_Free(name1);
  1826. goto tpm2_duplicate_skip_esapi_call;
  1827. }
  1828. TSS2_RC rval = Esys_Duplicate(esys_context, duplicable_key->tr_handle,
  1829. new_parent->tr_handle, shandle1, ESYS_TR_NONE, ESYS_TR_NONE, in_key,
  1830. sym_alg, out_key, duplicate, encrypted_seed);
  1831. if (rval != TPM2_RC_SUCCESS) {
  1832. LOG_PERR(Esys_Duplicate, rval);
  1833. return tool_rc_from_tpm(rval);
  1834. }
  1835. tpm2_duplicate_skip_esapi_call:
  1836. return rc;
  1837. }
  1838. tool_rc tpm2_encryptdecrypt(ESYS_CONTEXT *esys_context,
  1839. tpm2_loaded_object *encryption_key_obj, TPMI_YES_NO decrypt,
  1840. TPMI_ALG_SYM_MODE mode, const TPM2B_IV *iv_in,
  1841. const TPM2B_MAX_BUFFER *input_data, TPM2B_MAX_BUFFER **output_data,
  1842. TPM2B_IV **iv_out, TPM2B_DIGEST *cp_hash) {
  1843. ESYS_TR shandle1 = ESYS_TR_NONE;
  1844. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  1845. encryption_key_obj->tr_handle, encryption_key_obj->session, &shandle1);
  1846. if (rc != tool_rc_success) {
  1847. LOG_ERR("Failed to get shandle");
  1848. return rc;
  1849. }
  1850. /* Keep track of which version you ran for error reporting.*/
  1851. unsigned version = 2;
  1852. if (cp_hash) {
  1853. /*
  1854. * Need sys_context to be able to calculate CpHash
  1855. */
  1856. TSS2_SYS_CONTEXT *sys_context = NULL;
  1857. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1858. if(rc != tool_rc_success) {
  1859. LOG_ERR("Failed to acquire SAPI context.");
  1860. return rc;
  1861. }
  1862. TSS2_RC rval = Tss2_Sys_EncryptDecrypt2_Prepare(sys_context,
  1863. encryption_key_obj->handle, input_data, decrypt, mode, iv_in);
  1864. if (tpm2_error_get(rval) == TPM2_RC_COMMAND_CODE) {
  1865. version = 1;
  1866. rval = Tss2_Sys_EncryptDecrypt_Prepare(sys_context,
  1867. encryption_key_obj->handle, decrypt, mode, iv_in, input_data);
  1868. }
  1869. if (rval != TPM2_RC_SUCCESS) {
  1870. if (version == 2) {
  1871. LOG_PERR(Tss2_Sys_EncryptDecrypt2_Prepare, rval);
  1872. } else {
  1873. LOG_PERR(Tss2_Sys_EncryptDecrypt_Prepare, rval);
  1874. }
  1875. return tool_rc_general_error;
  1876. }
  1877. TPM2B_NAME *name1 = NULL;
  1878. rc = tpm2_tr_get_name(esys_context, encryption_key_obj->tr_handle,
  1879. &name1);
  1880. if (rc != tool_rc_success) {
  1881. goto tpm2_encryptdecrypt_free_name1;
  1882. }
  1883. cp_hash->size = tpm2_alg_util_get_hash_size(
  1884. tpm2_session_get_authhash(encryption_key_obj->session));
  1885. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1886. tpm2_session_get_authhash(encryption_key_obj->session), cp_hash);
  1887. /*
  1888. * Exit here without making the ESYS call since we just need the cpHash
  1889. */
  1890. tpm2_encryptdecrypt_free_name1:
  1891. Esys_Free(name1);
  1892. goto tpm2_encryptdecrypt_skip_esapi_call;
  1893. }
  1894. TSS2_RC rval = Esys_EncryptDecrypt2(esys_context,
  1895. encryption_key_obj->tr_handle, shandle1, ESYS_TR_NONE, ESYS_TR_NONE,
  1896. input_data, decrypt, mode, iv_in, output_data, iv_out);
  1897. if (tpm2_error_get(rval) == TPM2_RC_COMMAND_CODE) {
  1898. version = 1;
  1899. rval = Esys_EncryptDecrypt(esys_context, encryption_key_obj->tr_handle,
  1900. shandle1, ESYS_TR_NONE, ESYS_TR_NONE, decrypt, mode, iv_in,
  1901. input_data, output_data, iv_out);
  1902. }
  1903. if (rval != TPM2_RC_SUCCESS) {
  1904. if (version == 2) {
  1905. LOG_PERR(Esys_EncryptDecrypt2, rval);
  1906. } else {
  1907. LOG_PERR(Esys_EncryptDecrypt, rval);
  1908. }
  1909. return tool_rc_from_tpm(rval);
  1910. }
  1911. tpm2_encryptdecrypt_skip_esapi_call:
  1912. return rc;
  1913. }
  1914. tool_rc tpm2_hierarchycontrol(ESYS_CONTEXT *esys_context,
  1915. tpm2_loaded_object *auth_hierarchy, TPMI_RH_ENABLES enable,
  1916. TPMI_YES_NO state, TPM2B_DIGEST *cp_hash) {
  1917. ESYS_TR shandle = ESYS_TR_NONE;
  1918. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  1919. auth_hierarchy->tr_handle, auth_hierarchy->session, &shandle);
  1920. if (rc != tool_rc_success) {
  1921. LOG_ERR("Failed to get shandle for hierarchy");
  1922. return rc;
  1923. }
  1924. if (cp_hash) {
  1925. /*
  1926. * Need sys_context to be able to calculate CpHash
  1927. */
  1928. TSS2_SYS_CONTEXT *sys_context = NULL;
  1929. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1930. if(rc != tool_rc_success) {
  1931. LOG_ERR("Failed to acquire SAPI context.");
  1932. return rc;
  1933. }
  1934. TSS2_RC rval = Tss2_Sys_HierarchyControl_Prepare(sys_context,
  1935. auth_hierarchy->handle, enable, state);
  1936. if (rval != TPM2_RC_SUCCESS) {
  1937. LOG_PERR(Tss2_Sys_HierarchyControl_Prepare, rval);
  1938. return tool_rc_general_error;
  1939. }
  1940. TPM2B_NAME *name1 = NULL;
  1941. rc = tpm2_tr_get_name(esys_context, auth_hierarchy->tr_handle,
  1942. &name1);
  1943. if (rc != tool_rc_success) {
  1944. goto tpm2_hierarchycontrol_free_name1;
  1945. }
  1946. cp_hash->size = tpm2_alg_util_get_hash_size(
  1947. tpm2_session_get_authhash(auth_hierarchy->session));
  1948. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  1949. tpm2_session_get_authhash(auth_hierarchy->session), cp_hash);
  1950. /*
  1951. * Exit here without making the ESYS call since we just need the cpHash
  1952. */
  1953. tpm2_hierarchycontrol_free_name1:
  1954. Esys_Free(name1);
  1955. goto tpm2_hierarchycontrol_skip_esapi_call;
  1956. }
  1957. TSS2_RC rval = fix_esys_hierarchy(enable, &enable);
  1958. if (rval != TSS2_RC_SUCCESS) {
  1959. LOG_ERR("Unknown hierarchy");
  1960. return tool_rc_from_tpm(rval);
  1961. }
  1962. rval = Esys_HierarchyControl(esys_context, auth_hierarchy->tr_handle,
  1963. shandle, ESYS_TR_NONE, ESYS_TR_NONE, enable, state);
  1964. if (rval != TPM2_RC_SUCCESS && rval != TPM2_RC_INITIALIZE) {
  1965. LOG_PERR(Esys_HierarchyControl, rval);
  1966. return tool_rc_from_tpm(rval);
  1967. }
  1968. tpm2_hierarchycontrol_skip_esapi_call:
  1969. return rc;
  1970. }
  1971. tool_rc tpm2_hmac(ESYS_CONTEXT *esys_context, tpm2_loaded_object *hmac_key_obj,
  1972. TPMI_ALG_HASH halg, const TPM2B_MAX_BUFFER *input_buffer,
  1973. TPM2B_DIGEST **out_hmac, TPM2B_DIGEST *cp_hash) {
  1974. ESYS_TR hmac_key_obj_shandle = ESYS_TR_NONE;
  1975. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  1976. hmac_key_obj->tr_handle, hmac_key_obj->session,
  1977. &hmac_key_obj_shandle);
  1978. if (rc != tool_rc_success) {
  1979. LOG_ERR("Failed to get hmac_key_obj_shandle");
  1980. return rc;
  1981. }
  1982. if (cp_hash) {
  1983. /*
  1984. * Need sys_context to be able to calculate CpHash
  1985. */
  1986. TSS2_SYS_CONTEXT *sys_context = NULL;
  1987. rc = tpm2_getsapicontext(esys_context, &sys_context);
  1988. if(rc != tool_rc_success) {
  1989. LOG_ERR("Failed to acquire SAPI context.");
  1990. return rc;
  1991. }
  1992. TSS2_RC rval = Tss2_Sys_HMAC_Prepare(sys_context, hmac_key_obj->handle,
  1993. input_buffer, halg);
  1994. if (rval != TPM2_RC_SUCCESS) {
  1995. LOG_PERR(Tss2_Sys_HMAC_Prepare, rval);
  1996. return tool_rc_general_error;
  1997. }
  1998. TPM2B_NAME *name1 = NULL;
  1999. rc = tpm2_tr_get_name(esys_context, hmac_key_obj->tr_handle,
  2000. &name1);
  2001. if (rc != tool_rc_success) {
  2002. goto tpm2_hmac_free_name1;
  2003. }
  2004. cp_hash->size = tpm2_alg_util_get_hash_size(
  2005. tpm2_session_get_authhash(hmac_key_obj->session));
  2006. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  2007. tpm2_session_get_authhash(hmac_key_obj->session), cp_hash);
  2008. /*
  2009. * Exit here without making the ESYS call since we just need the cpHash
  2010. */
  2011. tpm2_hmac_free_name1:
  2012. Esys_Free(name1);
  2013. goto tpm2_hmac_skip_esapi_call;
  2014. }
  2015. TPM2_RC rval = Esys_HMAC(esys_context, hmac_key_obj->tr_handle,
  2016. hmac_key_obj_shandle, ESYS_TR_NONE, ESYS_TR_NONE, input_buffer,
  2017. halg, out_hmac);
  2018. if (rval != TSS2_RC_SUCCESS) {
  2019. LOG_PERR(Esys_HMAC, rval);
  2020. return tool_rc_from_tpm(rval);
  2021. }
  2022. tpm2_hmac_skip_esapi_call:
  2023. return rc;
  2024. }
  2025. tool_rc tpm2_hmac_start(ESYS_CONTEXT *esys_context,
  2026. tpm2_loaded_object *hmac_key_obj, TPMI_ALG_HASH halg,
  2027. ESYS_TR *sequence_handle) {
  2028. ESYS_TR hmac_key_obj_shandle = ESYS_TR_NONE;
  2029. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2030. hmac_key_obj->tr_handle, hmac_key_obj->session,
  2031. &hmac_key_obj_shandle);
  2032. if (rc != tool_rc_success) {
  2033. LOG_ERR("Failed to get hmac_key_obj_shandle");
  2034. return rc;
  2035. }
  2036. TPM2B_AUTH null_auth = { .size = 0 };
  2037. TPM2_RC rval = Esys_HMAC_Start(esys_context, hmac_key_obj->tr_handle,
  2038. hmac_key_obj_shandle, ESYS_TR_NONE, ESYS_TR_NONE, &null_auth, halg,
  2039. sequence_handle);
  2040. if (rval != TSS2_RC_SUCCESS) {
  2041. LOG_PERR(Esys_HMAC, rval);
  2042. return tool_rc_from_tpm(rval);
  2043. }
  2044. return tool_rc_success;
  2045. }
  2046. tool_rc tpm2_hmac_sequenceupdate(ESYS_CONTEXT *esys_context,
  2047. ESYS_TR sequence_handle, tpm2_loaded_object *hmac_key_obj,
  2048. const TPM2B_MAX_BUFFER *input_buffer) {
  2049. ESYS_TR hmac_key_obj_shandle = ESYS_TR_NONE;
  2050. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2051. hmac_key_obj->tr_handle, hmac_key_obj->session,
  2052. &hmac_key_obj_shandle);
  2053. if (rc != tool_rc_success) {
  2054. LOG_ERR("Failed to get hmac_key_obj_shandle");
  2055. return rc;
  2056. }
  2057. TPM2_RC rval = Esys_SequenceUpdate(esys_context, sequence_handle,
  2058. hmac_key_obj_shandle, ESYS_TR_NONE, ESYS_TR_NONE, input_buffer);
  2059. if (rval != TSS2_RC_SUCCESS) {
  2060. LOG_PERR(Esys_HMAC, rval);
  2061. return tool_rc_from_tpm(rval);
  2062. }
  2063. return tool_rc_success;
  2064. }
  2065. tool_rc tpm2_hmac_sequencecomplete(ESYS_CONTEXT *esys_context,
  2066. ESYS_TR sequence_handle, tpm2_loaded_object *hmac_key_obj,
  2067. const TPM2B_MAX_BUFFER *input_buffer, TPM2B_DIGEST **result,
  2068. TPMT_TK_HASHCHECK **validation) {
  2069. ESYS_TR hmac_key_obj_shandle = ESYS_TR_NONE;
  2070. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2071. hmac_key_obj->tr_handle, hmac_key_obj->session,
  2072. &hmac_key_obj_shandle);
  2073. if (rc != tool_rc_success) {
  2074. LOG_ERR("Failed to get hmac_key_obj_shandle");
  2075. return rc;
  2076. }
  2077. uint32_t hierarchy;
  2078. TSS2_RC rval = fix_esys_hierarchy(TPM2_RH_NULL, &hierarchy);
  2079. if (rval != TSS2_RC_SUCCESS) {
  2080. LOG_ERR("Unknown hierarchy");
  2081. return tool_rc_from_tpm(rval);
  2082. }
  2083. rval = Esys_SequenceComplete(esys_context, sequence_handle,
  2084. hmac_key_obj_shandle, ESYS_TR_NONE, ESYS_TR_NONE, input_buffer,
  2085. hierarchy, result, validation);
  2086. if (rval != TSS2_RC_SUCCESS) {
  2087. LOG_PERR(Esys_HMAC, rval);
  2088. return tool_rc_from_tpm(rval);
  2089. }
  2090. return tool_rc_success;
  2091. }
  2092. tool_rc tpm2_import(ESYS_CONTEXT *esys_context, tpm2_loaded_object *parent_obj,
  2093. const TPM2B_DATA *encryption_key, const TPM2B_PUBLIC *object_public,
  2094. const TPM2B_PRIVATE *duplicate, const TPM2B_ENCRYPTED_SECRET *in_sym_seed,
  2095. const TPMT_SYM_DEF_OBJECT *symmetric_alg, TPM2B_PRIVATE **out_private,
  2096. TPM2B_DIGEST *cp_hash) {
  2097. ESYS_TR parentobj_shandle = ESYS_TR_NONE;
  2098. tool_rc rc = tpm2_auth_util_get_shandle(esys_context, parent_obj->tr_handle,
  2099. parent_obj->session, &parentobj_shandle);
  2100. if (rc != tool_rc_success) {
  2101. LOG_ERR("Couldn't get shandle for phandle");
  2102. return rc;
  2103. }
  2104. if (cp_hash) {
  2105. /*
  2106. * Need sys_context to be able to calculate CpHash
  2107. */
  2108. TSS2_SYS_CONTEXT *sys_context = NULL;
  2109. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2110. if(rc != tool_rc_success) {
  2111. LOG_ERR("Failed to acquire SAPI context.");
  2112. return rc;
  2113. }
  2114. TSS2_RC rval = Tss2_Sys_Import_Prepare(sys_context,
  2115. parent_obj->handle, encryption_key, object_public, duplicate,
  2116. in_sym_seed, symmetric_alg);
  2117. if (rval != TPM2_RC_SUCCESS) {
  2118. LOG_PERR(Tss2_Sys_Import_Prepare, rval);
  2119. return tool_rc_general_error;
  2120. }
  2121. TPM2B_NAME *name1 = NULL;
  2122. rc = tpm2_tr_get_name(esys_context, parent_obj->tr_handle, &name1);
  2123. if (rc != tool_rc_success) {
  2124. goto tpm2_import_free_name1;
  2125. }
  2126. cp_hash->size = tpm2_alg_util_get_hash_size(
  2127. tpm2_session_get_authhash(parent_obj->session));
  2128. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  2129. tpm2_session_get_authhash(parent_obj->session), cp_hash);
  2130. /*
  2131. * Exit here without making the ESYS call since we just need the cpHash
  2132. */
  2133. tpm2_import_free_name1:
  2134. Esys_Free(name1);
  2135. goto tpm2_import_skip_esapi_call;
  2136. }
  2137. TPM2_RC rval = Esys_Import(esys_context, parent_obj->tr_handle,
  2138. parentobj_shandle, ESYS_TR_NONE, ESYS_TR_NONE, encryption_key,
  2139. object_public, duplicate, in_sym_seed, symmetric_alg, out_private);
  2140. if (rval != TSS2_RC_SUCCESS) {
  2141. LOG_PERR(Esys_HMAC, rval);
  2142. return tool_rc_from_tpm(rval);
  2143. }
  2144. tpm2_import_skip_esapi_call:
  2145. return rc;
  2146. }
  2147. tool_rc tpm2_nv_definespace(ESYS_CONTEXT *esys_context,
  2148. tpm2_loaded_object *auth_hierarchy_obj, const TPM2B_AUTH *auth,
  2149. const TPM2B_NV_PUBLIC *public_info, TPM2B_DIGEST *cp_hash,
  2150. TPM2B_DIGEST *rp_hash, TPMI_ALG_HASH parameter_hash_algorithm,
  2151. ESYS_TR shandle2, ESYS_TR shandle3) {
  2152. TSS2_SYS_CONTEXT *sys_context = NULL;
  2153. tool_rc rc = tool_rc_success;
  2154. if (cp_hash->size || rp_hash->size) {
  2155. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2156. if(rc != tool_rc_success) {
  2157. LOG_ERR("Failed to acquire SAPI context.");
  2158. return rc;
  2159. }
  2160. }
  2161. if (cp_hash->size) {
  2162. /*
  2163. * Need sys_context to be able to calculate CpHash
  2164. */
  2165. TSS2_SYS_CONTEXT *sys_context = NULL;
  2166. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2167. if(rc != tool_rc_success) {
  2168. LOG_ERR("Failed to acquire SAPI context.");
  2169. return rc;
  2170. }
  2171. TSS2_RC rval = Tss2_Sys_NV_DefineSpace_Prepare(sys_context,
  2172. auth_hierarchy_obj->handle, auth, public_info);
  2173. if (rval != TPM2_RC_SUCCESS) {
  2174. LOG_PERR(Tss2_Sys_NV_DefineSpace_Prepare, rval);
  2175. return tool_rc_general_error;
  2176. }
  2177. TPM2B_NAME *name1 = NULL;
  2178. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  2179. &name1);
  2180. if (rc != tool_rc_success) {
  2181. goto tpm2_nvdefinespace_free_name1;
  2182. }
  2183. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  2184. parameter_hash_algorithm, cp_hash);
  2185. tpm2_nvdefinespace_free_name1:
  2186. Esys_Free(name1);
  2187. /*
  2188. * Exit here without making the ESYS call since we just need the cpHash
  2189. */
  2190. if (!rp_hash->size) {
  2191. goto tpm2_nvdefinespace_skip_esapi_call;
  2192. }
  2193. }
  2194. ESYS_TR shandle1 = ESYS_TR_NONE;
  2195. rc = tpm2_auth_util_get_shandle(esys_context, auth_hierarchy_obj->tr_handle,
  2196. auth_hierarchy_obj->session, &shandle1);
  2197. if (rc != tool_rc_success) {
  2198. LOG_ERR("Failed to get shandle");
  2199. return rc;
  2200. }
  2201. ESYS_TR nvHandle;
  2202. TSS2_RC rval = Esys_NV_DefineSpace(esys_context,
  2203. auth_hierarchy_obj->tr_handle, shandle1, shandle2, shandle3, auth,
  2204. public_info, &nvHandle);
  2205. if (rval != TPM2_RC_SUCCESS) {
  2206. LOG_ERR("Failed to define NV area at index 0x%X",
  2207. public_info->nvPublic.nvIndex);
  2208. LOG_PERR(Esys_NV_DefineSpace, rval);
  2209. return tool_rc_from_tpm(rval);
  2210. }
  2211. if (rp_hash->size) {
  2212. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  2213. parameter_hash_algorithm);
  2214. }
  2215. tpm2_nvdefinespace_skip_esapi_call:
  2216. return rc;
  2217. }
  2218. tool_rc tpm2_nv_increment(ESYS_CONTEXT *esys_context,
  2219. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nv_index,
  2220. TPM2B_DIGEST *cp_hash) {
  2221. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  2222. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2223. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  2224. &auth_hierarchy_obj_session_handle);
  2225. if (rc != tool_rc_success) {
  2226. LOG_ERR("Failed to get shandle");
  2227. return rc;
  2228. }
  2229. // Convert TPM2_HANDLE ctx.nv_index to an ESYS_TR
  2230. ESYS_TR esys_tr_nv_index;
  2231. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  2232. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_index);
  2233. if (rval != TPM2_RC_SUCCESS) {
  2234. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  2235. return tool_rc_from_tpm(rval);
  2236. }
  2237. if (cp_hash) {
  2238. /*
  2239. * Need sys_context to be able to calculate CpHash
  2240. */
  2241. TSS2_SYS_CONTEXT *sys_context = NULL;
  2242. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2243. if(rc != tool_rc_success) {
  2244. LOG_ERR("Failed to acquire SAPI context.");
  2245. return rc;
  2246. }
  2247. rval = Tss2_Sys_NV_Increment_Prepare(sys_context,
  2248. auth_hierarchy_obj->handle, nv_index);
  2249. if (rval != TPM2_RC_SUCCESS) {
  2250. LOG_PERR(Tss2_Sys_NV_Increment_Prepare, rval);
  2251. return tool_rc_general_error;
  2252. }
  2253. TPM2B_NAME *name1 = NULL;
  2254. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  2255. &name1);
  2256. if (rc != tool_rc_success) {
  2257. goto tpm2_nvincrement_free_name1;
  2258. }
  2259. TPM2B_NAME *name2 = NULL;
  2260. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_index, &name2);
  2261. if (rc != tool_rc_success) {
  2262. goto tpm2_nvincrement_free_name1_name2;
  2263. }
  2264. cp_hash->size = tpm2_alg_util_get_hash_size(
  2265. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  2266. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  2267. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  2268. /*
  2269. * Exit here without making the ESYS call since we just need the cpHash
  2270. */
  2271. tpm2_nvincrement_free_name1_name2:
  2272. Esys_Free(name2);
  2273. tpm2_nvincrement_free_name1:
  2274. Esys_Free(name1);
  2275. goto tpm2_nvincrement_skip_esapi_call;
  2276. }
  2277. rval = Esys_NV_Increment(esys_context, auth_hierarchy_obj->tr_handle,
  2278. esys_tr_nv_index, auth_hierarchy_obj_session_handle, ESYS_TR_NONE,
  2279. ESYS_TR_NONE);
  2280. if (rval != TPM2_RC_SUCCESS) {
  2281. return tool_rc_from_tpm(rval);
  2282. }
  2283. tpm2_nvincrement_skip_esapi_call:
  2284. return rc;
  2285. }
  2286. tool_rc tpm2_nvreadlock(ESYS_CONTEXT *esys_context,
  2287. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nv_index,
  2288. TPM2B_DIGEST *cp_hash) {
  2289. ESYS_TR esys_tr_nv_handle;
  2290. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  2291. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_handle);
  2292. if (rval != TPM2_RC_SUCCESS) {
  2293. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  2294. return tool_rc_from_tpm(rval);
  2295. }
  2296. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  2297. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2298. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  2299. &auth_hierarchy_obj_session_handle);
  2300. if (rc != tool_rc_success) {
  2301. LOG_ERR("Failed to get shandle");
  2302. return rc;
  2303. }
  2304. if (cp_hash) {
  2305. /*
  2306. * Need sys_context to be able to calculate CpHash
  2307. */
  2308. TSS2_SYS_CONTEXT *sys_context = NULL;
  2309. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2310. if(rc != tool_rc_success) {
  2311. LOG_ERR("Failed to acquire SAPI context.");
  2312. return rc;
  2313. }
  2314. rval = Tss2_Sys_NV_ReadLock_Prepare(sys_context,
  2315. auth_hierarchy_obj->handle, nv_index);
  2316. if (rval != TPM2_RC_SUCCESS) {
  2317. LOG_PERR(Tss2_Sys_NV_ReadLock_Prepare, rval);
  2318. return tool_rc_general_error;
  2319. }
  2320. TPM2B_NAME *name1 = NULL;
  2321. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  2322. &name1);
  2323. if (rc != tool_rc_success) {
  2324. goto tpm2_readlock_free_name1;
  2325. }
  2326. TPM2B_NAME *name2 = NULL;
  2327. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_handle, &name2);
  2328. if (rc != tool_rc_success) {
  2329. goto tpm2_nvreadlock_free_name1_name2;
  2330. }
  2331. cp_hash->size = tpm2_alg_util_get_hash_size(
  2332. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  2333. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  2334. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  2335. /*
  2336. * Exit here without making the ESYS call since we just need the cpHash
  2337. */
  2338. tpm2_nvreadlock_free_name1_name2:
  2339. Esys_Free(name2);
  2340. tpm2_readlock_free_name1:
  2341. Esys_Free(name1);
  2342. goto tpm2_nvreadlock_skip_esapi_call;
  2343. }
  2344. rval = Esys_NV_ReadLock(esys_context, auth_hierarchy_obj->tr_handle,
  2345. esys_tr_nv_handle, auth_hierarchy_obj_session_handle, ESYS_TR_NONE,
  2346. ESYS_TR_NONE);
  2347. if (rval != TPM2_RC_SUCCESS) {
  2348. LOG_PERR(Esys_NV_ReadLock, rval);
  2349. return tool_rc_from_tpm(rval);
  2350. }
  2351. tpm2_nvreadlock_skip_esapi_call:
  2352. return rc;
  2353. }
  2354. tool_rc tpm2_nvwritelock(ESYS_CONTEXT *esys_context,
  2355. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nv_index,
  2356. TPM2B_DIGEST *cp_hash) {
  2357. ESYS_TR esys_tr_nv_handle;
  2358. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  2359. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_handle);
  2360. if (rval != TPM2_RC_SUCCESS) {
  2361. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  2362. return tool_rc_from_tpm(rval);
  2363. }
  2364. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  2365. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2366. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  2367. &auth_hierarchy_obj_session_handle);
  2368. if (rc != tool_rc_success) {
  2369. LOG_ERR("Failed to get shandle");
  2370. return rc;
  2371. }
  2372. if (cp_hash) {
  2373. /*
  2374. * Need sys_context to be able to calculate CpHash
  2375. */
  2376. TSS2_SYS_CONTEXT *sys_context = NULL;
  2377. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2378. if(rc != tool_rc_success) {
  2379. LOG_ERR("Failed to acquire SAPI context.");
  2380. return rc;
  2381. }
  2382. rval = Tss2_Sys_NV_WriteLock_Prepare(sys_context,
  2383. auth_hierarchy_obj->handle, nv_index);
  2384. if (rval != TPM2_RC_SUCCESS) {
  2385. LOG_PERR(Tss2_Sys_NV_WriteLock_Prepare, rval);
  2386. return tool_rc_general_error;
  2387. }
  2388. TPM2B_NAME *name1 = NULL;
  2389. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  2390. &name1);
  2391. if (rc != tool_rc_success) {
  2392. goto tpm2_nvwritelock_free_name1;
  2393. }
  2394. TPM2B_NAME *name2 = NULL;
  2395. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_handle, &name2);
  2396. if (rc != tool_rc_success) {
  2397. goto tpm2_nvwritelock_free_name1_name2;
  2398. }
  2399. cp_hash->size = tpm2_alg_util_get_hash_size(
  2400. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  2401. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  2402. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  2403. /*
  2404. * Exit here without making the ESYS call since we just need the cpHash
  2405. */
  2406. tpm2_nvwritelock_free_name1_name2:
  2407. Esys_Free(name2);
  2408. tpm2_nvwritelock_free_name1:
  2409. Esys_Free(name1);
  2410. goto tpm2_nvwritelock_skip_esapi_call;
  2411. }
  2412. rval = Esys_NV_WriteLock(esys_context, auth_hierarchy_obj->tr_handle,
  2413. esys_tr_nv_handle, auth_hierarchy_obj_session_handle, ESYS_TR_NONE,
  2414. ESYS_TR_NONE);
  2415. if (rval != TPM2_RC_SUCCESS) {
  2416. LOG_PERR(Esys_NV_WriteLock, rval);
  2417. return tool_rc_from_tpm(rval);
  2418. }
  2419. tpm2_nvwritelock_skip_esapi_call:
  2420. return rc;
  2421. }
  2422. tool_rc tpm2_nvglobalwritelock(ESYS_CONTEXT *esys_context,
  2423. tpm2_loaded_object *auth_hierarchy_obj, TPM2B_DIGEST *cp_hash) {
  2424. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  2425. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2426. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  2427. &auth_hierarchy_obj_session_handle);
  2428. if (rc != tool_rc_success) {
  2429. LOG_ERR("Failed to get shandle");
  2430. return rc;
  2431. }
  2432. if (cp_hash) {
  2433. /*
  2434. * Need sys_context to be able to calculate CpHash
  2435. */
  2436. TSS2_SYS_CONTEXT *sys_context = NULL;
  2437. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2438. if(rc != tool_rc_success) {
  2439. LOG_ERR("Failed to acquire SAPI context.");
  2440. return rc;
  2441. }
  2442. TSS2_RC rval = Tss2_Sys_NV_GlobalWriteLock_Prepare(sys_context,
  2443. auth_hierarchy_obj->handle);
  2444. if (rval != TPM2_RC_SUCCESS) {
  2445. LOG_PERR(Tss2_Sys_NV_GlobalWriteLock_Prepare, rval);
  2446. return tool_rc_general_error;
  2447. }
  2448. TPM2B_NAME *name1 = NULL;
  2449. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  2450. &name1);
  2451. if (rc != tool_rc_success) {
  2452. goto tpm2_globalnvwritelock_free_name1;
  2453. }
  2454. cp_hash->size = tpm2_alg_util_get_hash_size(
  2455. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  2456. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  2457. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  2458. /*
  2459. * Exit here without making the ESYS call since we just need the cpHash
  2460. */
  2461. tpm2_globalnvwritelock_free_name1:
  2462. Esys_Free(name1);
  2463. goto tpm2_globalnvwritelock_skip_esapi_call;
  2464. }
  2465. TSS2_RC rval = Esys_NV_GlobalWriteLock(esys_context, auth_hierarchy_obj->tr_handle,
  2466. auth_hierarchy_obj_session_handle, ESYS_TR_NONE, ESYS_TR_NONE);
  2467. if (rval != TPM2_RC_SUCCESS) {
  2468. LOG_PERR(Esys_NV_GlobalWriteLock, rval);
  2469. return tool_rc_from_tpm(rval);
  2470. }
  2471. tpm2_globalnvwritelock_skip_esapi_call:
  2472. return rc;
  2473. }
  2474. tool_rc tpm2_tr_from_tpm_public(ESYS_CONTEXT *esys_context, TPM2_HANDLE handle, ESYS_TR *tr_handle) {
  2475. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, handle, ESYS_TR_NONE,
  2476. ESYS_TR_NONE, ESYS_TR_NONE, tr_handle);
  2477. if (rval != TPM2_RC_SUCCESS) {
  2478. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  2479. return tool_rc_from_tpm(rval);
  2480. }
  2481. return tool_rc_success;
  2482. }
  2483. tool_rc tpm2_nvsetbits(ESYS_CONTEXT *esys_context,
  2484. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nv_index,
  2485. UINT64 bits, TPM2B_DIGEST *cp_hash) {
  2486. ESYS_TR esys_tr_nv_handle;
  2487. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  2488. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_handle);
  2489. if (rval != TPM2_RC_SUCCESS) {
  2490. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  2491. return tool_rc_from_tpm(rval);
  2492. }
  2493. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  2494. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2495. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  2496. &auth_hierarchy_obj_session_handle);
  2497. if (rc != tool_rc_success) {
  2498. LOG_ERR("Failed to get shandle");
  2499. return rc;
  2500. }
  2501. if (cp_hash) {
  2502. /*
  2503. * Need sys_context to be able to calculate CpHash
  2504. */
  2505. TSS2_SYS_CONTEXT *sys_context = NULL;
  2506. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2507. if(rc != tool_rc_success) {
  2508. LOG_ERR("Failed to acquire SAPI context.");
  2509. return rc;
  2510. }
  2511. rval = Tss2_Sys_NV_SetBits_Prepare(sys_context,
  2512. auth_hierarchy_obj->handle, nv_index, bits);
  2513. if (rval != TPM2_RC_SUCCESS) {
  2514. LOG_PERR(Tss2_Sys_NV_SetBits_Prepare, rval);
  2515. return tool_rc_general_error;
  2516. }
  2517. TPM2B_NAME *name1 = NULL;
  2518. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  2519. &name1);
  2520. if (rc != tool_rc_success) {
  2521. goto tpm2_nvsetbits_free_name1;
  2522. }
  2523. TPM2B_NAME *name2 = NULL;
  2524. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_handle, &name2);
  2525. if (rc != tool_rc_success) {
  2526. goto tpm2_nvsetbits_free_name1_name2;
  2527. }
  2528. cp_hash->size = tpm2_alg_util_get_hash_size(
  2529. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  2530. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  2531. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  2532. /*
  2533. * Exit here without making the ESYS call since we just need the cpHash
  2534. */
  2535. tpm2_nvsetbits_free_name1_name2:
  2536. Esys_Free(name2);
  2537. tpm2_nvsetbits_free_name1:
  2538. Esys_Free(name1);
  2539. goto tpm2_nvsetbits_skip_esapi_call;
  2540. }
  2541. rval = Esys_NV_SetBits(esys_context, auth_hierarchy_obj->tr_handle,
  2542. esys_tr_nv_handle, auth_hierarchy_obj_session_handle, ESYS_TR_NONE,
  2543. ESYS_TR_NONE, bits);
  2544. if (rval != TPM2_RC_SUCCESS) {
  2545. LOG_PERR(Esys_NV_SetBits, rval);
  2546. return tool_rc_from_tpm(rval);
  2547. }
  2548. tpm2_nvsetbits_skip_esapi_call:
  2549. return rc;
  2550. }
  2551. tool_rc tpm2_nvextend(ESYS_CONTEXT *esys_context,
  2552. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nv_index,
  2553. TPM2B_MAX_NV_BUFFER *data, TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
  2554. TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle2,
  2555. ESYS_TR shandle3) {
  2556. ESYS_TR esys_tr_nv_handle;
  2557. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  2558. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_handle);
  2559. if (rval != TPM2_RC_SUCCESS) {
  2560. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  2561. return tool_rc_from_tpm(rval);
  2562. }
  2563. TSS2_SYS_CONTEXT *sys_context = NULL;
  2564. tool_rc rc = tool_rc_success;
  2565. if (cp_hash->size || rp_hash->size) {
  2566. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2567. if(rc != tool_rc_success) {
  2568. LOG_ERR("Failed to acquire SAPI context.");
  2569. return rc;
  2570. }
  2571. }
  2572. if (cp_hash->size) {
  2573. /*
  2574. * Need sys_context to be able to calculate CpHash
  2575. */
  2576. TSS2_SYS_CONTEXT *sys_context = NULL;
  2577. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2578. if(rc != tool_rc_success) {
  2579. LOG_ERR("Failed to acquire SAPI context.");
  2580. return rc;
  2581. }
  2582. rval = Tss2_Sys_NV_Extend_Prepare(sys_context,
  2583. auth_hierarchy_obj->handle, nv_index, data);
  2584. if (rval != TPM2_RC_SUCCESS) {
  2585. LOG_PERR(Tss2_Sys_NV_Extend_Prepare, rval);
  2586. return tool_rc_general_error;
  2587. }
  2588. TPM2B_NAME *name1 = NULL;
  2589. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  2590. &name1);
  2591. if (rc != tool_rc_success) {
  2592. goto tpm2_nvextend_free_name1;
  2593. }
  2594. TPM2B_NAME *name2 = NULL;
  2595. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_handle, &name2);
  2596. if (rc != tool_rc_success) {
  2597. goto tpm2_nvextend_free_name1_name2;
  2598. }
  2599. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  2600. parameter_hash_algorithm, cp_hash);
  2601. tpm2_nvextend_free_name1_name2:
  2602. Esys_Free(name2);
  2603. tpm2_nvextend_free_name1:
  2604. Esys_Free(name1);
  2605. /*
  2606. * Exit here without making the ESYS call since we just need the cpHash
  2607. */
  2608. if (!rp_hash->size) {
  2609. goto tpm2_nvextend_skip_esapi_call;
  2610. }
  2611. }
  2612. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  2613. rc = tpm2_auth_util_get_shandle(esys_context,
  2614. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  2615. &auth_hierarchy_obj_session_handle);
  2616. if (rc != tool_rc_success) {
  2617. LOG_ERR("Failed to get shandle");
  2618. return rc;
  2619. }
  2620. rval = Esys_NV_Extend(esys_context, auth_hierarchy_obj->tr_handle,
  2621. esys_tr_nv_handle, auth_hierarchy_obj_session_handle, shandle2,
  2622. shandle3, data);
  2623. if (rval != TPM2_RC_SUCCESS) {
  2624. LOG_PERR(Esys_NV_Extend, rval);
  2625. return tool_rc_from_tpm(rval);
  2626. }
  2627. if (rp_hash->size) {
  2628. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  2629. parameter_hash_algorithm);
  2630. }
  2631. tpm2_nvextend_skip_esapi_call:
  2632. return rc;
  2633. }
  2634. tool_rc tpm2_nvundefine(ESYS_CONTEXT *esys_context,
  2635. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nv_index,
  2636. TPM2B_DIGEST *cp_hash) {
  2637. ESYS_TR esys_tr_nv_handle;
  2638. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  2639. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_handle);
  2640. if (rval != TPM2_RC_SUCCESS) {
  2641. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  2642. return tool_rc_from_tpm(rval);
  2643. }
  2644. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  2645. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2646. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  2647. &auth_hierarchy_obj_session_handle);
  2648. if (rc != tool_rc_success) {
  2649. LOG_ERR("Couldn't get shandle");
  2650. return rc;
  2651. }
  2652. if (cp_hash) {
  2653. /*
  2654. * Need sys_context to be able to calculate CpHash
  2655. */
  2656. TSS2_SYS_CONTEXT *sys_context = NULL;
  2657. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2658. if(rc != tool_rc_success) {
  2659. LOG_ERR("Failed to acquire SAPI context.");
  2660. return rc;
  2661. }
  2662. rval = Tss2_Sys_NV_UndefineSpace_Prepare(sys_context,
  2663. auth_hierarchy_obj->handle, nv_index);
  2664. if (rval != TPM2_RC_SUCCESS) {
  2665. LOG_PERR(Tss2_Sys_NV_UndefineSpace_Prepare, rval);
  2666. return tool_rc_general_error;
  2667. }
  2668. TPM2B_NAME *name1 = NULL;
  2669. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  2670. &name1);
  2671. if (rc != tool_rc_success) {
  2672. goto tpm2_nvundefine_free_name1;
  2673. }
  2674. TPM2B_NAME *name2 = NULL;
  2675. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_handle, &name2);
  2676. if (rc != tool_rc_success) {
  2677. goto tpm2_nvundefine_free_name1_name2;
  2678. }
  2679. cp_hash->size = tpm2_alg_util_get_hash_size(
  2680. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  2681. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  2682. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  2683. /*
  2684. * Exit here without making the ESYS call since we just need the cpHash
  2685. */
  2686. tpm2_nvundefine_free_name1_name2:
  2687. Esys_Free(name2);
  2688. tpm2_nvundefine_free_name1:
  2689. Esys_Free(name1);
  2690. goto tpm2_nvundefine_skip_esapi_call;
  2691. }
  2692. rval = Esys_NV_UndefineSpace(esys_context, auth_hierarchy_obj->tr_handle,
  2693. esys_tr_nv_handle, auth_hierarchy_obj_session_handle, ESYS_TR_NONE,
  2694. ESYS_TR_NONE);
  2695. if (rval != TPM2_RC_SUCCESS) {
  2696. LOG_ERR("Failed to release NV area at index 0x%X", nv_index);
  2697. LOG_PERR(Esys_NV_UndefineSpace, rval);
  2698. return tool_rc_from_tpm(rval);
  2699. }
  2700. LOG_INFO("Success to release NV area at index 0x%x.", nv_index);
  2701. tpm2_nvundefine_skip_esapi_call:
  2702. return rc;
  2703. }
  2704. tool_rc tpm2_nvundefinespecial(ESYS_CONTEXT *esys_context,
  2705. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nv_index,
  2706. tpm2_session *policy_session, TPM2B_DIGEST *cp_hash) {
  2707. ESYS_TR esys_tr_nv_handle;
  2708. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  2709. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_handle);
  2710. if (rval != TPM2_RC_SUCCESS) {
  2711. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  2712. return tool_rc_from_tpm(rval);
  2713. }
  2714. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  2715. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2716. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  2717. &auth_hierarchy_obj_session_handle);
  2718. if (rc != tool_rc_success) {
  2719. LOG_ERR("Couldn't get shandle");
  2720. return rc;
  2721. }
  2722. ESYS_TR policy_session_handle = tpm2_session_get_handle(policy_session);
  2723. if (cp_hash) {
  2724. /*
  2725. * Need sys_context to be able to calculate CpHash
  2726. */
  2727. TSS2_SYS_CONTEXT *sys_context = NULL;
  2728. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2729. if(rc != tool_rc_success) {
  2730. LOG_ERR("Failed to acquire SAPI context.");
  2731. return rc;
  2732. }
  2733. rval = Tss2_Sys_NV_UndefineSpaceSpecial_Prepare(sys_context, nv_index,
  2734. auth_hierarchy_obj->handle);
  2735. if (rval != TPM2_RC_SUCCESS) {
  2736. LOG_PERR(Tss2_Sys_NV_UndefineSpaceSpecial_Prepare, rval);
  2737. return tool_rc_general_error;
  2738. }
  2739. TPM2B_NAME *name1 = NULL;
  2740. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_handle, &name1);
  2741. if (rc != tool_rc_success) {
  2742. goto tpm2_nvundefinespecial_free_name1;
  2743. }
  2744. TPM2B_NAME *name2 = NULL;
  2745. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle,
  2746. &name2);
  2747. if (rc != tool_rc_success) {
  2748. goto tpm2_nvundefinespecial_free_name1_name2;
  2749. }
  2750. cp_hash->size = tpm2_alg_util_get_hash_size(
  2751. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  2752. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  2753. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  2754. /*
  2755. * Exit here without making the ESYS call since we just need the cpHash
  2756. */
  2757. tpm2_nvundefinespecial_free_name1_name2:
  2758. Esys_Free(name2);
  2759. tpm2_nvundefinespecial_free_name1:
  2760. Esys_Free(name1);
  2761. goto tpm2_nvundefinespecial_skip_esapi_call;
  2762. }
  2763. rval = Esys_NV_UndefineSpaceSpecial(esys_context,
  2764. esys_tr_nv_handle,
  2765. auth_hierarchy_obj->tr_handle,
  2766. policy_session_handle, // policy session
  2767. auth_hierarchy_obj_session_handle, // auth session for hierarchy
  2768. ESYS_TR_NONE);
  2769. if (rval != TPM2_RC_SUCCESS) {
  2770. LOG_ERR("Failed to release NV area at index 0x%X", nv_index);
  2771. LOG_PERR(Esys_NV_UndefineSpaceSpecial, rval);
  2772. return tool_rc_from_tpm(rval);
  2773. }
  2774. LOG_INFO("Success to release NV area at index 0x%x.", nv_index);
  2775. tpm2_nvundefinespecial_skip_esapi_call:
  2776. return rc;
  2777. }
  2778. tool_rc tpm2_nvwrite(ESYS_CONTEXT *esys_context,
  2779. tpm2_loaded_object *auth_hierarchy_obj, TPM2_HANDLE nvindex,
  2780. const TPM2B_MAX_NV_BUFFER *data, UINT16 offset, TPM2B_DIGEST *cp_hash) {
  2781. // Convert TPM2_HANDLE ctx.nv_index to an ESYS_TR
  2782. ESYS_TR esys_tr_nv_index;
  2783. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nvindex, ESYS_TR_NONE,
  2784. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_index);
  2785. if (rval != TPM2_RC_SUCCESS) {
  2786. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  2787. return tool_rc_from_tpm(rval);
  2788. }
  2789. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  2790. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2791. auth_hierarchy_obj->tr_handle, auth_hierarchy_obj->session,
  2792. &auth_hierarchy_obj_session_handle);
  2793. if (rc != tool_rc_success) {
  2794. LOG_ERR("Failed to get shandle");
  2795. return rc;
  2796. }
  2797. if (cp_hash) {
  2798. /*
  2799. * Need sys_context to be able to calculate CpHash
  2800. */
  2801. TSS2_SYS_CONTEXT *sys_context = NULL;
  2802. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2803. if(rc != tool_rc_success) {
  2804. LOG_ERR("Failed to acquire SAPI context.");
  2805. return rc;
  2806. }
  2807. rval = Tss2_Sys_NV_Write_Prepare(sys_context, auth_hierarchy_obj->handle,
  2808. nvindex, data, offset);
  2809. if (rval != TPM2_RC_SUCCESS) {
  2810. LOG_PERR(Tss2_Sys_NV_Write_Prepare, rval);
  2811. return tool_rc_general_error;
  2812. }
  2813. TPM2B_NAME *name1 = NULL;
  2814. rc = tpm2_tr_get_name(esys_context, auth_hierarchy_obj->tr_handle, &name1);
  2815. if (rc != tool_rc_success) {
  2816. goto tpm2_nvwrite_free_name1;
  2817. }
  2818. TPM2B_NAME *name2 = NULL;
  2819. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_index, &name2);
  2820. if (rc != tool_rc_success) {
  2821. goto tpm2_nvwrite_free_name1_name2;
  2822. }
  2823. cp_hash->size = tpm2_alg_util_get_hash_size(
  2824. tpm2_session_get_authhash(auth_hierarchy_obj->session));
  2825. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  2826. tpm2_session_get_authhash(auth_hierarchy_obj->session), cp_hash);
  2827. /*
  2828. * Exit here without making the ESYS call since we just need the cpHash
  2829. */
  2830. tpm2_nvwrite_free_name1_name2:
  2831. Esys_Free(name2);
  2832. tpm2_nvwrite_free_name1:
  2833. Esys_Free(name1);
  2834. goto tpm2_nvwrite_skip_esapi_call;
  2835. }
  2836. rval = Esys_NV_Write(esys_context, auth_hierarchy_obj->tr_handle,
  2837. esys_tr_nv_index, auth_hierarchy_obj_session_handle, ESYS_TR_NONE,
  2838. ESYS_TR_NONE, data, offset);
  2839. if (rval != TPM2_RC_SUCCESS) {
  2840. LOG_ERR("Failed to write NV area at index 0x%X", nvindex);
  2841. LOG_PERR(Tss2_Sys_NV_Write, rval);
  2842. return tool_rc_from_tpm(rval);
  2843. }
  2844. LOG_INFO("Success to write NV area at index 0x%x offset 0x%x.", nvindex,
  2845. offset);
  2846. tpm2_nvwrite_skip_esapi_call:
  2847. return rc;
  2848. }
  2849. tool_rc tpm2_pcr_allocate(ESYS_CONTEXT *esys_context,
  2850. tpm2_loaded_object *auth_hierarchy_obj,
  2851. const TPML_PCR_SELECTION *pcr_allocation) {
  2852. TSS2_RC rval;
  2853. TPMI_YES_NO allocation_success;
  2854. UINT32 max_pcr;
  2855. UINT32 size_needed;
  2856. UINT32 size_available;
  2857. ESYS_TR auth_hierarchy_obj_session_handle = ESYS_TR_NONE;
  2858. tool_rc rc = tpm2_auth_util_get_shandle(esys_context, ESYS_TR_RH_PLATFORM,
  2859. auth_hierarchy_obj->session, &auth_hierarchy_obj_session_handle);
  2860. if (rc != tool_rc_success) {
  2861. LOG_ERR("Couldn't get shandle for lockout hierarchy");
  2862. return rc;
  2863. }
  2864. rval = Esys_PCR_Allocate(esys_context, ESYS_TR_RH_PLATFORM,
  2865. auth_hierarchy_obj_session_handle, ESYS_TR_NONE, ESYS_TR_NONE,
  2866. pcr_allocation, &allocation_success, &max_pcr, &size_needed,
  2867. &size_available);
  2868. if (rval != TSS2_RC_SUCCESS) {
  2869. LOG_ERR("Could not allocate PCRs.");
  2870. LOG_PERR(Esys_PCR_Allocate, rval);
  2871. return tool_rc_from_tpm(rval);
  2872. }
  2873. if (!allocation_success) {
  2874. LOG_ERR("Allocation failed. "
  2875. "MaxPCR: %i, Size Needed: %i, Size available: %i", max_pcr,
  2876. size_needed, size_available);
  2877. return tool_rc_general_error;
  2878. }
  2879. return tool_rc_success;
  2880. }
  2881. tool_rc tpm2_sign(ESYS_CONTEXT *esys_context, tpm2_loaded_object *signingkey_obj,
  2882. TPM2B_DIGEST *digest, TPMT_SIG_SCHEME *in_scheme,
  2883. TPMT_TK_HASHCHECK *validation, TPMT_SIGNATURE **signature,
  2884. TPM2B_DIGEST *cp_hash) {
  2885. ESYS_TR signingkey_obj_session_handle = ESYS_TR_NONE;
  2886. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2887. signingkey_obj->tr_handle, signingkey_obj->session,
  2888. &signingkey_obj_session_handle);
  2889. if (rc != tool_rc_success) {
  2890. return rc;
  2891. }
  2892. if (cp_hash) {
  2893. /*
  2894. * Need sys_context to be able to calculate CpHash
  2895. */
  2896. TSS2_SYS_CONTEXT *sys_context = NULL;
  2897. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2898. if(rc != tool_rc_success) {
  2899. LOG_ERR("Failed to acquire SAPI context.");
  2900. return rc;
  2901. }
  2902. TSS2_RC rval = Tss2_Sys_Sign_Prepare(sys_context,
  2903. signingkey_obj->handle, digest, in_scheme, validation);
  2904. if (rval != TPM2_RC_SUCCESS) {
  2905. LOG_PERR(Tss2_Sys_Sign_Prepare, rval);
  2906. return tool_rc_general_error;
  2907. }
  2908. TPM2B_NAME *name1 = NULL;
  2909. rc = tpm2_tr_get_name(esys_context, signingkey_obj->tr_handle,
  2910. &name1);
  2911. if (rc != tool_rc_success) {
  2912. goto tpm2_sign_free_name1;
  2913. }
  2914. cp_hash->size = tpm2_alg_util_get_hash_size(
  2915. tpm2_session_get_authhash(signingkey_obj->session));
  2916. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  2917. tpm2_session_get_authhash(signingkey_obj->session), cp_hash);
  2918. /*
  2919. * Exit here without making the ESYS call since we just need the cpHash
  2920. */
  2921. tpm2_sign_free_name1:
  2922. Esys_Free(name1);
  2923. goto tpm2_sign_skip_esapi_call;
  2924. }
  2925. TSS2_RC rval = Esys_Sign(esys_context, signingkey_obj->tr_handle,
  2926. signingkey_obj_session_handle, ESYS_TR_NONE, ESYS_TR_NONE, digest,
  2927. in_scheme, validation, signature);
  2928. if (rval != TPM2_RC_SUCCESS) {
  2929. LOG_PERR(Eys_Sign, rval);
  2930. rc = tool_rc_from_tpm(rval);
  2931. return rc;
  2932. }
  2933. tpm2_sign_skip_esapi_call:
  2934. return rc;
  2935. }
  2936. tool_rc tpm2_nvcertify(ESYS_CONTEXT *esys_context,
  2937. tpm2_loaded_object *signingkey_obj, tpm2_loaded_object *nvindex_authobj,
  2938. TPM2_HANDLE nv_index, UINT16 offset, UINT16 size,
  2939. TPMT_SIG_SCHEME *in_scheme, TPM2B_ATTEST **certify_info,
  2940. TPMT_SIGNATURE **signature, TPM2B_DATA *policy_qualifier,
  2941. TPM2B_DIGEST *cp_hash) {
  2942. ESYS_TR signingkey_obj_session_handle = ESYS_TR_NONE;
  2943. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  2944. signingkey_obj->tr_handle, signingkey_obj->session,
  2945. &signingkey_obj_session_handle);
  2946. if (rc != tool_rc_success) {
  2947. return rc;
  2948. }
  2949. ESYS_TR nvindex_authobj_session_handle = ESYS_TR_NONE;
  2950. rc = tpm2_auth_util_get_shandle(esys_context,
  2951. nvindex_authobj->tr_handle, nvindex_authobj->session,
  2952. &nvindex_authobj_session_handle);
  2953. if (rc != tool_rc_success) {
  2954. return rc;
  2955. }
  2956. ESYS_TR esys_tr_nv_index;
  2957. TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE,
  2958. ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_index);
  2959. if (rval != TPM2_RC_SUCCESS) {
  2960. LOG_PERR(Esys_TR_FromTPMPublic, rval);
  2961. return tool_rc_from_tpm(rval);
  2962. }
  2963. if (cp_hash) {
  2964. /*
  2965. * Need sys_context to be able to calculate CpHash
  2966. */
  2967. TSS2_SYS_CONTEXT *sys_context = NULL;
  2968. rc = tpm2_getsapicontext(esys_context, &sys_context);
  2969. if(rc != tool_rc_success) {
  2970. LOG_ERR("Failed to acquire SAPI context.");
  2971. return rc;
  2972. }
  2973. rval = Tss2_Sys_NV_Certify_Prepare(sys_context, signingkey_obj->handle,
  2974. nvindex_authobj->handle, nv_index, policy_qualifier, in_scheme,
  2975. size, offset);
  2976. if (rval != TPM2_RC_SUCCESS) {
  2977. LOG_PERR(Tss2_Sys_NV_Certify_Prepare, rval);
  2978. return tool_rc_general_error;
  2979. }
  2980. TPM2B_NAME *name1 = NULL;
  2981. rc = tpm2_tr_get_name(esys_context, signingkey_obj->tr_handle, &name1);
  2982. if (rc != tool_rc_success) {
  2983. goto tpm2_nvcertify_free_name1;
  2984. }
  2985. TPM2B_NAME *name2 = NULL;
  2986. rc = tpm2_tr_get_name(esys_context, nvindex_authobj->tr_handle, &name2);
  2987. if (rc != tool_rc_success) {
  2988. goto tpm2_nvcertify_free_name1_name2;
  2989. }
  2990. TPM2B_NAME *name3 = NULL;
  2991. rc = tpm2_tr_get_name(esys_context, esys_tr_nv_index, &name3);
  2992. if (rc != tool_rc_success) {
  2993. goto tpm2_nvcertify_free_name1_name2_name3;
  2994. }
  2995. cp_hash->size = tpm2_alg_util_get_hash_size(
  2996. tpm2_session_get_authhash(signingkey_obj->session));
  2997. rc = tpm2_sapi_getcphash(sys_context, name1, name2, name3,
  2998. tpm2_session_get_authhash(signingkey_obj->session), cp_hash);
  2999. /*
  3000. * Exit here without making the ESYS call since we just need the cpHash
  3001. */
  3002. tpm2_nvcertify_free_name1_name2_name3:
  3003. Esys_Free(name3);
  3004. tpm2_nvcertify_free_name1_name2:
  3005. Esys_Free(name2);
  3006. tpm2_nvcertify_free_name1:
  3007. Esys_Free(name1);
  3008. goto tpm2_nvcertify_skip_esapi_call;
  3009. }
  3010. rval = Esys_NV_Certify(esys_context, signingkey_obj->tr_handle,
  3011. nvindex_authobj->tr_handle, esys_tr_nv_index,
  3012. signingkey_obj_session_handle, nvindex_authobj_session_handle,
  3013. ESYS_TR_NONE, policy_qualifier, in_scheme, size, offset, certify_info,
  3014. signature);
  3015. if (rval != TPM2_RC_SUCCESS) {
  3016. LOG_PERR(Esys_NV_Certify, rval);
  3017. return tool_rc_from_tpm(rval);
  3018. }
  3019. tpm2_nvcertify_skip_esapi_call:
  3020. return rc;
  3021. }
  3022. tool_rc tpm2_certifycreation(ESYS_CONTEXT *esys_context,
  3023. tpm2_loaded_object *signingkey_obj, tpm2_loaded_object *certifiedkey_obj,
  3024. TPM2B_DIGEST *creation_hash, TPMT_SIG_SCHEME *in_scheme,
  3025. TPMT_TK_CREATION *creation_ticket, TPM2B_ATTEST **certify_info,
  3026. TPMT_SIGNATURE **signature, TPM2B_DATA *policy_qualifier,
  3027. TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
  3028. TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle2, ESYS_TR shandle3) {
  3029. TSS2_SYS_CONTEXT *sys_context = NULL;
  3030. tool_rc rc = tool_rc_success;
  3031. if (cp_hash->size || rp_hash->size) {
  3032. rc = tpm2_getsapicontext(esys_context, &sys_context);
  3033. if(rc != tool_rc_success) {
  3034. LOG_ERR("Failed to acquire SAPI context.");
  3035. return rc;
  3036. }
  3037. }
  3038. if (cp_hash->size) {
  3039. TSS2_RC rval = Tss2_Sys_CertifyCreation_Prepare(sys_context,
  3040. signingkey_obj->handle, certifiedkey_obj->handle, policy_qualifier,
  3041. creation_hash, in_scheme, creation_ticket);
  3042. if (rval != TPM2_RC_SUCCESS) {
  3043. LOG_PERR(Tss2_Sys_CertifyCreation_Prepare, rval);
  3044. return tool_rc_general_error;
  3045. }
  3046. TPM2B_NAME *name1 = NULL;
  3047. rc = tpm2_tr_get_name(esys_context, signingkey_obj->tr_handle, &name1);
  3048. if (rc != tool_rc_success) {
  3049. goto tpm2_certifycreation_free_name1;
  3050. }
  3051. TPM2B_NAME *name2 = NULL;
  3052. rc = tpm2_tr_get_name(esys_context, certifiedkey_obj->tr_handle, &name2);
  3053. if (rc != tool_rc_success) {
  3054. goto tpm2_certifycreation_free_name1_name2;
  3055. }
  3056. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  3057. parameter_hash_algorithm, cp_hash);
  3058. tpm2_certifycreation_free_name1_name2:
  3059. Esys_Free(name2);
  3060. tpm2_certifycreation_free_name1:
  3061. Esys_Free(name1);
  3062. /*
  3063. * Exit here without making the ESYS call since we just need the cpHash
  3064. */
  3065. if (!rp_hash->size || rc != tool_rc_success) {
  3066. goto tpm2_certifycreation_skip_esapi_call;
  3067. }
  3068. }
  3069. ESYS_TR signingkey_obj_session_handle = ESYS_TR_NONE;
  3070. rc = tpm2_auth_util_get_shandle(esys_context, signingkey_obj->tr_handle,
  3071. signingkey_obj->session, &signingkey_obj_session_handle);
  3072. if (rc != tool_rc_success) {
  3073. return rc;
  3074. }
  3075. TSS2_RC rval = Esys_CertifyCreation(esys_context, signingkey_obj->tr_handle,
  3076. certifiedkey_obj->tr_handle, signingkey_obj_session_handle,
  3077. shandle2, shandle3, policy_qualifier, creation_hash, in_scheme,
  3078. creation_ticket, certify_info, signature);
  3079. if (rval != TPM2_RC_SUCCESS) {
  3080. LOG_PERR(Esys_CertifyCreation, rval);
  3081. return tool_rc_from_tpm(rval);
  3082. }
  3083. if (rp_hash->size) {
  3084. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  3085. parameter_hash_algorithm);
  3086. }
  3087. tpm2_certifycreation_skip_esapi_call:
  3088. return rc;
  3089. }
  3090. tool_rc tpm2_setprimarypolicy(ESYS_CONTEXT *esys_context,
  3091. tpm2_loaded_object *hierarchy_object, TPM2B_DIGEST *auth_policy,
  3092. TPMI_ALG_HASH hash_algorithm, TPM2B_DIGEST *cp_hash) {
  3093. ESYS_TR hierarchy_object_session_handle = ESYS_TR_NONE;
  3094. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  3095. hierarchy_object->tr_handle, hierarchy_object->session,
  3096. &hierarchy_object_session_handle);
  3097. if (rc != tool_rc_success) {
  3098. return rc;
  3099. }
  3100. if (cp_hash) {
  3101. /*
  3102. * Need sys_context to be able to calculate CpHash
  3103. */
  3104. TSS2_SYS_CONTEXT *sys_context = NULL;
  3105. rc = tpm2_getsapicontext(esys_context, &sys_context);
  3106. if(rc != tool_rc_success) {
  3107. LOG_ERR("Failed to acquire SAPI context.");
  3108. return rc;
  3109. }
  3110. TSS2_RC rval = Tss2_Sys_SetPrimaryPolicy_Prepare(sys_context,
  3111. hierarchy_object->handle, auth_policy, hash_algorithm);
  3112. if (rval != TPM2_RC_SUCCESS) {
  3113. LOG_PERR(Tss2_Sys_SetPrimaryPolicy_Prepare, rval);
  3114. return tool_rc_general_error;
  3115. }
  3116. TPM2B_NAME *name1 = NULL;
  3117. rc = tpm2_tr_get_name(esys_context, hierarchy_object->tr_handle,
  3118. &name1);
  3119. if (rc != tool_rc_success) {
  3120. goto tpm2_setprimarypolicy_free_name1;
  3121. }
  3122. cp_hash->size = tpm2_alg_util_get_hash_size(
  3123. tpm2_session_get_authhash(hierarchy_object->session));
  3124. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  3125. tpm2_session_get_authhash(hierarchy_object->session), cp_hash);
  3126. /*
  3127. * Exit here without making the ESYS call since we just need the cpHash
  3128. */
  3129. tpm2_setprimarypolicy_free_name1:
  3130. Esys_Free(name1);
  3131. goto tpm2_setprimarypolicy_skip_esapi_call;
  3132. }
  3133. TSS2_RC rval = Esys_SetPrimaryPolicy(esys_context,
  3134. hierarchy_object->tr_handle, hierarchy_object_session_handle,
  3135. ESYS_TR_NONE, ESYS_TR_NONE, auth_policy, hash_algorithm);
  3136. if (rval != TPM2_RC_SUCCESS) {
  3137. LOG_PERR(Esys_SetPrimaryPolicy, rval);
  3138. return tool_rc_from_tpm(rval);
  3139. }
  3140. tpm2_setprimarypolicy_skip_esapi_call:
  3141. return rc;
  3142. }
  3143. tool_rc tpm2_quote(ESYS_CONTEXT *esys_context, tpm2_loaded_object *quote_obj,
  3144. TPMT_SIG_SCHEME *in_scheme, TPM2B_DATA *qualifying_data,
  3145. TPML_PCR_SELECTION *pcr_select, TPM2B_ATTEST **quoted,
  3146. TPMT_SIGNATURE **signature, TPM2B_DIGEST *cp_hash) {
  3147. ESYS_TR quote_obj_session_handle = ESYS_TR_NONE;
  3148. tool_rc rc = tpm2_auth_util_get_shandle(esys_context, quote_obj->tr_handle,
  3149. quote_obj->session, &quote_obj_session_handle);
  3150. if (rc != tool_rc_success) {
  3151. LOG_ERR("Failed to get shandle");
  3152. return rc;
  3153. }
  3154. if (cp_hash) {
  3155. /*
  3156. * Need sys_context to be able to calculate CpHash
  3157. */
  3158. TSS2_SYS_CONTEXT *sys_context = NULL;
  3159. rc = tpm2_getsapicontext(esys_context, &sys_context);
  3160. if(rc != tool_rc_success) {
  3161. LOG_ERR("Failed to acquire SAPI context.");
  3162. return rc;
  3163. }
  3164. TSS2_RC rval = Tss2_Sys_Quote_Prepare(sys_context, quote_obj->handle,
  3165. qualifying_data, in_scheme, pcr_select);
  3166. if (rval != TPM2_RC_SUCCESS) {
  3167. LOG_PERR(Tss2_Sys_Quote_Prepare, rval);
  3168. return tool_rc_general_error;
  3169. }
  3170. TPM2B_NAME *name1 = NULL;
  3171. rc = tpm2_tr_get_name(esys_context, quote_obj->tr_handle, &name1);
  3172. if (rc != tool_rc_success) {
  3173. goto tpm2_quote_free_name1;
  3174. }
  3175. cp_hash->size = tpm2_alg_util_get_hash_size(
  3176. tpm2_session_get_authhash(quote_obj->session));
  3177. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  3178. tpm2_session_get_authhash(quote_obj->session), cp_hash);
  3179. /*
  3180. * Exit here without making the ESYS call since we just need the cpHash
  3181. */
  3182. tpm2_quote_free_name1:
  3183. Esys_Free(name1);
  3184. goto tpm2_quote_skip_esapi_call;
  3185. }
  3186. TSS2_RC rval = Esys_Quote(esys_context, quote_obj->tr_handle,
  3187. quote_obj_session_handle, ESYS_TR_NONE, ESYS_TR_NONE,
  3188. qualifying_data, in_scheme, pcr_select, quoted, signature);
  3189. if (rval != TPM2_RC_SUCCESS) {
  3190. LOG_PERR(Esys_Quote, rval);
  3191. return tool_rc_from_tpm(rval);
  3192. }
  3193. tpm2_quote_skip_esapi_call:
  3194. return rc;
  3195. }
  3196. tool_rc tpm2_changeeps(ESYS_CONTEXT *ectx,
  3197. tpm2_session *platform_hierarchy_session, TPM2B_DIGEST *cp_hash,
  3198. TPM2B_DIGEST *rp_hash, TPMI_ALG_HASH parameter_hash_algorithm,
  3199. ESYS_TR shandle2, ESYS_TR shandle3) {
  3200. TSS2_SYS_CONTEXT *sys_context = NULL;
  3201. tool_rc rc = tool_rc_success;
  3202. if (cp_hash->size || rp_hash->size) {
  3203. rc = tpm2_getsapicontext(ectx, &sys_context);
  3204. if(rc != tool_rc_success) {
  3205. LOG_ERR("Failed to acquire SAPI context.");
  3206. return rc;
  3207. }
  3208. }
  3209. if (cp_hash->size) {
  3210. TSS2_RC rval = Tss2_Sys_ChangeEPS_Prepare(sys_context, TPM2_RH_PLATFORM);
  3211. if (rval != TPM2_RC_SUCCESS) {
  3212. LOG_PERR(Tss2_Sys_ObjectChangeAuth_Prepare, rval);
  3213. return tool_rc_general_error;
  3214. }
  3215. TPM2B_NAME *name1 = NULL;
  3216. rc = tpm2_tr_get_name(ectx, ESYS_TR_RH_PLATFORM ,&name1);
  3217. if (rc != tool_rc_success) {
  3218. goto tpm2_changeeps_free_name1;
  3219. }
  3220. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  3221. parameter_hash_algorithm, cp_hash);
  3222. tpm2_changeeps_free_name1:
  3223. Esys_Free(name1);
  3224. /*
  3225. * Exit here without making the ESYS call since we just need the cpHash
  3226. */
  3227. if (!rp_hash->size || rc != tool_rc_success) {
  3228. goto tpm2_changeeps_skip_esapi_call;
  3229. }
  3230. }
  3231. ESYS_TR platform_hierarchy_session_handle = ESYS_TR_NONE;
  3232. rc = tpm2_auth_util_get_shandle(ectx, ESYS_TR_RH_PLATFORM,
  3233. platform_hierarchy_session, &platform_hierarchy_session_handle);
  3234. if (rc != tool_rc_success) {
  3235. return rc;
  3236. }
  3237. TSS2_RC rval = Esys_ChangeEPS(ectx, ESYS_TR_RH_PLATFORM,
  3238. platform_hierarchy_session_handle, shandle2, shandle3);
  3239. if (rval != TPM2_RC_SUCCESS) {
  3240. LOG_PERR(Esys_ChangeEPS, rval);
  3241. return tool_rc_from_tpm(rval);
  3242. }
  3243. if (rp_hash->size) {
  3244. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  3245. parameter_hash_algorithm);
  3246. }
  3247. tpm2_changeeps_skip_esapi_call:
  3248. return rc;
  3249. }
  3250. tool_rc tpm2_changepps(ESYS_CONTEXT *ectx,
  3251. tpm2_session *platform_hierarchy_session, TPM2B_DIGEST *cp_hash,
  3252. TPM2B_DIGEST *rp_hash, TPMI_ALG_HASH parameter_hash_algorithm,
  3253. ESYS_TR shandle2, ESYS_TR shandle3) {
  3254. TSS2_SYS_CONTEXT *sys_context = NULL;
  3255. tool_rc rc = (cp_hash->size || rp_hash->size) ?
  3256. tpm2_getsapicontext(ectx, &sys_context)
  3257. : tool_rc_success;
  3258. if(rc != tool_rc_success) {
  3259. LOG_ERR("Failed to acquire SAPI context.");
  3260. return rc;
  3261. }
  3262. if (cp_hash->size) {
  3263. TSS2_RC rval = Tss2_Sys_ChangePPS_Prepare(sys_context, TPM2_RH_PLATFORM);
  3264. if (rval != TPM2_RC_SUCCESS) {
  3265. LOG_PERR(Tss2_Sys_ObjectChangeAuth_Prepare, rval);
  3266. return tool_rc_general_error;
  3267. }
  3268. TPM2B_NAME *name1 = NULL;
  3269. rc = tpm2_tr_get_name(ectx, ESYS_TR_RH_PLATFORM ,&name1);
  3270. if (rc != tool_rc_success) {
  3271. goto tpm2_changepps_free_name1;
  3272. }
  3273. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  3274. parameter_hash_algorithm, cp_hash);
  3275. tpm2_changepps_free_name1:
  3276. Esys_Free(name1);
  3277. /*
  3278. * Exit here without making the ESYS call since we just need the cpHash
  3279. */
  3280. if (!rp_hash->size || rc != tool_rc_success) {
  3281. goto tpm2_changepps_skip_esapi_call;
  3282. }
  3283. }
  3284. ESYS_TR platform_hierarchy_session_handle = ESYS_TR_NONE;
  3285. rc = tpm2_auth_util_get_shandle(ectx, ESYS_TR_RH_PLATFORM,
  3286. platform_hierarchy_session, &platform_hierarchy_session_handle);
  3287. if (rc != tool_rc_success) {
  3288. return rc;
  3289. }
  3290. TSS2_RC rval = Esys_ChangePPS(ectx, ESYS_TR_RH_PLATFORM,
  3291. platform_hierarchy_session_handle, shandle2, shandle3);
  3292. if (rval != TPM2_RC_SUCCESS) {
  3293. LOG_PERR(Esys_ChangePPS, rval);
  3294. return tool_rc_from_tpm(rval);
  3295. }
  3296. if (rp_hash->size) {
  3297. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  3298. parameter_hash_algorithm);
  3299. }
  3300. tpm2_changepps_skip_esapi_call:
  3301. return rc;
  3302. }
  3303. tool_rc tpm2_unseal(ESYS_CONTEXT *esys_context, tpm2_loaded_object *sealkey_obj,
  3304. TPM2B_SENSITIVE_DATA **out_data, TPM2B_DIGEST *cp_hash,
  3305. TPM2B_DIGEST *rp_hash, TPMI_ALG_HASH parameter_hash_algorithm,
  3306. ESYS_TR shandle2, ESYS_TR shandle3) {
  3307. TSS2_SYS_CONTEXT *sys_context = NULL;
  3308. tool_rc rc = tool_rc_success;
  3309. if (cp_hash->size || rp_hash->size) {
  3310. rc = tpm2_getsapicontext(esys_context, &sys_context);
  3311. if(rc != tool_rc_success) {
  3312. LOG_ERR("Failed to acquire SAPI context.");
  3313. return rc;
  3314. }
  3315. }
  3316. if (cp_hash->size) {
  3317. /*
  3318. * Need sys_context to be able to calculate CpHash
  3319. */
  3320. TSS2_SYS_CONTEXT *sys_context = NULL;
  3321. rc = tpm2_getsapicontext(esys_context, &sys_context);
  3322. if(rc != tool_rc_success) {
  3323. LOG_ERR("Failed to acquire SAPI context.");
  3324. return rc;
  3325. }
  3326. TSS2_RC rval = Tss2_Sys_Unseal_Prepare(sys_context,
  3327. sealkey_obj->handle);
  3328. if (rval != TPM2_RC_SUCCESS) {
  3329. LOG_PERR(Tss2_Sys_Unseal_Prepare, rval);
  3330. return tool_rc_general_error;
  3331. }
  3332. TPM2B_NAME *name1 = NULL;
  3333. rc = tpm2_tr_get_name(esys_context, sealkey_obj->tr_handle,
  3334. &name1);
  3335. if (rc != tool_rc_success) {
  3336. goto tpm2_unseal_free_name1;
  3337. }
  3338. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  3339. parameter_hash_algorithm, cp_hash);
  3340. tpm2_unseal_free_name1:
  3341. Esys_Free(name1);
  3342. /*
  3343. * Exit here without making the ESYS call since we just need the cpHash
  3344. */
  3345. if (!rp_hash->size) {
  3346. goto tpm2_unseal_skip_esapi_call;
  3347. }
  3348. }
  3349. ESYS_TR sealkey_obj_session_handle = ESYS_TR_NONE;
  3350. rc = tpm2_auth_util_get_shandle(esys_context, sealkey_obj->tr_handle,
  3351. sealkey_obj->session, &sealkey_obj_session_handle);
  3352. if (rc != tool_rc_success) {
  3353. return rc;
  3354. }
  3355. TSS2_RC rval = Esys_Unseal(esys_context, sealkey_obj->tr_handle,
  3356. sealkey_obj_session_handle, shandle2, shandle3, out_data);
  3357. if (rval != TPM2_RC_SUCCESS) {
  3358. LOG_PERR(Esys_Unseal, rval);
  3359. return tool_rc_from_tpm(rval);
  3360. }
  3361. if (rp_hash->size) {
  3362. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  3363. parameter_hash_algorithm);
  3364. }
  3365. tpm2_unseal_skip_esapi_call:
  3366. return rc;
  3367. }
  3368. tool_rc tpm2_incrementalselftest(ESYS_CONTEXT *ectx, const TPML_ALG *to_test,
  3369. TPML_ALG **to_do_list) {
  3370. TSS2_RC rval = Esys_IncrementalSelfTest(ectx, ESYS_TR_NONE, ESYS_TR_NONE,
  3371. ESYS_TR_NONE, to_test, to_do_list);
  3372. if (rval != TPM2_RC_SUCCESS) {
  3373. LOG_PERR(Esys_IncrementalSelfTest, rval);
  3374. return tool_rc_from_tpm(rval);
  3375. }
  3376. return tool_rc_success;
  3377. }
  3378. tool_rc tpm2_stirrandom(ESYS_CONTEXT *ectx,
  3379. const TPM2B_SENSITIVE_DATA *data) {
  3380. TSS2_RC rval = Esys_StirRandom(ectx, ESYS_TR_NONE, ESYS_TR_NONE,
  3381. ESYS_TR_NONE, data);
  3382. if (rval != TPM2_RC_SUCCESS) {
  3383. LOG_PERR(Esys_StirRandom, rval);
  3384. return tool_rc_from_tpm(rval);
  3385. }
  3386. return tool_rc_success;
  3387. }
  3388. tool_rc tpm2_selftest(ESYS_CONTEXT *ectx, TPMI_YES_NO full_test) {
  3389. TSS2_RC rval = Esys_SelfTest(ectx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
  3390. full_test);
  3391. if (rval != TPM2_RC_SUCCESS) {
  3392. LOG_PERR(Esys_SelfTest, rval);
  3393. return tool_rc_from_tpm(rval);
  3394. }
  3395. return tool_rc_success;
  3396. }
  3397. tool_rc tpm2_gettestresult(ESYS_CONTEXT *ectx, TPM2B_MAX_BUFFER **out_data,
  3398. TPM2_RC *test_result) {
  3399. TSS2_RC rval = Esys_GetTestResult(ectx, ESYS_TR_NONE, ESYS_TR_NONE,
  3400. ESYS_TR_NONE, out_data, test_result);
  3401. if (rval != TSS2_RC_SUCCESS) {
  3402. LOG_PERR(Esys_GetTestResult, rval);
  3403. return tool_rc_from_tpm(rval);
  3404. }
  3405. return tool_rc_success;
  3406. }
  3407. tool_rc tpm2_loadexternal(ESYS_CONTEXT *ectx, const TPM2B_SENSITIVE *private,
  3408. const TPM2B_PUBLIC *public, TPMI_RH_HIERARCHY hierarchy,
  3409. ESYS_TR *object_handle) {
  3410. TSS2_RC rval = fix_esys_hierarchy(hierarchy, &hierarchy);
  3411. if (rval != TSS2_RC_SUCCESS) {
  3412. LOG_ERR("Unknown hierarchy");
  3413. return tool_rc_from_tpm(rval);
  3414. }
  3415. rval = Esys_LoadExternal(ectx,
  3416. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
  3417. private, public, hierarchy,
  3418. object_handle);
  3419. if (rval != TSS2_RC_SUCCESS) {
  3420. LOG_PERR(Esys_LoadExternal, rval);
  3421. return tool_rc_from_tpm(rval);
  3422. }
  3423. return tool_rc_success;
  3424. }
  3425. tool_rc tpm2_pcr_event(ESYS_CONTEXT *ectx,
  3426. ESYS_TR pcr, tpm2_session *session,
  3427. const TPM2B_EVENT *event_data,
  3428. TPML_DIGEST_VALUES **digests) {
  3429. ESYS_TR shandle1 = ESYS_TR_NONE;
  3430. tool_rc rc = tpm2_auth_util_get_shandle(ectx, pcr, session,
  3431. &shandle1);
  3432. if (rc != tool_rc_success) {
  3433. return rc;
  3434. }
  3435. TSS2_RC rval = Esys_PCR_Event(ectx, pcr, shandle1, ESYS_TR_NONE,
  3436. ESYS_TR_NONE, event_data, digests);
  3437. if (rval != TSS2_RC_SUCCESS) {
  3438. LOG_PERR(Esys_PCR_Event, rval);
  3439. return tool_rc_from_tpm(rval);
  3440. }
  3441. return tool_rc_success;
  3442. }
  3443. tool_rc tpm2_getrandom(ESYS_CONTEXT *ectx, UINT16 count,
  3444. TPM2B_DIGEST **random, TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
  3445. ESYS_TR session_handle_1, ESYS_TR session_handle_2,
  3446. ESYS_TR session_handle_3, TPMI_ALG_HASH parameter_hash_algorithm) {
  3447. TSS2_SYS_CONTEXT *sys_context = NULL;
  3448. tool_rc rc = tool_rc_success;
  3449. if (cp_hash->size || rp_hash->size) {
  3450. rc = tpm2_getsapicontext(ectx, &sys_context);
  3451. if (rc != tool_rc_success) {
  3452. LOG_ERR("Failed to acquire SAPI context.");
  3453. return rc;
  3454. }
  3455. }
  3456. if (cp_hash->size) {
  3457. TSS2_RC rval = Tss2_Sys_GetRandom_Prepare(sys_context, count);
  3458. if (rval != TPM2_RC_SUCCESS) {
  3459. LOG_PERR(Tss2_Sys_GetRandom_Prepare, rval);
  3460. return tool_rc_general_error;
  3461. }
  3462. rc = tpm2_sapi_getcphash(sys_context, NULL, NULL, NULL,
  3463. parameter_hash_algorithm, cp_hash);
  3464. if (rc != tool_rc_success) {
  3465. return rc;
  3466. }
  3467. /*
  3468. * Exit here without making the ESYS call since if we only need cpHash
  3469. */
  3470. if (!rp_hash->size || rc != tool_rc_success) {
  3471. goto tpm2_getrandom_skip_esapi_call;
  3472. }
  3473. }
  3474. TSS2_RC rval = Esys_GetRandom(ectx, session_handle_1, session_handle_2,
  3475. session_handle_3, count, random);
  3476. if (rval != TPM2_RC_SUCCESS) {
  3477. LOG_PERR(Esys_GetRandom, rval);
  3478. return tool_rc_from_tpm(rval);
  3479. }
  3480. if (rp_hash->size) {
  3481. rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
  3482. parameter_hash_algorithm);
  3483. }
  3484. tpm2_getrandom_skip_esapi_call:
  3485. return rc;
  3486. }
  3487. tool_rc tpm2_startup(ESYS_CONTEXT *ectx, TPM2_SU startup_type) {
  3488. TSS2_RC rval = Esys_Startup(ectx, startup_type);
  3489. if (rval != TPM2_RC_SUCCESS && rval != TPM2_RC_INITIALIZE) {
  3490. LOG_PERR(Esys_Startup, rval);
  3491. return tool_rc_from_tpm(rval);
  3492. }
  3493. return tool_rc_success;
  3494. }
  3495. tool_rc tpm2_pcr_reset(ESYS_CONTEXT *ectx, ESYS_TR pcr_handle) {
  3496. TSS2_RC rval = Esys_PCR_Reset(ectx, pcr_handle, ESYS_TR_PASSWORD,
  3497. ESYS_TR_NONE, ESYS_TR_NONE);
  3498. if (rval != TSS2_RC_SUCCESS) {
  3499. LOG_PERR(Esys_PCR_Reset, rval);
  3500. return tool_rc_from_tpm(rval);
  3501. }
  3502. return tool_rc_success;
  3503. }
  3504. tool_rc tpm2_makecredential(ESYS_CONTEXT *ectx, ESYS_TR handle,
  3505. const TPM2B_DIGEST *credential, const TPM2B_NAME *object_name,
  3506. TPM2B_ID_OBJECT **credential_blob, TPM2B_ENCRYPTED_SECRET **secret) {
  3507. TSS2_RC rval = Esys_MakeCredential(ectx, handle, ESYS_TR_NONE, ESYS_TR_NONE,
  3508. ESYS_TR_NONE, credential, object_name, credential_blob,
  3509. secret);
  3510. if (rval != TPM2_RC_SUCCESS) {
  3511. LOG_PERR(Esys_MakeCredential, rval);
  3512. return tool_rc_from_tpm(rval);
  3513. }
  3514. return tool_rc_success;
  3515. }
  3516. tool_rc tpm2_verifysignature(ESYS_CONTEXT *ectx, ESYS_TR key_handle,
  3517. const TPM2B_DIGEST *digest, const TPMT_SIGNATURE *signature,
  3518. TPMT_TK_VERIFIED **validation) {
  3519. TSS2_RC rval = Esys_VerifySignature(ectx,
  3520. key_handle, ESYS_TR_NONE, ESYS_TR_NONE,
  3521. ESYS_TR_NONE, digest, signature, validation);
  3522. if (rval != TPM2_RC_SUCCESS) {
  3523. LOG_PERR(Esys_VerifySignature, rval);
  3524. return tool_rc_from_tpm(rval);
  3525. }
  3526. return tool_rc_success;
  3527. }
  3528. tool_rc tpm2_readclock(ESYS_CONTEXT *ectx, TPMS_TIME_INFO **current_time) {
  3529. TSS2_RC rval = Esys_ReadClock(ectx,
  3530. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
  3531. current_time);
  3532. if (rval != TPM2_RC_SUCCESS) {
  3533. LOG_PERR(Esys_ReadClock, rval);
  3534. return tool_rc_from_tpm(rval);
  3535. }
  3536. return tool_rc_success;
  3537. }
  3538. tool_rc tpm2_setclock(ESYS_CONTEXT *ectx, tpm2_loaded_object *object,
  3539. UINT64 new_time, TPM2B_DIGEST *cp_hash) {
  3540. ESYS_TR shandle1 = ESYS_TR_NONE;
  3541. tool_rc rc = tpm2_auth_util_get_shandle(ectx,
  3542. object->tr_handle, object->session, &shandle1);
  3543. if (rc != tool_rc_success) {
  3544. LOG_ERR("Couldn't get shandle for lockout hierarchy");
  3545. return rc;
  3546. }
  3547. if (cp_hash) {
  3548. /*
  3549. * Need sys_context to be able to calculate CpHash
  3550. */
  3551. TSS2_SYS_CONTEXT *sys_context = NULL;
  3552. rc = tpm2_getsapicontext(ectx, &sys_context);
  3553. if(rc != tool_rc_success) {
  3554. LOG_ERR("Failed to acquire SAPI context.");
  3555. return rc;
  3556. }
  3557. TSS2_RC rval = Tss2_Sys_ClockSet_Prepare(sys_context,
  3558. object->handle, new_time);
  3559. if (rval != TPM2_RC_SUCCESS) {
  3560. LOG_PERR(Tss2_Sys_ClockSet_Prepare, rval);
  3561. return tool_rc_general_error;
  3562. }
  3563. TPM2B_NAME *name1 = NULL;
  3564. rc = tpm2_tr_get_name(ectx, object->tr_handle,
  3565. &name1);
  3566. if (rc != tool_rc_success) {
  3567. goto tpm2_setclock_free_name1;
  3568. }
  3569. cp_hash->size = tpm2_alg_util_get_hash_size(
  3570. tpm2_session_get_authhash(object->session));
  3571. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  3572. tpm2_session_get_authhash(object->session), cp_hash);
  3573. /*
  3574. * Exit here without making the ESYS call since we just need the cpHash
  3575. */
  3576. tpm2_setclock_free_name1:
  3577. Esys_Free(name1);
  3578. goto tpm2_setclock_skip_esapi_call;
  3579. }
  3580. TSS2_RC rval = Esys_ClockSet(ectx,
  3581. object->tr_handle,
  3582. shandle1, ESYS_TR_NONE, ESYS_TR_NONE,
  3583. new_time);
  3584. if (rval != TPM2_RC_SUCCESS) {
  3585. LOG_PERR(Esys_ClockSet, rval);
  3586. return tool_rc_from_tpm(rval);
  3587. }
  3588. tpm2_setclock_skip_esapi_call:
  3589. return rc;
  3590. }
  3591. tool_rc tpm2_clockrateadjust(ESYS_CONTEXT *ectx, tpm2_loaded_object *object,
  3592. TPM2_CLOCK_ADJUST rate_adjust, TPM2B_DIGEST *cp_hash) {
  3593. ESYS_TR shandle1 = ESYS_TR_NONE;
  3594. tool_rc rc = tpm2_auth_util_get_shandle(ectx,
  3595. object->tr_handle, object->session, &shandle1);
  3596. if (rc != tool_rc_success) {
  3597. LOG_ERR("Couldn't get shandle for lockout hierarchy");
  3598. return rc;
  3599. }
  3600. if (cp_hash) {
  3601. /*
  3602. * Need sys_context to be able to calculate CpHash
  3603. */
  3604. TSS2_SYS_CONTEXT *sys_context = NULL;
  3605. rc = tpm2_getsapicontext(ectx, &sys_context);
  3606. if(rc != tool_rc_success) {
  3607. LOG_ERR("Failed to acquire SAPI context.");
  3608. return rc;
  3609. }
  3610. TSS2_RC rval = Tss2_Sys_ClockRateAdjust_Prepare(sys_context,
  3611. object->handle, rate_adjust);
  3612. if (rval != TPM2_RC_SUCCESS) {
  3613. LOG_PERR(Tss2_Sys_ClockRateAdjust_Prepare, rval);
  3614. return tool_rc_general_error;
  3615. }
  3616. TPM2B_NAME *name1 = NULL;
  3617. rc = tpm2_tr_get_name(ectx, object->tr_handle,
  3618. &name1);
  3619. if (rc != tool_rc_success) {
  3620. goto tpm2_clockrateadjust_free_name1;
  3621. }
  3622. cp_hash->size = tpm2_alg_util_get_hash_size(
  3623. tpm2_session_get_authhash(object->session));
  3624. rc = tpm2_sapi_getcphash(sys_context, name1, NULL, NULL,
  3625. tpm2_session_get_authhash(object->session), cp_hash);
  3626. /*
  3627. * Exit here without making the ESYS call since we just need the cpHash
  3628. */
  3629. tpm2_clockrateadjust_free_name1:
  3630. Esys_Free(name1);
  3631. goto tpm2_clockrateadjust_skip_esapi_call;
  3632. }
  3633. TSS2_RC rval = Esys_ClockRateAdjust(ectx,
  3634. object->tr_handle,
  3635. shandle1, ESYS_TR_NONE, ESYS_TR_NONE,
  3636. rate_adjust);
  3637. if (rval != TPM2_RC_SUCCESS) {
  3638. LOG_PERR(Esys_ClockRateAdjust, rval);
  3639. return tool_rc_from_tpm(rval);
  3640. }
  3641. tpm2_clockrateadjust_skip_esapi_call:
  3642. return rc;
  3643. }
  3644. tool_rc tpm2_shutdown(ESYS_CONTEXT *ectx, TPM2_SU shutdown_type) {
  3645. TSS2_RC rval = Esys_Shutdown(ectx,
  3646. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
  3647. shutdown_type);
  3648. if (rval != TPM2_RC_SUCCESS) {
  3649. LOG_PERR(Esys_Shutdown, rval);
  3650. return tool_rc_from_tpm(rval);
  3651. }
  3652. return tool_rc_success;
  3653. }
  3654. tool_rc tpm2_gettime(ESYS_CONTEXT *ectx,
  3655. tpm2_loaded_object *privacy_admin,
  3656. tpm2_loaded_object *signing_object,
  3657. const TPM2B_DATA *qualifying_data,
  3658. const TPMT_SIG_SCHEME *scheme,
  3659. TPM2B_ATTEST **time_info,
  3660. TPMT_SIGNATURE **signature,
  3661. TPM2B_DIGEST *cp_hash) {
  3662. ESYS_TR privacy_admin_session_handle = ESYS_TR_NONE;
  3663. tool_rc rc = tpm2_auth_util_get_shandle(ectx,
  3664. privacy_admin->tr_handle, privacy_admin->session, &privacy_admin_session_handle);
  3665. if (rc != tool_rc_success) {
  3666. LOG_ERR("Couldn't get shandle for privacy admin");
  3667. return rc;
  3668. }
  3669. ESYS_TR sign_session_handle = ESYS_TR_NONE;
  3670. rc = tpm2_auth_util_get_shandle(ectx,
  3671. signing_object->tr_handle, signing_object->session, &sign_session_handle);
  3672. if (rc != tool_rc_success) {
  3673. LOG_ERR("Couldn't get shandle for signing key");
  3674. return rc;
  3675. }
  3676. if (cp_hash) {
  3677. /*
  3678. * Need sys_context to be able to calculate CpHash
  3679. */
  3680. TSS2_SYS_CONTEXT *sys_context = NULL;
  3681. rc = tpm2_getsapicontext(ectx, &sys_context);
  3682. if(rc != tool_rc_success) {
  3683. LOG_ERR("Failed to acquire SAPI context.");
  3684. return rc;
  3685. }
  3686. TSS2_RC rval = Tss2_Sys_GetTime_Prepare(sys_context,
  3687. privacy_admin->handle, signing_object->handle, qualifying_data, scheme);
  3688. if (rval != TPM2_RC_SUCCESS) {
  3689. LOG_PERR(Tss2_Sys_GetTime_Prepare, rval);
  3690. return tool_rc_general_error;
  3691. }
  3692. TPM2B_NAME *name1 = NULL;
  3693. rc = tpm2_tr_get_name(ectx, privacy_admin->tr_handle, &name1);
  3694. if (rc != tool_rc_success) {
  3695. goto tpm2_gettime_free_name1;
  3696. }
  3697. TPM2B_NAME *name2 = NULL;
  3698. rc = tpm2_tr_get_name(ectx, signing_object->tr_handle, &name2);
  3699. if (rc != tool_rc_success) {
  3700. goto tpm2_gettime_free_name1_name2;
  3701. }
  3702. cp_hash->size = tpm2_alg_util_get_hash_size(
  3703. tpm2_session_get_authhash(signing_object->session));
  3704. rc = tpm2_sapi_getcphash(sys_context, name1, name2, NULL,
  3705. tpm2_session_get_authhash(signing_object->session), cp_hash);
  3706. /*
  3707. * Exit here without making the ESYS call since we just need the cpHash
  3708. */
  3709. tpm2_gettime_free_name1_name2:
  3710. Esys_Free(name2);
  3711. tpm2_gettime_free_name1:
  3712. Esys_Free(name1);
  3713. goto tpm2_gettime_skip_esapi_call;
  3714. }
  3715. TSS2_RC rval = Esys_GetTime(
  3716. ectx,
  3717. privacy_admin->tr_handle,
  3718. signing_object->tr_handle,
  3719. privacy_admin_session_handle,
  3720. sign_session_handle,
  3721. ESYS_TR_NONE,
  3722. qualifying_data,
  3723. scheme,
  3724. time_info,
  3725. signature);
  3726. if (rval != TPM2_RC_SUCCESS) {
  3727. LOG_PERR(Esys_GetTime, rval);
  3728. return tool_rc_from_tpm(rval);
  3729. }
  3730. tpm2_gettime_skip_esapi_call:
  3731. return rc;
  3732. }
  3733. tool_rc tpm2_geteccparameters(ESYS_CONTEXT *esys_context,
  3734. TPMI_ECC_CURVE curve_id, TPMS_ALGORITHM_DETAIL_ECC **parameters) {
  3735. TSS2_RC rval = Esys_ECC_Parameters(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
  3736. ESYS_TR_NONE, curve_id, parameters);
  3737. if (rval != TSS2_RC_SUCCESS) {
  3738. LOG_PERR(Esys_ECC_Parameters, rval);
  3739. return tool_rc_from_tpm(rval);
  3740. }
  3741. return tool_rc_success;
  3742. }
  3743. tool_rc tpm2_ecephemeral(ESYS_CONTEXT *esys_context, TPMI_ECC_CURVE curve_id,
  3744. TPM2B_ECC_POINT **Q, uint16_t *counter) {
  3745. TSS2_RC rval = Esys_EC_Ephemeral(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
  3746. ESYS_TR_NONE, curve_id, Q, counter);
  3747. if (rval != TSS2_RC_SUCCESS) {
  3748. LOG_PERR(Esys_EC_Ephemeral, rval);
  3749. return tool_rc_from_tpm(rval);
  3750. }
  3751. return tool_rc_success;
  3752. }
  3753. tool_rc tpm2_commit(ESYS_CONTEXT *esys_context,
  3754. tpm2_loaded_object *signing_key_object, TPM2B_ECC_POINT *P1,
  3755. TPM2B_SENSITIVE_DATA *s2, TPM2B_ECC_PARAMETER *y2, TPM2B_ECC_POINT **K,
  3756. TPM2B_ECC_POINT **L, TPM2B_ECC_POINT **E, uint16_t *counter) {
  3757. ESYS_TR signing_key_obj_session_handle = ESYS_TR_NONE;
  3758. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  3759. signing_key_object->tr_handle, signing_key_object->session,
  3760. &signing_key_obj_session_handle);
  3761. if (rc != tool_rc_success) {
  3762. LOG_ERR("Failed to get shandle");
  3763. return rc;
  3764. }
  3765. TSS2_RC rval = Esys_Commit(esys_context, signing_key_object->tr_handle,
  3766. signing_key_obj_session_handle, ESYS_TR_NONE, ESYS_TR_NONE, P1, s2, y2,
  3767. K, L, E, counter);
  3768. if (rval != TSS2_RC_SUCCESS) {
  3769. LOG_PERR(Esys_Commit, rval);
  3770. return tool_rc_from_tpm(rval);
  3771. }
  3772. return tool_rc_success;
  3773. }
  3774. tool_rc tpm2_ecdhkeygen(ESYS_CONTEXT *esys_context,
  3775. tpm2_loaded_object *ecc_public_key, TPM2B_ECC_POINT **Z,
  3776. TPM2B_ECC_POINT **Q) {
  3777. TSS2_RC rval = Esys_ECDH_KeyGen(esys_context, ecc_public_key->tr_handle,
  3778. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, Z, Q);
  3779. if (rval != TSS2_RC_SUCCESS) {
  3780. LOG_PERR(Esys_ECDH_KeyGen, rval);
  3781. return tool_rc_from_tpm(rval);
  3782. }
  3783. return tool_rc_success;
  3784. }
  3785. tool_rc tpm2_ecdhzgen(ESYS_CONTEXT *esys_context,
  3786. tpm2_loaded_object *ecc_key_object, TPM2B_ECC_POINT **Z,
  3787. TPM2B_ECC_POINT *Q) {
  3788. ESYS_TR ecc_key_obj_session_handle = ESYS_TR_NONE;
  3789. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  3790. ecc_key_object->tr_handle, ecc_key_object->session,
  3791. &ecc_key_obj_session_handle);
  3792. if (rc != tool_rc_success) {
  3793. LOG_ERR("Failed to get shandle");
  3794. return rc;
  3795. }
  3796. TSS2_RC rval = Esys_ECDH_ZGen(esys_context, ecc_key_object->tr_handle,
  3797. ecc_key_obj_session_handle, ESYS_TR_NONE, ESYS_TR_NONE, Q, Z);
  3798. if (rval != TSS2_RC_SUCCESS) {
  3799. LOG_PERR(Esys_ECDH_ZGen, rval);
  3800. return tool_rc_from_tpm(rval);
  3801. }
  3802. return tool_rc_success;
  3803. }
  3804. tool_rc tpm2_zgen2phase(ESYS_CONTEXT *esys_context,
  3805. tpm2_loaded_object *ecc_key_object, TPM2B_ECC_POINT *Q1,
  3806. TPM2B_ECC_POINT *Q2, TPM2B_ECC_POINT **Z1, TPM2B_ECC_POINT **Z2,
  3807. TPMI_ECC_KEY_EXCHANGE keyexchange_scheme, UINT16 commit_counter) {
  3808. ESYS_TR ecc_key_obj_session_handle = ESYS_TR_NONE;
  3809. tool_rc rc = tpm2_auth_util_get_shandle(esys_context,
  3810. ecc_key_object->tr_handle, ecc_key_object->session,
  3811. &ecc_key_obj_session_handle);
  3812. if (rc != tool_rc_success) {
  3813. LOG_ERR("Failed to get shandle");
  3814. return rc;
  3815. }
  3816. TSS2_RC rval = Esys_ZGen_2Phase(esys_context, ecc_key_object->tr_handle,
  3817. ecc_key_obj_session_handle, ESYS_TR_NONE, ESYS_TR_NONE, Q1, Q2,
  3818. keyexchange_scheme, commit_counter, Z1, Z2);
  3819. if (rval != TSS2_RC_SUCCESS) {
  3820. LOG_PERR(Esys_ZGen_2Phase, rval);
  3821. return tool_rc_from_tpm(rval);
  3822. }
  3823. return tool_rc_success;
  3824. }
  3825. tool_rc tpm2_getsapicontext(ESYS_CONTEXT *esys_context,
  3826. TSS2_SYS_CONTEXT **sys_context) {
  3827. TSS2_RC rval = Esys_GetSysContext(esys_context, sys_context);
  3828. if (rval != TPM2_RC_SUCCESS) {
  3829. LOG_PERR(Esys_GetSysContext, rval);
  3830. return tool_rc_from_tpm(rval);
  3831. }
  3832. return tool_rc_success;
  3833. }
  3834. tool_rc tpm2_sapi_getrphash(TSS2_SYS_CONTEXT *sys_context,
  3835. TSS2_RC response_code, TPM2B_DIGEST *rp_hash, TPMI_ALG_HASH halg) {
  3836. uint8_t command_code[4];
  3837. TSS2_RC rval = Tss2_Sys_GetCommandCode(sys_context, &command_code[0]);
  3838. if (rval != TPM2_RC_SUCCESS) {
  3839. LOG_PERR(Tss2_Sys_GetCommandCode, rval);
  3840. return tool_rc_general_error;
  3841. }
  3842. const uint8_t *response_parameters;
  3843. size_t response_parameters_size;
  3844. rval = Tss2_Sys_GetRpBuffer(sys_context, &response_parameters_size,
  3845. &response_parameters);
  3846. if (rval != TPM2_RC_SUCCESS) {
  3847. LOG_PERR(Tss2_Sys_GetRpBuffer, rval);
  3848. return tool_rc_general_error;
  3849. }
  3850. uint16_t to_hash_len = sizeof(response_code) +
  3851. sizeof(command_code) +
  3852. response_parameters_size;
  3853. uint8_t *to_hash = malloc(to_hash_len);
  3854. if (!to_hash) {
  3855. LOG_ERR("oom");
  3856. return tool_rc_general_error;
  3857. }
  3858. //Response-Code
  3859. memcpy(to_hash, (uint8_t *)&response_code, sizeof(response_code));
  3860. uint16_t offset = sizeof(response_code);
  3861. //Command-Code
  3862. memcpy(to_hash + offset, command_code, sizeof(command_code));
  3863. offset += sizeof(command_code);
  3864. //RpBuffer
  3865. memcpy(to_hash + offset, response_parameters, response_parameters_size);
  3866. //rpHash
  3867. tool_rc rc = tool_rc_success;
  3868. bool result = tpm2_openssl_hash_compute_data(halg, to_hash, to_hash_len,
  3869. rp_hash);
  3870. free(to_hash);
  3871. if (!result) {
  3872. LOG_ERR("Failed rpHash digest calculation.");
  3873. rc = tool_rc_general_error;
  3874. }
  3875. return rc;
  3876. }
  3877. tool_rc tpm2_sapi_getcphash(TSS2_SYS_CONTEXT *sys_context,
  3878. const TPM2B_NAME *name1, const TPM2B_NAME *name2, const TPM2B_NAME *name3,
  3879. TPMI_ALG_HASH halg, TPM2B_DIGEST *cp_hash) {
  3880. uint8_t command_code[4];
  3881. TSS2_RC rval = Tss2_Sys_GetCommandCode(sys_context, &command_code[0]);
  3882. if (rval != TPM2_RC_SUCCESS) {
  3883. LOG_PERR(Tss2_Sys_GetCommandCode, rval);
  3884. return tool_rc_general_error;
  3885. }
  3886. const uint8_t *command_parameters;
  3887. size_t command_parameters_size;
  3888. rval = Tss2_Sys_GetCpBuffer(sys_context, &command_parameters_size,
  3889. &command_parameters);
  3890. if (rval != TPM2_RC_SUCCESS) {
  3891. LOG_PERR(Tss2_Sys_GetCpBuffer, rval);
  3892. return tool_rc_general_error;
  3893. }
  3894. uint16_t to_hash_len = sizeof(command_code) + command_parameters_size;
  3895. to_hash_len += name1 ? name1->size : 0;
  3896. to_hash_len += name2 ? name2->size : 0;
  3897. to_hash_len += name3 ? name3->size : 0;
  3898. uint8_t *to_hash = malloc(to_hash_len);
  3899. if (!to_hash) {
  3900. LOG_ERR("oom");
  3901. return tool_rc_general_error;
  3902. }
  3903. //Command-Code
  3904. memcpy(to_hash, command_code, sizeof(command_code));
  3905. uint16_t offset = sizeof(command_code);
  3906. //Names
  3907. if (name1) {
  3908. memcpy(to_hash + offset, name1->name, name1->size);
  3909. offset += name1->size;
  3910. }
  3911. if (name2) {
  3912. memcpy(to_hash + offset, name2->name, name2->size);
  3913. offset += name2->size;
  3914. }
  3915. if (name3) {
  3916. memcpy(to_hash + offset, name3->name, name3->size);
  3917. offset += name3->size;
  3918. }
  3919. //CpBuffer
  3920. memcpy(to_hash + offset, command_parameters, command_parameters_size);
  3921. //cpHash
  3922. tool_rc rc = tool_rc_success;
  3923. bool result = tpm2_openssl_hash_compute_data(halg, to_hash, to_hash_len,
  3924. cp_hash);
  3925. free(to_hash);
  3926. if (!result) {
  3927. LOG_ERR("Failed cpHash digest calculation.");
  3928. rc = tool_rc_general_error;
  3929. }
  3930. return rc;
  3931. }