123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281 |
- /*
- * The Clear BSD License
- * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
- * Copyright 2016-2017 NXP
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted (subject to the limitations in the disclaimer below) provided
- * that the following conditions are met:
- *
- * o Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- *
- * o Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or
- * other materials provided with the distribution.
- *
- * o Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "fsl_ltc.h"
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- /* Component ID definition, used by tools. */
- #ifndef FSL_COMPONENT_ID
- #define FSL_COMPONENT_ID "platform.drivers.ltc"
- #endif
- #define LTC_FIFO_SZ_MAX_DOWN_ALGN (0xff0u)
- #define LTC_AES_GCM_TYPE_AAD 55
- #define LTC_AES_GCM_TYPE_IV 0
- #define LTC_CCM_TAG_IDX 8 /*! For CCM encryption, the encrypted final MAC is written to the context word 8-11 */
- #define LTC_GCM_TAG_IDX 0 /*! For GCM encryption, the encrypted final MAC is written to the context word 0-3 */
- enum _ltc_md_dk_bit_shift
- {
- kLTC_ModeRegBitShiftDK = 12U,
- };
- /*! @brief LTC status flags */
- enum _ltc_status_flag
- {
- kLTC_StatusAesBusy = 1U << LTC_STA_AB_SHIFT,
- #if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES
- kLTC_StatusDesBusy = 1U << LTC_STA_DB_SHIFT,
- #endif /* FSL_FEATURE_LTC_HAS_DES */
- #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
- kLTC_StatusPkhaBusy = 1U << LTC_STA_PB_SHIFT,
- #endif /* FSL_FEATURE_LTC_HAS_PKHA */
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- kLTC_StatusMdhaBusy = 1U << LTC_STA_MB_SHIFT,
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- kLTC_StatusDoneIsr = 1U << LTC_STA_DI_SHIFT,
- kLTC_StatusErrorIsr = 1U << LTC_STA_EI_SHIFT,
- #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
- kLTC_StatusPublicKeyPrime = 1U << LTC_STA_PKP_SHIFT,
- kLTC_StatusPublicKeyOpOne = 1U << LTC_STA_PKO_SHIFT,
- kLTC_StatusPublicKeyOpZero = 1U << LTC_STA_PKZ_SHIFT,
- #endif /* FSL_FEATURE_LTC_HAS_PKHA */
- kLTC_StatusAll = LTC_STA_AB_MASK |
- #if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES
- LTC_STA_DB_MASK |
- #endif /* FSL_FEATURE_LTC_HAS_DES */
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- LTC_STA_MB_MASK |
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- LTC_STA_DI_MASK | LTC_STA_EI_MASK
- #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
- |
- LTC_STA_PB_MASK | LTC_STA_PKP_MASK | LTC_STA_PKO_MASK | LTC_STA_PKZ_MASK
- #endif /* FSL_FEATURE_LTC_HAS_PKHA */
- };
- /*! @brief LTC clear register */
- typedef enum _ltc_clear_written
- {
- kLTC_ClearMode = 1U << LTC_CW_CM_SHIFT,
- kLTC_ClearDataSize = 1U << LTC_CW_CDS_SHIFT,
- kLTC_ClearIcvSize = 1U << LTC_CW_CICV_SHIFT,
- kLTC_ClearContext = 1U << LTC_CW_CCR_SHIFT,
- kLTC_ClearKey = 1U << LTC_CW_CKR_SHIFT,
- #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
- kLTC_ClearPkhaSizeA = 1U << LTC_CW_CPKA_SHIFT,
- kLTC_ClearPkhaSizeB = 1U << LTC_CW_CPKB_SHIFT,
- kLTC_ClearPkhaSizeN = 1U << LTC_CW_CPKN_SHIFT,
- kLTC_ClearPkhaSizeE = 1U << LTC_CW_CPKE_SHIFT,
- kLTC_ClearAllSize = (int)kLTC_ClearPkhaSizeA | kLTC_ClearPkhaSizeB | kLTC_ClearPkhaSizeN | kLTC_ClearPkhaSizeE,
- #endif /* FSL_FEATURE_LTC_HAS_PKHA */
- kLTC_ClearOutputFifo = 1U << LTC_CW_COF_SHIFT,
- kLTC_ClearInputFifo = (int)(1U << LTC_CW_CIF_SHIFT),
- kLTC_ClearAll = (int)(LTC_CW_CM_MASK | LTC_CW_CDS_MASK | LTC_CW_CICV_MASK | LTC_CW_CCR_MASK | LTC_CW_CKR_MASK |
- #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
- LTC_CW_CPKA_MASK | LTC_CW_CPKB_MASK | LTC_CW_CPKN_MASK | LTC_CW_CPKE_MASK |
- #endif /* FSL_FEATURE_LTC_HAS_PKHA */
- LTC_CW_COF_MASK | LTC_CW_CIF_MASK)
- } ltc_clear_written_t;
- enum _ltc_ctrl_swap
- {
- kLTC_CtrlSwapAll =
- LTC_CTL_IFS_MASK | LTC_CTL_OFS_MASK | LTC_CTL_KIS_MASK | LTC_CTL_KOS_MASK | LTC_CTL_CIS_MASK | LTC_CTL_COS_MASK,
- };
- /*! @brief Type used in GCM and CCM modes.
- Content of a block is established via individual bytes and moved to LTC
- IFIFO by moving 32-bit words.
- */
- typedef union _ltc_xcm_block_t
- {
- uint32_t w[4]; /*!< LTC context register is 16 bytes written as four 32-bit words */
- uint8_t b[16]; /*!< 16 octets block for CCM B0 and CTR0 and for GCM */
- } ltc_xcm_block_t;
- #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
- /*! @brief PKHA functions - arithmetic, copy/clear memory. */
- typedef enum _ltc_pkha_func_t
- {
- kLTC_PKHA_ClearMem = 1U,
- kLTC_PKHA_ArithModAdd = 2U, /*!< (A + B) mod N */
- kLTC_PKHA_ArithModSub1 = 3U, /*!< (A - B) mod N */
- kLTC_PKHA_ArithModSub2 = 4U, /*!< (B - A) mod N */
- kLTC_PKHA_ArithModMul = 5U, /*!< (A x B) mod N */
- kLTC_PKHA_ArithModExp = 6U, /*!< (A^E) mod N */
- kLTC_PKHA_ArithModRed = 7U, /*!< (A) mod N */
- kLTC_PKHA_ArithModInv = 8U, /*!< (A^-1) mod N */
- kLTC_PKHA_ArithEccAdd = 9U, /*!< (P1 + P2) */
- kLTC_PKHA_ArithEccDouble = 10U, /*!< (P2 + P2) */
- kLTC_PKHA_ArithEccMul = 11U, /*!< (E x P1) */
- kLTC_PKHA_ArithModR2 = 12U, /*!< (R^2 mod N) */
- kLTC_PKHA_ArithGcd = 14U, /*!< GCD (A, N) */
- kLTC_PKHA_ArithPrimalityTest = 15U, /*!< Miller-Rabin */
- kLTC_PKHA_CopyMemSizeN = 16U,
- kLTC_PKHA_CopyMemSizeSrc = 17U,
- } ltc_pkha_func_t;
- /*! @brief Register areas for PKHA clear memory operations. */
- typedef enum _ltc_pkha_reg_area
- {
- kLTC_PKHA_RegA = 8U,
- kLTC_PKHA_RegB = 4U,
- kLTC_PKHA_RegE = 2U,
- kLTC_PKHA_RegN = 1U,
- kLTC_PKHA_RegAll = kLTC_PKHA_RegA | kLTC_PKHA_RegB | kLTC_PKHA_RegE | kLTC_PKHA_RegN,
- } ltc_pkha_reg_area_t;
- /*! @brief Quadrant areas for 2048-bit registers for PKHA copy memory
- * operations. */
- typedef enum _ltc_pkha_quad_area_t
- {
- kLTC_PKHA_Quad0 = 0U,
- kLTC_PKHA_Quad1 = 1U,
- kLTC_PKHA_Quad2 = 2U,
- kLTC_PKHA_Quad3 = 3U,
- } ltc_pkha_quad_area_t;
- /*! @brief User-supplied (R^2 mod N) input or LTC should calculate. */
- typedef enum _ltc_pkha_r2_t
- {
- kLTC_PKHA_CalcR2 = 0U, /*!< Calculate (R^2 mod N) */
- kLTC_PKHA_InputR2 = 1U /*!< (R^2 mod N) supplied as input */
- } ltc_pkha_r2_t;
- /*! @brief LTC PKHA parameters */
- typedef struct _ltc_pkha_mode_params_t
- {
- ltc_pkha_func_t func;
- ltc_pkha_f2m_t arithType;
- ltc_pkha_montgomery_form_t montFormIn;
- ltc_pkha_montgomery_form_t montFormOut;
- ltc_pkha_reg_area_t srcReg;
- ltc_pkha_quad_area_t srcQuad;
- ltc_pkha_reg_area_t dstReg;
- ltc_pkha_quad_area_t dstQuad;
- ltc_pkha_timing_t equalTime;
- ltc_pkha_r2_t r2modn;
- } ltc_pkha_mode_params_t;
- #endif /* FSL_FEATURE_LTC_HAS_PKHA */
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
- static status_t ltc_pkha_clear_regabne(LTC_Type *base, bool A, bool B, bool N, bool E);
- #endif /* FSL_FEATURE_LTC_HAS_PKHA */
- /*******************************************************************************
- * Code
- ******************************************************************************/
- /*******************************************************************************
- * LTC Common code static
- ******************************************************************************/
- /*!
- * @brief Tests the correct key size.
- *
- * This function tests the correct key size.
- * @param keySize Input key length in bytes.
- * @return True if the key length is supported, false if not.
- */
- bool ltc_check_key_size(const uint32_t keySize)
- {
- return ((keySize == 16u)
- #if defined(FSL_FEATURE_LTC_HAS_AES192) && FSL_FEATURE_LTC_HAS_AES192
- || ((keySize == 24u))
- #endif /* FSL_FEATURE_LTC_HAS_AES192 */
- #if defined(FSL_FEATURE_LTC_HAS_AES256) && FSL_FEATURE_LTC_HAS_AES256
- || ((keySize == 32u))
- #endif /* FSL_FEATURE_LTC_HAS_AES256 */
- );
- }
- /*! @brief LTC driver wait mechanism. */
- status_t ltc_wait(LTC_Type *base)
- {
- status_t status;
- bool error = false;
- bool done = false;
- /* Wait for 'done' or 'error' flag. */
- while ((!error) && (!done))
- {
- uint32_t temp32 = base->STA;
- error = temp32 & LTC_STA_EI_MASK;
- done = temp32 & LTC_STA_DI_MASK;
- }
- if (error)
- {
- base->COM = LTC_COM_ALL_MASK; /* Reset all engine to clear the error flag */
- status = kStatus_Fail;
- }
- else /* 'done' */
- {
- status = kStatus_Success;
- base->CW = kLTC_ClearDataSize;
- /* Clear 'done' interrupt status. This also clears the mode register. */
- base->STA = kLTC_StatusDoneIsr;
- }
- return status;
- }
- /*!
- * @brief Clears the LTC module.
- * This function can be used to clear all sensitive data from theLTC module, such as private keys. It is called
- * internally by the LTC driver in case of an error or operation complete.
- * @param base LTC peripheral base address
- * @param pkha Include LTC PKHA register clear. If there is no PKHA, the argument is ignored.
- */
- void ltc_clear_all(LTC_Type *base, bool addPKHA)
- {
- base->CW = (uint32_t)kLTC_ClearAll;
- #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
- if (addPKHA)
- {
- ltc_pkha_clear_regabne(base, true, true, true, true);
- }
- #endif /* FSL_FEATURE_LTC_HAS_PKHA */
- }
- void ltc_memcpy(void *dst, const void *src, size_t size)
- {
- #if defined(__cplusplus)
- register uint8_t *to = (uint8_t *)dst;
- register const uint8_t *from = (const uint8_t *)src;
- #else
- register uint8_t *to = dst;
- register const uint8_t *from = src;
- #endif
- while (size)
- {
- *to = *from;
- size--;
- to++;
- from++;
- }
- }
- /*!
- * @brief Reads an unaligned word.
- *
- * This function creates a 32-bit word from an input array of four bytes.
- *
- * @param src Input array of four bytes. The array can start at any address in memory.
- * @return 32-bit unsigned int created from the input byte array.
- */
- /* Force lower optimization for Keil, otherwise it replaces inline LDR with LDM */
- #if defined(__CC_ARM)
- #pragma push
- #pragma O0
- #endif
- static inline uint32_t ltc_get_word_from_unaligned(const uint8_t *srcAddr)
- {
- #if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0)))
- register const uint8_t *src = srcAddr;
- /* Cortex M0 does not support misaligned loads */
- if ((uint32_t)src & 0x3u)
- {
- union _align_bytes_t
- {
- uint32_t word;
- uint8_t byte[sizeof(uint32_t)];
- } my_bytes;
- my_bytes.byte[0] = *src;
- my_bytes.byte[1] = *(src + 1);
- my_bytes.byte[2] = *(src + 2);
- my_bytes.byte[3] = *(src + 3);
- return my_bytes.word;
- }
- else
- {
- /* addr aligned to 0-modulo-4 so it is safe to type cast */
- return *((const uint32_t *)src);
- }
- #elif defined(__CC_ARM)
- /* -O3 optimization in Keil 5.15 and 5.16a uses LDM instruction here (LDM r4!, {r0})
- * which is wrong, because srcAddr might be unaligned.
- * LDM on unaligned address causes hard-fault. in contrary,
- * LDR supports unaligned address on Cortex M4 */
- register uint32_t retVal;
- __asm
- {
- LDR retVal, [srcAddr]
- }
- return retVal;
- #else
- return *((const uint32_t *)srcAddr);
- #endif
- }
- /* End lower optimization */
- #if defined(__CC_ARM)
- #pragma pop
- #endif
- /*!
- * @brief Converts a 32-bit word into a byte array.
- *
- * This function creates an output array of four bytes from an input 32-bit word.
- *
- * @param srcWord Input 32-bit unsigned integer.
- * @param dst Output array of four bytes. The array can start at any address in memory.
- */
- static inline void ltc_set_unaligned_from_word(uint32_t srcWord, uint8_t *dstAddr)
- {
- #if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0)))
- register uint8_t *dst = dstAddr;
- /* Cortex M0 does not support misaligned stores */
- if ((uint32_t)dst & 0x3u)
- {
- *dst++ = (srcWord & 0x000000FFU);
- *dst++ = (srcWord & 0x0000FF00U) >> 8;
- *dst++ = (srcWord & 0x00FF0000U) >> 16;
- *dst++ = (srcWord & 0xFF000000U) >> 24;
- }
- else
- {
- *((uint32_t *)dstAddr) = srcWord; /* addr aligned to 0-modulo-4 so it is safe to type cast */
- }
- #elif defined(__CC_ARM)
- __asm
- {
- STR srcWord, [dstAddr]
- }
- return;
- #else
- *((uint32_t *)dstAddr) = srcWord;
- #endif
- }
- /*!
- * @brief Sets the LTC keys.
- *
- * This function writes the LTC keys into the key register. The keys should
- * be written before the key size.
- *
- * @param base LTC peripheral base address
- * @param key Key
- * @param keySize Number of bytes for all keys to be loaded (maximum 32, must be a
- * multiple of 4).
- * @returns Key set status
- */
- static status_t ltc_set_key(LTC_Type *base, const uint8_t *key, uint8_t keySize)
- {
- int32_t i;
- for (i = 0; i < (keySize / 4); i++)
- {
- base->KEY[i] = ltc_get_word_from_unaligned(key + i * sizeof(uint32_t));
- }
- return kStatus_Success;
- }
- /*!
- * @brief Gets the LTC keys.
- *
- * This function retrieves the LTC keys from the key register.
- *
- * @param base LTC peripheral base address
- * @param key Array of data to store keys
- * @param keySize Number of bytes of keys to retrieve
- * @returns Key set status
- */
- static status_t ltc_get_key(LTC_Type *base, uint8_t *key, uint8_t keySize)
- {
- int32_t i;
- for (i = 0; i < (keySize / 4); i++)
- {
- ltc_set_unaligned_from_word(base->KEY[i], key + i * sizeof(uint32_t));
- }
- return kStatus_Success;
- }
- /*!
- * @brief Writes the LTC context register;
- *
- * The LTC context register is a 512 bit (64 byte) register that holds
- * internal context for the crypto engine. The meaning varies based on the
- * algorithm and operating state being used. This register is written by the
- * driver/application to load state such as IV, counter, and so on. Then, it is
- * updated by the internal crypto engine as needed.
- *
- * @param base LTC peripheral base address
- * @param data Data to write
- * @param dataSize Size of data to write in bytes
- * @param startIndex Starting word (4-byte) index into the 16-word register.
- * @return Status of write
- */
- status_t ltc_set_context(LTC_Type *base, const uint8_t *data, uint8_t dataSize, uint8_t startIndex)
- {
- int32_t i;
- int32_t j;
- int32_t szLeft;
- /* Context register is 16 words in size (64 bytes). Ensure we are only
- * writing a valid amount of data. */
- if (startIndex + (dataSize / 4) >= 16)
- {
- return kStatus_InvalidArgument;
- }
- j = 0;
- szLeft = dataSize % 4;
- for (i = startIndex; i < (startIndex + dataSize / 4); i++)
- {
- base->CTX[i] = ltc_get_word_from_unaligned(data + j);
- j += sizeof(uint32_t);
- }
- if (szLeft)
- {
- uint32_t context_data = {0};
- ltc_memcpy(&context_data, data + j, szLeft);
- base->CTX[i] = context_data;
- }
- return kStatus_Success;
- }
- /*!
- * @brief Reads the LTC context register.
- *
- * The LTC context register is a 512 bit (64 byte) register that holds
- * internal context for the crypto engine. The meaning varies based on the
- * algorithm and operating state being used. This register is written by the
- * driver/application to load state such as IV, counter, and so on. Then, it is
- * updated by the internal crypto engine as needed.
- *
- * @param base LTC peripheral base address
- * @param data Destination of read data
- * @param dataSize Size of data to read in bytes
- * @param startIndex Starting word (4-byte) index into the 16-word register.
- * @return Status of read
- */
- status_t ltc_get_context(LTC_Type *base, uint8_t *dest, uint8_t dataSize, uint8_t startIndex)
- {
- int32_t i;
- int32_t j;
- int32_t szLeft;
- uint32_t rdCtx;
- /* Context register is 16 words in size (64 bytes). Ensure we are only
- * writing a valid amount of data. */
- if (startIndex + (dataSize / 4) >= 16)
- {
- return kStatus_InvalidArgument;
- }
- j = 0;
- szLeft = dataSize % 4;
- for (i = startIndex; i < (startIndex + dataSize / 4); i++)
- {
- ltc_set_unaligned_from_word(base->CTX[i], dest + j);
- j += sizeof(uint32_t);
- }
- if (szLeft)
- {
- rdCtx = 0;
- rdCtx = base->CTX[i];
- ltc_memcpy(dest + j, &rdCtx, szLeft);
- }
- return kStatus_Success;
- }
- static status_t ltc_symmetric_alg_state(LTC_Type *base,
- const uint8_t *key,
- uint8_t keySize,
- ltc_algorithm_t alg,
- ltc_mode_symmetric_alg_t mode,
- ltc_mode_encrypt_t enc,
- ltc_mode_algorithm_state_t as)
- {
- ltc_mode_t modeReg;
- /* Clear internal register states. */
- base->CW = (uint32_t)kLTC_ClearAll;
- /* Set byte swap on for several registers we will be reading and writing
- * user data to/from. */
- base->CTL |= kLTC_CtrlSwapAll;
- /* Write the key in place. */
- ltc_set_key(base, key, keySize);
- /* Write the key size. This must be done after writing the key, and this
- * action locks the ability to modify the key registers. */
- base->KS = keySize;
- /* Clear the 'done' interrupt. */
- base->STA = kLTC_StatusDoneIsr;
- /* Set the proper block and algorithm mode. */
- modeReg = (uint32_t)alg | (uint32_t)enc | (uint32_t)as | (uint32_t)mode;
- /* Write the mode register to the hardware. */
- base->MD = modeReg;
- return kStatus_Success;
- }
- /*!
- * @brief Initializes the LTC for symmetric encrypt/decrypt operation. Mode is set to UPDATE.
- *
- * @param base LTC peripheral base address
- * @param key Input key to use for encryption
- * @param keySize Size of the input key, in bytes. Must be 8, 16, 24, or 32.
- * @param alg Symmetric algorithm
- * @param mode Symmetric block mode
- * @param enc Encrypt/decrypt control
- * @return Status
- */
- status_t ltc_symmetric_update(LTC_Type *base,
- const uint8_t *key,
- uint8_t keySize,
- ltc_algorithm_t alg,
- ltc_mode_symmetric_alg_t mode,
- ltc_mode_encrypt_t enc)
- {
- return ltc_symmetric_alg_state(base, key, keySize, alg, mode, enc, kLTC_ModeUpdate);
- }
- #if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM
- /*!
- * @brief Initializes the LTC for symmetric encrypt/decrypt operation. Mode is set to FINALIZE.
- *
- * @param base LTC peripheral base address
- * @param key Input key to use for encryption
- * @param keySize Size of the input key, in bytes. Must be 8, 16, 24, or 32.
- * @param alg Symmetric algorithm
- * @param mode Symmetric block mode
- * @param enc Encrypt/decrypt control
- * @return Status
- */
- static status_t ltc_symmetric_final(LTC_Type *base,
- const uint8_t *key,
- uint8_t keySize,
- ltc_algorithm_t alg,
- ltc_mode_symmetric_alg_t mode,
- ltc_mode_encrypt_t enc)
- {
- return ltc_symmetric_alg_state(base, key, keySize, alg, mode, enc, kLTC_ModeFinalize);
- }
- #endif /* FSL_FEATURE_LTC_HAS_GCM */
- /*!
- * @brief Initializes the LTC for symmetric encrypt/decrypt operation. Mode is set to INITIALIZE.
- *
- * @param base LTC peripheral base address
- * @param key Input key to use for encryption
- * @param keySize Size of the input key, in bytes. Must be 8, 16, 24, or 32.
- * @param alg Symmetric algorithm
- * @param mode Symmetric block mode
- * @param enc Encrypt/decrypt control
- * @return Status
- */
- static status_t ltc_symmetric_init(LTC_Type *base,
- const uint8_t *key,
- uint8_t keySize,
- ltc_algorithm_t alg,
- ltc_mode_symmetric_alg_t mode,
- ltc_mode_encrypt_t enc)
- {
- return ltc_symmetric_alg_state(base, key, keySize, alg, mode, enc, kLTC_ModeInit);
- }
- /*!
- * @brief Initializes the LTC for symmetric encrypt/decrypt operation. Mode is set to INITIALIZE/FINALIZE.
- *
- * @param base LTC peripheral base address
- * @param key Input key to use for encryption
- * @param keySize Size of the input key, in bytes. Must be 8, 16, 24, or 32.
- * @param alg Symmetric algorithm
- * @param mode Symmetric block mode
- * @param enc Encrypt/decrypt control
- * @return Status
- */
- static status_t ltc_symmetric_init_final(LTC_Type *base,
- const uint8_t *key,
- uint8_t keySize,
- ltc_algorithm_t alg,
- ltc_mode_symmetric_alg_t mode,
- ltc_mode_encrypt_t enc)
- {
- return ltc_symmetric_alg_state(base, key, keySize, alg, mode, enc, kLTC_ModeInitFinal);
- }
- void ltc_symmetric_process(LTC_Type *base, uint32_t inSize, const uint8_t **inData, uint8_t **outData)
- {
- uint32_t outSize;
- uint32_t fifoData;
- uint32_t fifoStatus;
- register const uint8_t *in = *inData;
- register uint8_t *out = *outData;
- outSize = inSize;
- while ((outSize > 0) || (inSize > 0))
- {
- fifoStatus = base->FIFOSTA;
- /* Check output FIFO level to make sure there is at least an entry
- * ready to be read. */
- if (fifoStatus & LTC_FIFOSTA_OFL_MASK)
- {
- /* Read data from the output FIFO. */
- if (outSize > 0)
- {
- if (outSize >= sizeof(uint32_t))
- {
- ltc_set_unaligned_from_word(base->OFIFO, out);
- out += sizeof(uint32_t);
- outSize -= sizeof(uint32_t);
- }
- else /* (outSize > 0) && (outSize < 4) */
- {
- fifoData = base->OFIFO;
- ltc_memcpy(out, &fifoData, outSize);
- out += outSize;
- outSize = 0;
- }
- }
- }
- /* Check input FIFO status to see if it is full. We can
- * only write more data when both input and output FIFOs are not at a full state.
- * At the same time we are sure Output FIFO is not full because we have poped at least one entry
- * by the while loop above.
- */
- if (!(fifoStatus & LTC_FIFOSTA_IFF_MASK))
- {
- /* Copy data to the input FIFO.
- * Data can only be copied one word at a time, so pad the data
- * appropriately if it is less than this size. */
- if (inSize > 0)
- {
- if (inSize >= sizeof(uint32_t))
- {
- base->IFIFO = ltc_get_word_from_unaligned(in);
- inSize -= sizeof(uint32_t);
- in += sizeof(uint32_t);
- }
- else /* (inSize > 0) && (inSize < 4) */
- {
- fifoData = 0;
- ltc_memcpy(&fifoData, in, inSize);
- base->IFIFO = fifoData;
- in += inSize;
- inSize = 0;
- }
- }
- }
- }
- *inData = in;
- *outData = out;
- }
- /*!
- * @brief Processes symmetric data through LTC AES and DES engines.
- *
- * @param base LTC peripheral base address
- * @param inData Input data
- * @param inSize Size of input data, in bytes
- * @param outData Output data
- * @return Status from encrypt/decrypt operation
- */
- status_t ltc_symmetric_process_data(LTC_Type *base, const uint8_t *inData, uint32_t inSize, uint8_t *outData)
- {
- uint32_t lastSize;
- if ((!inData) || (!outData))
- {
- return kStatus_InvalidArgument;
- }
- /* Write the data size. */
- base->DS = inSize;
- /* Split the inSize into full 16-byte chunks and last incomplete block due to LTC AES OFIFO errata */
- if (inSize <= 16u)
- {
- lastSize = inSize;
- inSize = 0;
- }
- else
- {
- /* Process all 16-byte data chunks. */
- lastSize = inSize % 16u;
- if (lastSize == 0)
- {
- lastSize = 16;
- inSize -= 16;
- }
- else
- {
- inSize -= lastSize; /* inSize will be rounded down to 16 byte boundary. remaining bytes in lastSize */
- }
- }
- ltc_symmetric_process(base, inSize, &inData, &outData);
- ltc_symmetric_process(base, lastSize, &inData, &outData);
- return ltc_wait(base);
- }
- /*!
- * @brief Splits the LTC job into sessions. Used for CBC, CTR, CFB, OFB cipher block modes.
- *
- * @param base LTC peripheral base address
- * @param inData Input data to process.
- * @param inSize Input size of the input buffer.
- * @param outData Output data buffer.
- */
- static status_t ltc_process_message_in_sessions(LTC_Type *base,
- const uint8_t *inData,
- uint32_t inSize,
- uint8_t *outData)
- {
- uint32_t sz;
- status_t retval;
- ltc_mode_t modeReg; /* read and write LTC mode register */
- sz = LTC_FIFO_SZ_MAX_DOWN_ALGN;
- modeReg = base->MD;
- retval = kStatus_Success;
- while (inSize)
- {
- if (inSize <= sz)
- {
- retval = ltc_symmetric_process_data(base, inData, inSize, outData);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- inSize = 0;
- }
- else
- {
- retval = ltc_symmetric_process_data(base, inData, sz, outData);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- inData += sz;
- inSize -= sz;
- outData += sz;
- base->MD = modeReg;
- }
- }
- return retval;
- }
- static void ltc_move_block_to_ififo(LTC_Type *base, const ltc_xcm_block_t *blk, uint32_t num_bytes)
- {
- uint32_t i = 0;
- uint32_t words;
- words = num_bytes / 4u;
- if (num_bytes % 4u)
- {
- words++;
- }
- if (words > 4)
- {
- words = 4;
- }
- while (i < words)
- {
- if (0U == (base->FIFOSTA & LTC_FIFOSTA_IFF_MASK))
- {
- /* Copy data to the input FIFO. */
- base->IFIFO = blk->w[i++];
- }
- }
- }
- static void ltc_move_to_ififo(LTC_Type *base, const uint8_t *data, uint32_t dataSize)
- {
- ltc_xcm_block_t blk;
- ltc_xcm_block_t blkZero = {{0x0u, 0x0u, 0x0u, 0x0u}};
- while (dataSize)
- {
- if (dataSize > 16u)
- {
- ltc_memcpy(&blk, data, 16u);
- dataSize -= 16u;
- data += 16u;
- }
- else
- {
- ltc_memcpy(&blk, &blkZero, sizeof(ltc_xcm_block_t)); /* memset blk to zeroes */
- ltc_memcpy(&blk, data, dataSize);
- dataSize = 0;
- }
- ltc_move_block_to_ififo(base, &blk, sizeof(ltc_xcm_block_t));
- }
- }
- /*!
- * @brief Processes symmetric data through LTC AES in multiple sessions.
- *
- * Specific for AES CCM and GCM modes as they need to update mode register.
- *
- * @param base LTC peripheral base address
- * @param inData Input data
- * @param inSize Size of input data, in bytes
- * @param outData Output data
- * @param lastAs The LTC Algorithm state to be set sup for last block during message processing in multiple sessions.
- * For CCM it is kLTC_ModeFinalize. For GCM it is kLTC_ModeInitFinal.
- * @return Status from encrypt/decrypt operation
- */
- static status_t ltc_symmetric_process_data_multiple(LTC_Type *base,
- const uint8_t *inData,
- uint32_t inSize,
- uint8_t *outData,
- ltc_mode_t modeReg,
- ltc_mode_algorithm_state_t lastAs)
- {
- uint32_t fifoConsumed;
- uint32_t lastSize;
- uint32_t sz;
- uint32_t max_ltc_fifo_size;
- ltc_mode_algorithm_state_t fsm;
- status_t status;
- if ((!inData) || (!outData))
- {
- return kStatus_InvalidArgument;
- }
- if (!((kLTC_ModeFinalize == lastAs) || (kLTC_ModeInitFinal == lastAs)))
- {
- return kStatus_InvalidArgument;
- }
- if (0 == inSize)
- {
- return kStatus_Success;
- }
- if (inSize <= 16u)
- {
- fsm = lastAs;
- lastSize = inSize;
- }
- else
- {
- fsm = (ltc_mode_algorithm_state_t)(
- modeReg &
- LTC_MD_AS_MASK); /* this will be either kLTC_ModeInit or kLTC_ModeUpdate, based on prior processing */
- /* Process all 16-byte data chunks. */
- lastSize = inSize % 16u;
- if (lastSize == 0u)
- {
- lastSize = 16u;
- inSize -= 16u;
- }
- else
- {
- inSize -= lastSize; /* inSize will be rounded down to 16 byte boundary. remaining bytes in lastSize */
- }
- }
- max_ltc_fifo_size = LTC_FIFO_SZ_MAX_DOWN_ALGN;
- fifoConsumed = base->DS;
- while (lastSize)
- {
- switch (fsm)
- {
- case kLTC_ModeUpdate:
- case kLTC_ModeInit:
- while (inSize)
- {
- if (inSize > (max_ltc_fifo_size - fifoConsumed))
- {
- sz = (max_ltc_fifo_size - fifoConsumed);
- }
- else
- {
- sz = inSize;
- }
- base->DS = sz;
- ltc_symmetric_process(base, sz, &inData, &outData);
- inSize -= sz;
- fifoConsumed = 0;
- /* after we completed INITIALIZE job, are there still any data left? */
- if (inSize)
- {
- fsm = kLTC_ModeUpdate;
- status = ltc_wait(base);
- if (kStatus_Success != status)
- {
- return status;
- }
- modeReg &= ~LTC_MD_AS_MASK;
- modeReg |= (uint32_t)fsm;
- base->MD = modeReg;
- }
- else
- {
- fsm = lastAs;
- }
- }
- break;
- case kLTC_ModeFinalize:
- case kLTC_ModeInitFinal:
- /* process last block in FINALIZE */
- status = ltc_wait(base);
- if (kStatus_Success != status)
- {
- return status;
- }
- modeReg &= ~LTC_MD_AS_MASK;
- modeReg |= (uint32_t)lastAs;
- base->MD = modeReg;
- base->DS = lastSize;
- ltc_symmetric_process(base, lastSize, &inData, &outData);
- lastSize = 0;
- break;
- default:
- break;
- }
- }
- status = ltc_wait(base);
- return status;
- }
- /*!
- * @brief Receives MAC compare.
- *
- * This function is a sub-process of CCM and GCM decryption.
- * It compares received MAC with the MAC computed during decryption.
- *
- * @param base LTC peripheral base address
- * @param tag Received MAC.
- * @param tagSize Number of bytes in the received MAC.
- * @param modeReg LTC Mode Register current value. It is modified and written to LTC Mode Register.
- */
- static status_t ltc_aes_received_mac_compare(LTC_Type *base, const uint8_t *tag, uint32_t tagSize, ltc_mode_t modeReg)
- {
- ltc_xcm_block_t blk = {{0x0u, 0x0u, 0x0u, 0x0u}};
- base->CW = kLTC_ClearDataSize;
- base->STA = kLTC_StatusDoneIsr;
- modeReg &= ~LTC_MD_AS_MASK;
- modeReg |= (uint32_t)kLTC_ModeUpdate | LTC_MD_ICV_TEST_MASK;
- base->MD = modeReg;
- base->DS = 0u;
- base->ICVS = tagSize;
- ltc_memcpy(&blk.b[0], &tag[0], tagSize);
- ltc_move_block_to_ififo(base, &blk, tagSize);
- return ltc_wait(base);
- }
- /*!
- * @brief Processes tag during AES GCM and CCM.
- *
- * This function is a sub-process of CCM and GCM encryption and decryption.
- * For encryption, it writes computed MAC to the output tag.
- * For decryption, it compares the received MAC with the computed MAC.
- *
- * @param base LTC peripheral base address
- * @param[in,out] tag Output computed MAC during encryption or Input received MAC during decryption.
- * @param tagSize Size of MAC buffer in bytes.
- * @param modeReg LTC Mode Register current value. It is checked to read Enc/Dec bit.
- * It is modified and written to LTC Mode Register during decryption.
- * @param ctx Index to LTC context registers with computed MAC for encryption process.
- */
- static status_t ltc_aes_process_tag(LTC_Type *base, uint8_t *tag, uint32_t tagSize, ltc_mode_t modeReg, uint32_t ctx)
- {
- status_t status = kStatus_Success;
- if (tag)
- {
- /* For decrypt, compare received MAC with the computed MAC. */
- if (kLTC_ModeDecrypt == (modeReg & LTC_MD_ENC_MASK))
- {
- status = ltc_aes_received_mac_compare(base, tag, tagSize, modeReg);
- }
- else /* FSL_AES_GCM_TYPE_ENCRYPT */
- {
- /* For encryption, write the computed and encrypted MAC to user buffer */
- ltc_get_context(base, &tag[0], tagSize, ctx);
- }
- }
- return status;
- }
- /*******************************************************************************
- * LTC Common code public
- ******************************************************************************/
- void LTC_Init(LTC_Type *base)
- {
- #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
- /* ungate clock */
- CLOCK_EnableClock(kCLOCK_Ltc0);
- #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
- }
- void LTC_Deinit(LTC_Type *base)
- {
- #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
- /* gate clock */
- CLOCK_DisableClock(kCLOCK_Ltc0);
- #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
- }
- #if defined(FSL_FEATURE_LTC_HAS_DPAMS) && FSL_FEATURE_LTC_HAS_DPAMS
- void LTC_SetDpaMaskSeed(LTC_Type *base, uint32_t mask)
- {
- base->DPAMS = mask;
- /* second write as workaround for DPA mask re-seed errata */
- base->DPAMS = mask;
- }
- #endif /* FSL_FEATURE_LTC_HAS_DPAMS */
- /*******************************************************************************
- * AES Code static
- ******************************************************************************/
- static status_t ltc_aes_decrypt_ecb(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t *key,
- uint32_t keySize,
- ltc_aes_key_t keyType)
- {
- status_t retval;
- /* Initialize algorithm state. */
- ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeECB, kLTC_ModeDecrypt);
- /* set DK bit in the LTC Mode Register AAI field for directly loaded decrypt keys */
- if (keyType == kLTC_DecryptKey)
- {
- base->MD |= (1U << kLTC_ModeRegBitShiftDK);
- }
- /* Process data and return status. */
- retval = ltc_process_message_in_sessions(base, &ciphertext[0], size, &plaintext[0]);
- return retval;
- }
- /*******************************************************************************
- * AES Code public
- ******************************************************************************/
- status_t LTC_AES_GenerateDecryptKey(LTC_Type *base, const uint8_t *encryptKey, uint8_t *decryptKey, uint32_t keySize)
- {
- uint8_t plaintext[LTC_AES_BLOCK_SIZE];
- uint8_t ciphertext[LTC_AES_BLOCK_SIZE];
- status_t status;
- if (!ltc_check_key_size(keySize))
- {
- return kStatus_InvalidArgument;
- }
- /* ECB decrypt with encrypt key will convert the key in LTC context into decrypt form of the key */
- status = ltc_aes_decrypt_ecb(base, ciphertext, plaintext, LTC_AES_BLOCK_SIZE, encryptKey, keySize, kLTC_EncryptKey);
- /* now there is decrypt form of the key in the LTC context, so take it */
- ltc_get_key(base, decryptKey, keySize);
- ltc_clear_all(base, false);
- return status;
- }
- status_t LTC_AES_EncryptEcb(
- LTC_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, uint32_t size, const uint8_t *key, uint32_t keySize)
- {
- status_t retval;
- if (!ltc_check_key_size(keySize))
- {
- return kStatus_InvalidArgument;
- }
- /* ECB mode, size must be 16-byte multiple */
- if ((size < 16u) || (size % 16u))
- {
- return kStatus_InvalidArgument;
- }
- /* Initialize algorithm state. */
- ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeECB, kLTC_ModeEncrypt);
- /* Process data and return status. */
- retval = ltc_process_message_in_sessions(base, &plaintext[0], size, &ciphertext[0]);
- ltc_clear_all(base, false);
- return retval;
- }
- status_t LTC_AES_DecryptEcb(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t *key,
- uint32_t keySize,
- ltc_aes_key_t keyType)
- {
- status_t status;
- if (!ltc_check_key_size(keySize))
- {
- return kStatus_InvalidArgument;
- }
- /* ECB mode, size must be 16-byte multiple */
- if ((size < 16u) || (size % 16u))
- {
- return kStatus_InvalidArgument;
- }
- status = ltc_aes_decrypt_ecb(base, ciphertext, plaintext, size, key, keySize, keyType);
- ltc_clear_all(base, false);
- return status;
- }
- status_t LTC_AES_EncryptCbc(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t iv[LTC_AES_IV_SIZE],
- const uint8_t *key,
- uint32_t keySize)
- {
- status_t retval;
- if (!ltc_check_key_size(keySize))
- {
- return kStatus_InvalidArgument;
- }
- /* CBC mode, size must be 16-byte multiple */
- if ((size < 16u) || (size % 16u))
- {
- return kStatus_InvalidArgument;
- }
- /* Initialize algorithm state. */
- ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCBC, kLTC_ModeEncrypt);
- /* Write IV data to the context register. */
- ltc_set_context(base, &iv[0], LTC_AES_IV_SIZE, 0);
- /* Process data and return status. */
- retval = ltc_process_message_in_sessions(base, &plaintext[0], size, &ciphertext[0]);
- ltc_clear_all(base, false);
- return retval;
- }
- status_t LTC_AES_DecryptCbc(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t iv[LTC_AES_IV_SIZE],
- const uint8_t *key,
- uint32_t keySize,
- ltc_aes_key_t keyType)
- {
- status_t retval;
- if (!ltc_check_key_size(keySize))
- {
- return kStatus_InvalidArgument;
- }
- /* CBC mode, size must be 16-byte multiple */
- if ((size < 16u) || (size % 16u))
- {
- return kStatus_InvalidArgument;
- }
- /* set DK bit in the LTC Mode Register AAI field for directly loaded decrypt keys */
- if (keyType == kLTC_DecryptKey)
- {
- base->MD |= (1U << kLTC_ModeRegBitShiftDK);
- }
- /* Initialize algorithm state. */
- ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCBC, kLTC_ModeDecrypt);
- /* Write IV data to the context register. */
- ltc_set_context(base, &iv[0], LTC_AES_IV_SIZE, 0);
- /* Process data and return status. */
- retval = ltc_process_message_in_sessions(base, &ciphertext[0], size, &plaintext[0]);
- ltc_clear_all(base, false);
- return retval;
- }
- status_t LTC_AES_CryptCtr(LTC_Type *base,
- const uint8_t *input,
- uint8_t *output,
- uint32_t size,
- uint8_t counter[LTC_AES_BLOCK_SIZE],
- const uint8_t *key,
- uint32_t keySize,
- uint8_t counterlast[LTC_AES_BLOCK_SIZE],
- uint32_t *szLeft)
- {
- status_t retval;
- uint32_t lastSize;
- if (!ltc_check_key_size(keySize))
- {
- return kStatus_InvalidArgument;
- }
- lastSize = 0U;
- if (counterlast != NULL)
- {
- /* Split the size into full 16-byte chunks and last incomplete block due to LTC AES OFIFO errata */
- if (size <= 16U)
- {
- lastSize = size;
- size = 0U;
- }
- else
- {
- /* Process all 16-byte data chunks. */
- lastSize = size % 16U;
- if (lastSize == 0U)
- {
- lastSize = 16U;
- size -= 16U;
- }
- else
- {
- size -= lastSize; /* size will be rounded down to 16 byte boundary. remaining bytes in lastSize */
- }
- }
- }
- /* Initialize algorithm state. */
- ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCTR, kLTC_ModeEncrypt);
- /* Write initial counter data to the context register.
- * NOTE the counter values start at 4-bytes offset into the context. */
- ltc_set_context(base, &counter[0], 16U, 4U);
- /* Process data and return status. */
- retval = ltc_process_message_in_sessions(base, input, size, output);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- input += size;
- output += size;
- if ((counterlast != NULL) && lastSize)
- {
- uint8_t zeroes[16] = {0};
- ltc_mode_t modeReg;
- modeReg = (uint32_t)kLTC_AlgorithmAES | (uint32_t)kLTC_ModeCTR | (uint32_t)kLTC_ModeEncrypt;
- /* Write the mode register to the hardware. */
- base->MD = modeReg | (uint32_t)kLTC_ModeFinalize;
- /* context is re-used (CTRi) */
- /* Process data and return status. */
- retval = ltc_symmetric_process_data(base, input, lastSize, output);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- if (szLeft)
- {
- *szLeft = 16U - lastSize;
- }
- /* Initialize algorithm state. */
- base->MD = modeReg | (uint32_t)kLTC_ModeUpdate;
- /* context is re-used (CTRi) */
- /* Process data and return status. */
- retval = ltc_symmetric_process_data(base, zeroes, 16U, counterlast);
- }
- ltc_get_context(base, &counter[0], 16U, 4U);
- ltc_clear_all(base, false);
- return retval;
- }
- #if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM
- /*******************************************************************************
- * GCM Code static
- ******************************************************************************/
- static status_t ltc_aes_gcm_check_input_args(LTC_Type *base,
- const uint8_t *src,
- const uint8_t *iv,
- const uint8_t *aad,
- const uint8_t *key,
- uint8_t *dst,
- uint32_t inputSize,
- uint32_t ivSize,
- uint32_t aadSize,
- uint32_t keySize,
- uint32_t tagSize)
- {
- if (!base)
- {
- return kStatus_InvalidArgument;
- }
- /* tag can be NULL to skip tag processing */
- if ((!key) || (ivSize && (!iv)) || (aadSize && (!aad)) || (inputSize && ((!src) || (!dst))))
- {
- return kStatus_InvalidArgument;
- }
- /* octet length of tag (tagSize) must be element of 4,8,12,13,14,15,16 */
- if (((tagSize > 16u) || (tagSize < 12u)) && (tagSize != 4u) && (tagSize != 8u))
- {
- return kStatus_InvalidArgument;
- }
- /* check if keySize is supported */
- if (!ltc_check_key_size(keySize))
- {
- return kStatus_InvalidArgument;
- }
- /* no IV AAD DATA makes no sense */
- if (0 == (inputSize + ivSize + aadSize))
- {
- return kStatus_InvalidArgument;
- }
- return kStatus_Success;
- }
- /*!
- * @brief Process Wrapper for void (*pfunc)(LTC_Type*, uint32_t, bool). Sets IV Size register.
- */
- static void ivsize_next(LTC_Type *base, uint32_t ivSize, bool iv_only)
- {
- base->IVSZ = LTC_IVSZ_IL(iv_only) | ((ivSize)<C_DS_DS_MASK);
- }
- /*!
- * @brief Process Wrapper for void (*pfunc)(LTC_Type*, uint32_t, bool). Sets AAD Size register.
- */
- static void aadsize_next(LTC_Type *base, uint32_t aadSize, bool aad_only)
- {
- base->AADSZ = LTC_AADSZ_AL(aad_only) | ((aadSize)<C_DS_DS_MASK);
- }
- /*!
- * @brief Process IV or AAD string in multi-session.
- *
- * @param base LTC peripheral base address
- * @param iv IV or AAD data
- * @param ivSize Size in bytes of IV or AAD data
- * @param modeReg LTC peripheral Mode register value
- * @param iv_only IV only or AAD only flag
- * @param type selects between IV or AAD
- */
- static status_t ltc_aes_gcm_process_iv_aad(
- LTC_Type *base, const uint8_t *iv, uint32_t ivSize, ltc_mode_t modeReg, bool iv_only, int type, ltc_mode_t modeLast)
- {
- uint32_t sz;
- status_t retval;
- void (*next_size_func)(LTC_Type *ltcBase, uint32_t nextSize, bool authOnly);
- if ((NULL == iv) || (ivSize == 0))
- {
- return kStatus_InvalidArgument;
- }
- sz = LTC_FIFO_SZ_MAX_DOWN_ALGN;
- next_size_func = type == LTC_AES_GCM_TYPE_AAD ? aadsize_next : ivsize_next;
- while (ivSize)
- {
- if (ivSize < sz)
- {
- modeReg &= ~LTC_MD_AS_MASK;
- modeReg |= modeLast;
- base->MD = modeReg;
- next_size_func(base, ivSize, iv_only);
- ltc_move_to_ififo(base, iv, ivSize);
- ivSize = 0;
- }
- else
- {
- /* set algorithm state to UPDATE */
- modeReg &= ~LTC_MD_AS_MASK;
- modeReg |= kLTC_ModeUpdate;
- base->MD = modeReg;
- next_size_func(base, (uint16_t)sz, true);
- ltc_move_to_ififo(base, iv, sz);
- ivSize -= sz;
- iv += sz;
- }
- retval = ltc_wait(base);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- } /* end while */
- return kStatus_Success;
- }
- static status_t ltc_aes_gcm_process(LTC_Type *base,
- ltc_mode_encrypt_t encryptMode,
- const uint8_t *src,
- uint32_t inputSize,
- const uint8_t *iv,
- uint32_t ivSize,
- const uint8_t *aad,
- uint32_t aadSize,
- const uint8_t *key,
- uint32_t keySize,
- uint8_t *dst,
- uint8_t *tag,
- uint32_t tagSize)
- {
- status_t retval; /* return value */
- uint32_t max_ltc_fifo_sz; /* maximum data size that we can put to LTC FIFO in one session. 12-bit limit. */
- ltc_mode_t modeReg; /* read and write LTC mode register */
- bool single_ses_proc_all; /* iv, aad and src data can be processed in one session */
- bool iv_only;
- bool aad_only;
- retval = ltc_aes_gcm_check_input_args(base, src, iv, aad, key, dst, inputSize, ivSize, aadSize, keySize, tagSize);
- /* API input validation */
- if (kStatus_Success != retval)
- {
- return retval;
- }
- max_ltc_fifo_sz = LTC_DS_DS_MASK; /* 12-bit field limit */
- /*
- * Write value to LTC AADSIZE (rounded up to next 16 byte boundary)
- * plus the write value to LTC IV (rounded up to next 16 byte boundary)
- * plus the inputSize. If the result is less than max_ltc_fifo_sz
- * then all can be processed in one session FINALIZE.
- * Otherwise, we have to split into multiple session, going through UPDATE(s), INITIALIZE, UPDATE(s) and FINALIZE.
- */
- single_ses_proc_all =
- (((aadSize + 15u) & 0xfffffff0u) + ((ivSize + 15u) & 0xfffffff0u) + inputSize) <= max_ltc_fifo_sz;
- /* setup key, algorithm and set the alg.state */
- if (single_ses_proc_all)
- {
- ltc_symmetric_final(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeGCM, encryptMode);
- modeReg = base->MD;
- iv_only = (aadSize == 0) && (inputSize == 0);
- aad_only = (inputSize == 0);
- /* DS_MASK here is not a bug. IV size field can be written with more than 4-bits,
- * as the IVSZ write value, aligned to next 16 bytes boundary, is written also to the Data Size.
- * For example, I can write 22 to IVSZ, 32 will be written to Data Size and IVSZ will have value 6, which is 22
- * mod 16.
- */
- base->IVSZ = LTC_IVSZ_IL(iv_only) | ((ivSize)<C_DS_DS_MASK);
- ltc_move_to_ififo(base, iv, ivSize);
- if (iv_only && ivSize)
- {
- retval = ltc_wait(base);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- }
- base->AADSZ = LTC_AADSZ_AL(aad_only) | ((aadSize)<C_DS_DS_MASK);
- ltc_move_to_ififo(base, aad, aadSize);
- if (aad_only && aadSize)
- {
- retval = ltc_wait(base);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- }
- if (inputSize)
- {
- /* Workaround for the LTC Data Size register update errata TKT261180 */
- while (16U < base->DS)
- {
- }
- ltc_symmetric_process_data(base, &src[0], inputSize, &dst[0]);
- }
- }
- else
- {
- ltc_symmetric_init(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeGCM, encryptMode);
- modeReg = base->MD;
- /* process IV */
- if (ivSize)
- {
- /* last chunk of IV is always INITIALIZE (for GHASH to occur) */
- retval = ltc_aes_gcm_process_iv_aad(base, iv, ivSize, modeReg, true, LTC_AES_GCM_TYPE_IV, kLTC_ModeInit);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- }
- /* process AAD */
- if (aadSize)
- {
- /* AS mode to process last chunk of AAD. it differs if we are in GMAC or GCM */
- ltc_mode_t lastModeReg;
- if (0 == inputSize)
- {
- /* if there is no DATA, set mode to compute final MAC. this is GMAC mode */
- lastModeReg = kLTC_ModeInitFinal;
- }
- else
- {
- /* there are confidential DATA. so process last chunk of AAD in UPDATE mode */
- lastModeReg = kLTC_ModeUpdate;
- }
- retval = ltc_aes_gcm_process_iv_aad(base, aad, aadSize, modeReg, true, LTC_AES_GCM_TYPE_AAD, lastModeReg);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- }
- /* there are DATA. */
- if (inputSize)
- {
- /* set algorithm state to UPDATE */
- modeReg &= ~LTC_MD_AS_MASK;
- modeReg |= kLTC_ModeUpdate;
- base->MD = modeReg;
- retval =
- ltc_symmetric_process_data_multiple(base, &src[0], inputSize, &dst[0], modeReg, kLTC_ModeInitFinal);
- }
- }
- if (kStatus_Success != retval)
- {
- return retval;
- }
- retval = ltc_aes_process_tag(base, tag, tagSize, modeReg, LTC_GCM_TAG_IDX);
- return retval;
- }
- /*******************************************************************************
- * GCM Code public
- ******************************************************************************/
- status_t LTC_AES_EncryptTagGcm(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t *iv,
- uint32_t ivSize,
- const uint8_t *aad,
- uint32_t aadSize,
- const uint8_t *key,
- uint32_t keySize,
- uint8_t *tag,
- uint32_t tagSize)
- {
- status_t status;
- status = ltc_aes_gcm_process(base, kLTC_ModeEncrypt, plaintext, size, iv, ivSize, aad, aadSize, key, keySize,
- ciphertext, tag, tagSize);
- ltc_clear_all(base, false);
- return status;
- }
- status_t LTC_AES_DecryptTagGcm(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t *iv,
- uint32_t ivSize,
- const uint8_t *aad,
- uint32_t aadSize,
- const uint8_t *key,
- uint32_t keySize,
- const uint8_t *tag,
- uint32_t tagSize)
- {
- uint8_t temp_tag[16] = {0}; /* max. octet length of Integrity Check Value ICV (tag) is 16 */
- uint8_t *tag_ptr;
- status_t status;
- tag_ptr = NULL;
- if (tag)
- {
- ltc_memcpy(temp_tag, tag, tagSize);
- tag_ptr = &temp_tag[0];
- }
- status = ltc_aes_gcm_process(base, kLTC_ModeDecrypt, ciphertext, size, iv, ivSize, aad, aadSize, key, keySize,
- plaintext, tag_ptr, tagSize);
- ltc_clear_all(base, false);
- return status;
- }
- #endif /* FSL_FEATURE_LTC_HAS_GCM */
- /*******************************************************************************
- * CCM Code static
- ******************************************************************************/
- static status_t ltc_aes_ccm_check_input_args(LTC_Type *base,
- const uint8_t *src,
- const uint8_t *iv,
- const uint8_t *key,
- uint8_t *dst,
- uint32_t ivSize,
- uint32_t aadSize,
- uint32_t keySize,
- uint32_t tagSize)
- {
- if (!base)
- {
- return kStatus_InvalidArgument;
- }
- /* tag can be NULL to skip tag processing */
- if ((!src) || (!iv) || (!key) || (!dst))
- {
- return kStatus_InvalidArgument;
- }
- /* size of Nonce (ivSize) must be element of 7,8,9,10,11,12,13 */
- if ((ivSize < 7u) || (ivSize > 13u))
- {
- return kStatus_InvalidArgument;
- }
- /* octet length of MAC (tagSize) must be element of 4,6,8,10,12,14,16 for tag processing or zero to skip tag
- * processing */
- if (((tagSize > 0) && (tagSize < 4u)) || (tagSize > 16u) || (tagSize & 1u))
- {
- return kStatus_InvalidArgument;
- }
- /* check if keySize is supported */
- if (!ltc_check_key_size(keySize))
- {
- return kStatus_InvalidArgument;
- }
- /* LTC does not support more AAD than this */
- if (aadSize >= 65280u)
- {
- return kStatus_InvalidArgument;
- }
- return kStatus_Success;
- }
- static uint32_t swap_bytes(uint32_t in)
- {
- return (((in & 0x000000ffu) << 24) | ((in & 0x0000ff00u) << 8) | ((in & 0x00ff0000u) >> 8) |
- ((in & 0xff000000u) >> 24));
- }
- static void ltc_aes_ccm_context_init(
- LTC_Type *base, uint32_t inputSize, const uint8_t *iv, uint32_t ivSize, uint32_t aadSize, uint32_t tagSize)
- {
- ltc_xcm_block_t blk;
- ltc_xcm_block_t blkZero = {{0x0u, 0x0u, 0x0u, 0x0u}};
- int q; /* octet length of binary representation of the octet length of the payload. computed as (15 - n), where n is
- length of nonce(=ivSize) */
- uint8_t flags; /* flags field in B0 and CTR0 */
- /* compute B0 */
- ltc_memcpy(&blk, &blkZero, sizeof(blk));
- /* tagSize - size of output MAC */
- q = 15 - ivSize;
- flags = (uint8_t)(8 * ((tagSize - 2) / 2) + q - 1); /* 8*M' + L' */
- if (aadSize)
- {
- flags |= 0x40; /* Adata */
- }
- blk.b[0] = flags; /* flags field */
- blk.w[3] = swap_bytes(inputSize); /* message size, most significant byte first */
- ltc_memcpy(&blk.b[1], iv, ivSize); /* nonce field */
- /* Write B0 data to the context register.
- */
- ltc_set_context(base, &blk.b[0], 16, 0);
- /* Write CTR0 to the context register.
- */
- ltc_memcpy(&blk, &blkZero, sizeof(blk)); /* ctr(0) field = zero */
- blk.b[0] = q - 1; /* flags field */
- ltc_memcpy(&blk.b[1], iv, ivSize); /* nonce field */
- ltc_set_context(base, &blk.b[0], 16, 4);
- }
- static status_t ltc_aes_ccm_process_aad(
- LTC_Type *base, uint32_t inputSize, const uint8_t *aad, uint32_t aadSize, ltc_mode_t *modeReg)
- {
- ltc_xcm_block_t blk = {{0x0u, 0x0u, 0x0u, 0x0u}};
- uint32_t swapped; /* holds byte swap of uint32_t */
- status_t retval;
- if (aadSize)
- {
- bool aad_only;
- bool aad_single_session;
- uint32_t sz = 0;
- aad_only = inputSize == 0u;
- aad_single_session = (((aadSize + 2u) + 15u) & 0xfffffff0u) <= LTC_FIFO_SZ_MAX_DOWN_ALGN;
- /* limit by CCM spec: 2^16 - 2^8 = 65280 */
- /* encoding is two octets, msbyte first */
- swapped = swap_bytes(aadSize);
- ltc_memcpy(&blk.b[0], ((uint8_t *)&swapped) + sizeof(uint16_t), sizeof(uint16_t));
- sz = aadSize > 14u ? 14u : aadSize; /* limit aad to the end of 16 bytes blk */
- ltc_memcpy(&blk.b[2], aad, sz); /* fill B1 with aad */
- if (aad_single_session)
- {
- base->AADSZ = LTC_AADSZ_AL(aad_only) | ((aadSize + 2U) & LTC_DS_DS_MASK);
- /* move first AAD block (16 bytes block B1) to FIFO */
- ltc_move_block_to_ififo(base, &blk, sizeof(blk));
- }
- else
- {
- base->AADSZ = LTC_AADSZ_AL(true) | (16U);
- /* move first AAD block (16 bytes block B1) to FIFO */
- ltc_move_block_to_ififo(base, &blk, sizeof(blk));
- }
- /* track consumed AAD. sz bytes have been moved to fifo. */
- aadSize -= sz;
- aad += sz;
- if (aad_single_session)
- {
- /* move remaining AAD to FIFO, then return, to continue with MDATA */
- ltc_move_to_ififo(base, aad, aadSize);
- }
- else if (aadSize == 0u)
- {
- retval = ltc_wait(base);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- }
- else
- {
- while (aadSize)
- {
- retval = ltc_wait(base);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- *modeReg &= ~LTC_MD_AS_MASK;
- *modeReg |= (uint32_t)kLTC_ModeUpdate;
- base->MD = *modeReg;
- sz = LTC_FIFO_SZ_MAX_DOWN_ALGN;
- if (aadSize < sz)
- {
- base->AADSZ = LTC_AADSZ_AL(aad_only) | (aadSize & LTC_DS_DS_MASK);
- ltc_move_to_ififo(base, aad, aadSize);
- aadSize = 0;
- }
- else
- {
- base->AADSZ = LTC_AADSZ_AL(true) | (sz & LTC_DS_DS_MASK);
- ltc_move_to_ififo(base, aad, sz);
- aadSize -= sz;
- aad += sz;
- }
- } /* end while */
- } /* end else */
- } /* end if */
- return kStatus_Success;
- }
- static status_t ltc_aes_ccm_process(LTC_Type *base,
- ltc_mode_encrypt_t encryptMode,
- const uint8_t *src,
- uint32_t inputSize,
- const uint8_t *iv,
- uint32_t ivSize,
- const uint8_t *aad,
- uint32_t aadSize,
- const uint8_t *key,
- uint32_t keySize,
- uint8_t *dst,
- uint8_t *tag,
- uint32_t tagSize)
- {
- status_t retval; /* return value */
- uint32_t max_ltc_fifo_sz; /* maximum data size that we can put to LTC FIFO in one session. 12-bit limit. */
- ltc_mode_t modeReg; /* read and write LTC mode register */
- bool single_ses_proc_all; /* aad and src data can be processed in one session */
- retval = ltc_aes_ccm_check_input_args(base, src, iv, key, dst, ivSize, aadSize, keySize, tagSize);
- /* API input validation */
- if (kStatus_Success != retval)
- {
- return retval;
- }
- max_ltc_fifo_sz = LTC_DS_DS_MASK; /* 12-bit field limit */
- /* Write value to LTC AADSIZE will be (aadSize+2) value.
- * The value will be rounded up to next 16 byte boundary and added to Data Size register.
- * We then add inputSize to Data Size register. If the resulting Data Size is less than max_ltc_fifo_sz
- * then all can be processed in one session INITIALIZE/FINALIZE.
- * Otherwise, we have to split into multiple session, going through INITIALIZE, UPDATE (if required) and FINALIZE.
- */
- single_ses_proc_all = ((((aadSize + 2) + 15u) & 0xfffffff0u) + inputSize) <= max_ltc_fifo_sz;
- /* setup key, algorithm and set the alg.state to INITIALIZE */
- if (single_ses_proc_all)
- {
- ltc_symmetric_init_final(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCCM, encryptMode);
- }
- else
- {
- ltc_symmetric_init(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCCM, encryptMode);
- }
- modeReg = base->MD;
- /* Initialize LTC context for AES CCM: block B0 and initial counter CTR0 */
- ltc_aes_ccm_context_init(base, inputSize, iv, ivSize, aadSize, tagSize);
- /* Process additional authentication data, if there are any.
- * Need to split the job into individual sessions of up to 4096 bytes, due to LTC IFIFO data size limit.
- */
- retval = ltc_aes_ccm_process_aad(base, inputSize, aad, aadSize, &modeReg);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- /* Workaround for the LTC Data Size register update errata TKT261180 */
- if (inputSize)
- {
- while (16u < base->DS)
- {
- }
- }
- /* Process message */
- if (single_ses_proc_all)
- {
- retval = ltc_symmetric_process_data(base, &src[0], inputSize, &dst[0]);
- }
- else
- {
- retval = ltc_symmetric_process_data_multiple(base, &src[0], inputSize, &dst[0], modeReg, kLTC_ModeFinalize);
- }
- if (kStatus_Success != retval)
- {
- return retval;
- }
- retval = ltc_aes_process_tag(base, tag, tagSize, modeReg, LTC_CCM_TAG_IDX);
- return retval;
- }
- /*******************************************************************************
- * CCM Code public
- ******************************************************************************/
- status_t LTC_AES_EncryptTagCcm(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t *iv,
- uint32_t ivSize,
- const uint8_t *aad,
- uint32_t aadSize,
- const uint8_t *key,
- uint32_t keySize,
- uint8_t *tag,
- uint32_t tagSize)
- {
- status_t status;
- status = ltc_aes_ccm_process(base, kLTC_ModeEncrypt, plaintext, size, iv, ivSize, aad, aadSize, key, keySize,
- ciphertext, tag, tagSize);
- ltc_clear_all(base, false);
- return status;
- }
- status_t LTC_AES_DecryptTagCcm(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t *iv,
- uint32_t ivSize,
- const uint8_t *aad,
- uint32_t aadSize,
- const uint8_t *key,
- uint32_t keySize,
- const uint8_t *tag,
- uint32_t tagSize)
- {
- uint8_t temp_tag[16] = {0}; /* max. octet length of MAC (tag) is 16 */
- uint8_t *tag_ptr;
- status_t status;
- tag_ptr = NULL;
- if (tag)
- {
- ltc_memcpy(temp_tag, tag, tagSize);
- tag_ptr = &temp_tag[0];
- }
- status = ltc_aes_ccm_process(base, kLTC_ModeDecrypt, ciphertext, size, iv, ivSize, aad, aadSize, key, keySize,
- plaintext, tag_ptr, tagSize);
- ltc_clear_all(base, false);
- return status;
- }
- #if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES
- /*******************************************************************************
- * DES / 3DES Code static
- ******************************************************************************/
- static status_t ltc_des_process(LTC_Type *base,
- const uint8_t *input,
- uint8_t *output,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key[LTC_DES_KEY_SIZE],
- ltc_mode_symmetric_alg_t modeAs,
- ltc_mode_encrypt_t modeEnc)
- {
- status_t retval;
- /* all but OFB, size must be 8-byte multiple */
- if ((modeAs != kLTC_ModeOFB) && ((size < 8u) || (size % 8u)))
- {
- return kStatus_InvalidArgument;
- }
- /* Initialize algorithm state. */
- ltc_symmetric_update(base, &key[0], LTC_DES_KEY_SIZE, kLTC_AlgorithmDES, modeAs, modeEnc);
- if ((modeAs != kLTC_ModeECB))
- {
- ltc_set_context(base, iv, LTC_DES_IV_SIZE, 0);
- }
- /* Process data and return status. */
- retval = ltc_process_message_in_sessions(base, input, size, output);
- ltc_clear_all(base, false);
- return retval;
- }
- status_t ltc_3des_check_input_args(ltc_mode_symmetric_alg_t modeAs,
- uint32_t size,
- const uint8_t *key1,
- const uint8_t *key2)
- {
- /* all but OFB, size must be 8-byte multiple */
- if ((modeAs != kLTC_ModeOFB) && ((size < 8u) || (size % 8u)))
- {
- return kStatus_InvalidArgument;
- }
- if ((key1 == NULL) || (key2 == NULL))
- {
- return kStatus_InvalidArgument;
- }
- return kStatus_Success;
- }
- static status_t ltc_3des_process(LTC_Type *base,
- const uint8_t *input,
- uint8_t *output,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE],
- const uint8_t key3[LTC_DES_KEY_SIZE],
- ltc_mode_symmetric_alg_t modeAs,
- ltc_mode_encrypt_t modeEnc)
- {
- status_t retval;
- uint8_t key[LTC_DES_KEY_SIZE * 3];
- uint8_t keySize = LTC_DES_KEY_SIZE * 2;
- retval = ltc_3des_check_input_args(modeAs, size, key1, key2);
- if (kStatus_Success != retval)
- {
- return retval;
- }
- ltc_memcpy(&key[0], &key1[0], LTC_DES_KEY_SIZE);
- ltc_memcpy(&key[LTC_DES_KEY_SIZE], &key2[0], LTC_DES_KEY_SIZE);
- if (key3)
- {
- ltc_memcpy(&key[LTC_DES_KEY_SIZE * 2], &key3[0], LTC_DES_KEY_SIZE);
- keySize = sizeof(key);
- }
- /* Initialize algorithm state. */
- ltc_symmetric_update(base, &key[0], keySize, kLTC_Algorithm3DES, modeAs, modeEnc);
- if ((modeAs != kLTC_ModeECB))
- {
- ltc_set_context(base, iv, LTC_DES_IV_SIZE, 0);
- }
- /* Process data and return status. */
- retval = ltc_process_message_in_sessions(base, input, size, output);
- ltc_clear_all(base, false);
- return retval;
- }
- /*******************************************************************************
- * DES / 3DES Code public
- ******************************************************************************/
- status_t LTC_DES_EncryptEcb(
- LTC_Type *base, const uint8_t *plaintext, uint8_t *ciphertext, uint32_t size, const uint8_t key[LTC_DES_KEY_SIZE])
- {
- return ltc_des_process(base, plaintext, ciphertext, size, NULL, key, kLTC_ModeECB, kLTC_ModeEncrypt);
- }
- status_t LTC_DES_DecryptEcb(
- LTC_Type *base, const uint8_t *ciphertext, uint8_t *plaintext, uint32_t size, const uint8_t key[LTC_DES_KEY_SIZE])
- {
- return ltc_des_process(base, ciphertext, plaintext, size, NULL, key, kLTC_ModeECB, kLTC_ModeDecrypt);
- }
- status_t LTC_DES_EncryptCbc(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key[LTC_DES_KEY_SIZE])
- {
- return ltc_des_process(base, plaintext, ciphertext, size, iv, key, kLTC_ModeCBC, kLTC_ModeEncrypt);
- }
- status_t LTC_DES_DecryptCbc(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key[LTC_DES_KEY_SIZE])
- {
- return ltc_des_process(base, ciphertext, plaintext, size, iv, key, kLTC_ModeCBC, kLTC_ModeDecrypt);
- }
- status_t LTC_DES_EncryptCfb(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key[LTC_DES_KEY_SIZE])
- {
- return ltc_des_process(base, plaintext, ciphertext, size, iv, key, kLTC_ModeCFB, kLTC_ModeEncrypt);
- }
- status_t LTC_DES_DecryptCfb(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key[LTC_DES_KEY_SIZE])
- {
- return ltc_des_process(base, ciphertext, plaintext, size, iv, key, kLTC_ModeCFB, kLTC_ModeDecrypt);
- }
- status_t LTC_DES_EncryptOfb(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key[LTC_DES_KEY_SIZE])
- {
- return ltc_des_process(base, plaintext, ciphertext, size, iv, key, kLTC_ModeOFB, kLTC_ModeEncrypt);
- }
- status_t LTC_DES_DecryptOfb(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key[LTC_DES_KEY_SIZE])
- {
- return ltc_des_process(base, ciphertext, plaintext, size, iv, key, kLTC_ModeOFB, kLTC_ModeDecrypt);
- }
- status_t LTC_DES2_EncryptEcb(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, plaintext, ciphertext, size, NULL, key1, key2, NULL, kLTC_ModeECB, kLTC_ModeEncrypt);
- }
- status_t LTC_DES3_EncryptEcb(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE],
- const uint8_t key3[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, plaintext, ciphertext, size, NULL, key1, key2, key3, kLTC_ModeECB, kLTC_ModeEncrypt);
- }
- status_t LTC_DES2_DecryptEcb(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, ciphertext, plaintext, size, NULL, key1, key2, NULL, kLTC_ModeECB, kLTC_ModeDecrypt);
- }
- status_t LTC_DES3_DecryptEcb(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE],
- const uint8_t key3[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, ciphertext, plaintext, size, NULL, key1, key2, key3, kLTC_ModeECB, kLTC_ModeDecrypt);
- }
- status_t LTC_DES2_EncryptCbc(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeCBC, kLTC_ModeEncrypt);
- }
- status_t LTC_DES3_EncryptCbc(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE],
- const uint8_t key3[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeCBC, kLTC_ModeEncrypt);
- }
- status_t LTC_DES2_DecryptCbc(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeCBC, kLTC_ModeDecrypt);
- }
- status_t LTC_DES3_DecryptCbc(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE],
- const uint8_t key3[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeCBC, kLTC_ModeDecrypt);
- }
- status_t LTC_DES2_EncryptCfb(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeCFB, kLTC_ModeEncrypt);
- }
- status_t LTC_DES3_EncryptCfb(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE],
- const uint8_t key3[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeCFB, kLTC_ModeEncrypt);
- }
- status_t LTC_DES2_DecryptCfb(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeCFB, kLTC_ModeDecrypt);
- }
- status_t LTC_DES3_DecryptCfb(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE],
- const uint8_t key3[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeCFB, kLTC_ModeDecrypt);
- }
- status_t LTC_DES2_EncryptOfb(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeOFB, kLTC_ModeEncrypt);
- }
- status_t LTC_DES3_EncryptOfb(LTC_Type *base,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE],
- const uint8_t key3[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeOFB, kLTC_ModeEncrypt);
- }
- status_t LTC_DES2_DecryptOfb(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeOFB, kLTC_ModeDecrypt);
- }
- status_t LTC_DES3_DecryptOfb(LTC_Type *base,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- uint32_t size,
- const uint8_t iv[LTC_DES_IV_SIZE],
- const uint8_t key1[LTC_DES_KEY_SIZE],
- const uint8_t key2[LTC_DES_KEY_SIZE],
- const uint8_t key3[LTC_DES_KEY_SIZE])
- {
- return ltc_3des_process(base, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeOFB, kLTC_ModeDecrypt);
- }
- #endif /* FSL_FEATURE_LTC_HAS_DES */
- /*******************************************************************************
- * HASH Definitions
- ******************************************************************************/
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- #define LTC_SHA_BLOCK_SIZE 64 /*!< SHA-1, SHA-224 & SHA-256 block size */
- #define LTC_HASH_BLOCK_SIZE LTC_SHA_BLOCK_SIZE /*!< LTC hash block size */
- enum _ltc_sha_digest_len
- {
- kLTC_RunLenSha1 = 28u,
- kLTC_OutLenSha1 = 20u,
- kLTC_RunLenSha224 = 40u,
- kLTC_OutLenSha224 = 28u,
- kLTC_RunLenSha256 = 40u,
- kLTC_OutLenSha256 = 32u,
- };
- #else
- #define LTC_HASH_BLOCK_SIZE LTC_AES_BLOCK_SIZE /*!< LTC hash block size */
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- /*! Internal states of the HASH creation process */
- typedef enum _ltc_hash_algo_state
- {
- kLTC_HashInit = 1u, /*!< Key in the HASH context is the input key. */
- kLTC_HashUpdate, /*!< HASH context has algorithm specific context: MAC, K2 and K3 (XCBC-MAC), MAC and L (CMAC),
- running digest (MDHA). Key in the HASH context is the derived key. */
- } ltc_hash_algo_state_t;
- /*! 16/64-byte block represented as byte array or 4/16 32-bit words */
- typedef union _ltc_hash_block
- {
- uint32_t w[LTC_HASH_BLOCK_SIZE / 4]; /*!< array of 32-bit words */
- uint8_t b[LTC_HASH_BLOCK_SIZE]; /*!< byte array */
- } ltc_hash_block_t;
- /*! Definitions of indexes into hash context array */
- typedef enum _ltc_hash_ctx_indexes
- {
- kLTC_HashCtxKeyStartIdx = 12, /*!< context word array index where key is stored */
- kLTC_HashCtxKeySize = 20, /*!< context word array index where key size is stored */
- kLTC_HashCtxNumWords = 21, /*!< number of context array 32-bit words */
- } ltc_hash_ctx_indexes;
- typedef struct _ltc_hash_ctx_internal
- {
- ltc_hash_block_t blk; /*!< memory buffer. only full 64/16-byte blocks are written to LTC during hash updates */
- uint32_t blksz; /*!< number of valid bytes in memory buffer */
- LTC_Type *base; /*!< LTC peripheral base address */
- ltc_hash_algo_t algo; /*!< selected algorithm from the set of supported algorithms in ltc_drv_hash_algo */
- ltc_hash_algo_state_t state; /*!< finite machine state of the hash software process */
- uint32_t word[kLTC_HashCtxNumWords]; /*!< LTC module context that needs to be saved/restored between LTC jobs */
- } ltc_hash_ctx_internal_t;
- /*******************************************************************************
- * HASH Code static
- ******************************************************************************/
- static status_t ltc_hash_check_input_alg(ltc_hash_algo_t algo)
- {
- if ((algo != kLTC_XcbcMac) && (algo != kLTC_Cmac)
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- && (algo != kLTC_Sha1) && (algo != kLTC_Sha224) && (algo != kLTC_Sha256)
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- )
- {
- return kStatus_InvalidArgument;
- }
- return kStatus_Success;
- }
- static inline bool ltc_hash_alg_is_cmac(ltc_hash_algo_t algo)
- {
- return ((algo == kLTC_XcbcMac) || (algo == kLTC_Cmac));
- }
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- static inline bool ltc_hash_alg_is_sha(ltc_hash_algo_t algo)
- {
- return ((algo == kLTC_Sha1) || (algo == kLTC_Sha224) || (algo == kLTC_Sha256));
- }
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- static status_t ltc_hash_check_input_args(
- LTC_Type *base, ltc_hash_ctx_t *ctx, ltc_hash_algo_t algo, const uint8_t *key, uint32_t keySize)
- {
- /* Check validity of input algorithm */
- if (kStatus_Success != ltc_hash_check_input_alg(algo))
- {
- return kStatus_InvalidArgument;
- }
- if ((NULL == ctx) || (NULL == base))
- {
- return kStatus_InvalidArgument;
- }
- if (ltc_hash_alg_is_cmac(algo))
- {
- if ((NULL == key) || (!ltc_check_key_size(keySize)))
- {
- return kStatus_InvalidArgument;
- }
- }
- return kStatus_Success;
- }
- static status_t ltc_hash_check_context(ltc_hash_ctx_internal_t *ctxInternal, const uint8_t *data)
- {
- if ((NULL == data) || (NULL == ctxInternal) || (NULL == ctxInternal->base) ||
- (kStatus_Success != ltc_hash_check_input_alg(ctxInternal->algo)))
- {
- return kStatus_InvalidArgument;
- }
- return kStatus_Success;
- }
- static uint32_t ltc_hash_algo2mode(ltc_hash_algo_t algo, ltc_mode_algorithm_state_t asMode, uint32_t *algOutSize)
- {
- uint32_t modeReg = 0u;
- uint32_t outSize = 0u;
- /* Set LTC algorithm */
- switch (algo)
- {
- case kLTC_XcbcMac:
- modeReg = (uint32_t)kLTC_AlgorithmAES | (uint32_t)kLTC_ModeXCBCMAC;
- outSize = 16u;
- break;
- case kLTC_Cmac:
- modeReg = (uint32_t)kLTC_AlgorithmAES | (uint32_t)kLTC_ModeCMAC;
- outSize = 16u;
- break;
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- case kLTC_Sha1:
- modeReg = (uint32_t)kLTC_AlgorithmSHA1;
- outSize = kLTC_OutLenSha1;
- break;
- case kLTC_Sha224:
- modeReg = (uint32_t)kLTC_AlgorithmSHA224;
- outSize = kLTC_OutLenSha224;
- break;
- case kLTC_Sha256:
- modeReg = (uint32_t)kLTC_AlgorithmSHA256;
- outSize = kLTC_OutLenSha256;
- break;
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- default:
- break;
- }
- modeReg |= (uint32_t)asMode;
- if (algOutSize)
- {
- *algOutSize = outSize;
- }
- return modeReg;
- }
- static void ltc_hash_engine_init(ltc_hash_ctx_internal_t *ctx)
- {
- uint8_t *key;
- uint32_t keySize;
- LTC_Type *base;
- ltc_mode_symmetric_alg_t algo;
- base = ctx->base;
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- if (ltc_hash_alg_is_cmac(ctx->algo))
- {
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- /*
- * word[kLtcCmacCtxKeySize] = key_length
- * word[1-8] = key
- */
- keySize = ctx->word[kLTC_HashCtxKeySize];
- key = (uint8_t *)&ctx->word[kLTC_HashCtxKeyStartIdx];
- /* set LTC mode register to INITIALIZE */
- algo = (ctx->algo == kLTC_XcbcMac) ? kLTC_ModeXCBCMAC : kLTC_ModeCMAC;
- ltc_symmetric_init(base, key, keySize, kLTC_AlgorithmAES, algo, kLTC_ModeEncrypt);
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- }
- else if (ltc_hash_alg_is_sha(ctx->algo))
- {
- /* Clear internal register states. */
- base->CW = (uint32_t)kLTC_ClearAll;
- /* Set byte swap on for several registers we will be reading and writing
- * user data to/from. */
- base->CTL |= kLTC_CtrlSwapAll;
- }
- else
- {
- /* do nothing in this case */
- }
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- }
- static void ltc_hash_save_context(ltc_hash_ctx_internal_t *ctx)
- {
- uint32_t sz;
- LTC_Type *base;
- base = ctx->base;
- /* Get context size */
- switch (ctx->algo)
- {
- case kLTC_XcbcMac:
- /*
- * word[0-3] = mac
- * word[3-7] = k3
- * word[8-11] = k2
- * word[kLtcCmacCtxKeySize] = keySize
- */
- sz = 12 * sizeof(uint32_t);
- break;
- case kLTC_Cmac:
- /*
- * word[0-3] = mac
- * word[3-7] = L */
- sz = 8 * sizeof(uint32_t);
- break;
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- case kLTC_Sha1:
- sz = (kLTC_RunLenSha1);
- break;
- case kLTC_Sha224:
- sz = (kLTC_RunLenSha224);
- break;
- case kLTC_Sha256:
- sz = (kLTC_RunLenSha256);
- break;
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- default:
- sz = 0;
- break;
- }
- ltc_get_context(base, (uint8_t *)&ctx->word[0], sz, 0);
- if (true == ltc_hash_alg_is_cmac(ctx->algo))
- {
- /* word[12-19] = key */
- ltc_get_key(base, (uint8_t *)&ctx->word[kLTC_HashCtxKeyStartIdx], ctx->word[kLTC_HashCtxKeySize]);
- }
- }
- static void ltc_hash_restore_context(ltc_hash_ctx_internal_t *ctx)
- {
- uint32_t sz;
- uint32_t keySize;
- LTC_Type *base;
- base = ctx->base;
- /* Get context size */
- switch (ctx->algo)
- {
- case kLTC_XcbcMac:
- /*
- * word[0-3] = mac
- * word[3-7] = k3
- * word[8-11] = k2
- * word[kLtcCmacCtxKeySize] = keySize
- */
- sz = 12 * sizeof(uint32_t);
- break;
- case kLTC_Cmac:
- /*
- * word[0-3] = mac
- * word[3-7] = L */
- sz = 8 * sizeof(uint32_t);
- break;
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- case kLTC_Sha1:
- sz = (kLTC_RunLenSha1);
- break;
- case kLTC_Sha224:
- sz = (kLTC_RunLenSha224);
- break;
- case kLTC_Sha256:
- sz = (kLTC_RunLenSha256);
- break;
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- default:
- sz = 0;
- break;
- }
- ltc_set_context(base, (const uint8_t *)&ctx->word[0], sz, 0);
- if (ltc_hash_alg_is_cmac(ctx->algo))
- {
- /*
- * word[12-19] = key
- * word[kLtcCmacCtxKeySize] = keySize
- */
- base->CW = kLTC_ClearKey; /* clear Key and Key Size registers */
- keySize = ctx->word[kLTC_HashCtxKeySize];
- /* Write the key in place. */
- ltc_set_key(base, (const uint8_t *)&ctx->word[kLTC_HashCtxKeyStartIdx], keySize);
- /* Write the key size. This must be done after writing the key, and this
- * action locks the ability to modify the key registers. */
- base->KS = keySize;
- }
- }
- static void ltc_hash_prepare_context_switch(LTC_Type *base)
- {
- base->CW = (uint32_t)kLTC_ClearDataSize | (uint32_t)kLTC_ClearMode;
- base->STA = kLTC_StatusDoneIsr;
- }
- static uint32_t ltc_hash_get_block_size(ltc_hash_algo_t algo)
- {
- if ((algo == kLTC_XcbcMac) || (algo == kLTC_Cmac))
- {
- return (uint32_t)LTC_AES_BLOCK_SIZE;
- }
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- else if ((algo == kLTC_Sha1) || (algo == kLTC_Sha224) || (algo == kLTC_Sha256))
- {
- return (uint32_t)LTC_SHA_BLOCK_SIZE;
- }
- else
- {
- return 0;
- }
- #else
- return 0;
- #endif
- }
- static void ltc_hash_block_to_ififo(LTC_Type *base, const ltc_hash_block_t *blk, uint32_t numBytes, uint32_t blockSize)
- {
- uint32_t i = 0;
- uint32_t words;
- words = numBytes / 4u;
- if (numBytes % 4u)
- {
- words++;
- }
- if (words > blockSize / 4u)
- {
- words = blockSize / 4u;
- }
- while (i < words)
- {
- if (0U == (base->FIFOSTA & LTC_FIFOSTA_IFF_MASK))
- {
- /* Copy data to the input FIFO. */
- base->IFIFO = blk->w[i++];
- }
- }
- }
- static void ltc_hash_move_to_ififo(ltc_hash_ctx_internal_t *ctx,
- const uint8_t *data,
- uint32_t dataSize,
- uint32_t blockSize)
- {
- ltc_hash_block_t blkZero;
- uint32_t i;
- for (i = 0; i < ARRAY_SIZE(blkZero.w); i++)
- {
- blkZero.w[i] = 0;
- }
- while (dataSize)
- {
- if (dataSize >= blockSize)
- {
- ltc_memcpy(&ctx->blk, data, blockSize);
- ltc_hash_block_to_ififo(ctx->base, &ctx->blk, blockSize, blockSize);
- dataSize -= blockSize;
- data += blockSize;
- }
- else
- {
- /* last incomplete 16/64-bytes block of this message chunk */
- ltc_memcpy(&ctx->blk, &blkZero, sizeof(ctx->blk));
- ltc_memcpy(&ctx->blk, data, dataSize);
- ctx->blksz = dataSize;
- dataSize = 0;
- }
- }
- }
- static status_t ltc_hash_merge_and_flush_buf(ltc_hash_ctx_internal_t *ctx,
- const uint8_t *input,
- uint32_t inputSize,
- ltc_mode_t modeReg,
- uint32_t blockSize,
- uint32_t *consumedSize)
- {
- uint32_t sz;
- LTC_Type *base;
- status_t status = kStatus_Success;
- base = ctx->base;
- sz = 0;
- if (ctx->blksz)
- {
- sz = blockSize - ctx->blksz;
- if (sz > inputSize)
- {
- sz = inputSize;
- }
- ltc_memcpy(ctx->blk.b + ctx->blksz, input, sz);
- input += sz;
- inputSize -= sz;
- ctx->blksz += sz;
- if (ctx->blksz == blockSize)
- {
- base->DS = blockSize;
- ltc_hash_block_to_ififo(base, &ctx->blk, blockSize, blockSize);
- ctx->blksz = 0;
- status = ltc_wait(base);
- if (kStatus_Success != status)
- {
- return status;
- }
- /* if there is still inputSize left, make sure LTC alg.state is set to UPDATE and continue */
- if (inputSize)
- {
- /* set algorithm state to UPDATE */
- modeReg &= ~LTC_MD_AS_MASK;
- modeReg |= kLTC_ModeUpdate;
- base->MD = modeReg;
- }
- }
- }
- if (consumedSize)
- {
- *consumedSize = sz;
- }
- return status;
- }
- static status_t ltc_hash_move_rest_to_context(
- ltc_hash_ctx_internal_t *ctx, const uint8_t *data, uint32_t dataSize, ltc_mode_t modeReg, uint32_t blockSize)
- {
- status_t status = kStatus_Success;
- ltc_hash_block_t blkZero;
- uint32_t i;
- /* make blkZero clear */
- for (i = 0; i < ARRAY_SIZE(blkZero.w); i++)
- {
- blkZero.w[i] = 0;
- }
- while (dataSize)
- {
- if (dataSize > blockSize)
- {
- dataSize -= blockSize;
- data += blockSize;
- }
- else
- {
- if (dataSize + ctx->blksz > blockSize)
- {
- uint32_t sz = 0;
- status = ltc_hash_merge_and_flush_buf(ctx, data, dataSize, modeReg, blockSize, &sz);
- if (kStatus_Success != status)
- {
- return status;
- }
- data += sz;
- dataSize -= sz;
- }
- /* last incomplete 16/64-bytes block of this message chunk */
- ltc_memcpy(&ctx->blk, &blkZero, blockSize);
- ltc_memcpy(&ctx->blk, data, dataSize);
- ctx->blksz = dataSize;
- dataSize = 0;
- }
- }
- return status;
- }
- static status_t ltc_hash_process_input_data(ltc_hash_ctx_internal_t *ctx,
- const uint8_t *input,
- uint32_t inputSize,
- ltc_mode_t modeReg)
- {
- uint32_t sz = 0;
- LTC_Type *base;
- uint32_t blockSize = 0;
- status_t status = kStatus_Success;
- blockSize = ltc_hash_get_block_size(ctx->algo);
- if (blockSize == 0)
- {
- return kStatus_Fail;
- }
- base = ctx->base;
- /* fill context struct blk and flush to LTC ififo in case it is full block */
- status = ltc_hash_merge_and_flush_buf(ctx, input, inputSize, modeReg, blockSize, &sz);
- if (kStatus_Success != status)
- {
- return status;
- }
- input += sz;
- inputSize -= sz;
- /* if there is still more than or equal to 64 bytes, move each 64 bytes through LTC */
- sz = LTC_DS_DS_MASK + 1u - LTC_HASH_BLOCK_SIZE;
- while (inputSize)
- {
- if (inputSize < sz)
- {
- uint32_t lastSize;
- lastSize = inputSize % blockSize;
- if (lastSize == 0)
- {
- lastSize = blockSize;
- }
- inputSize -= lastSize;
- if (inputSize)
- {
- /* move all complete blocks to ififo. */
- base->DS = inputSize;
- ltc_hash_move_to_ififo(ctx, input, inputSize, blockSize);
- status = ltc_wait(base);
- if (kStatus_Success != status)
- {
- return status;
- }
- input += inputSize;
- }
- /* keep last (in)complete 16-bytes block in context struct. */
- /* when 3rd argument of cmac_move_to_ififo() is <= 16 bytes, it only stores the data to context struct */
- status = ltc_hash_move_rest_to_context(ctx, input, lastSize, modeReg, blockSize);
- if (kStatus_Success != status)
- {
- return status;
- }
- inputSize = 0;
- }
- else
- {
- base->DS = sz;
- ltc_hash_move_to_ififo(ctx, input, sz, blockSize);
- inputSize -= sz;
- input += sz;
- status = ltc_wait(base);
- if (kStatus_Success != status)
- {
- return status;
- }
- /* set algorithm state to UPDATE */
- modeReg &= ~LTC_MD_AS_MASK;
- modeReg |= kLTC_ModeUpdate;
- base->MD = modeReg;
- }
- } /* end while */
- return status;
- }
- /*******************************************************************************
- * HASH Code public
- ******************************************************************************/
- status_t LTC_HASH_Init(LTC_Type *base, ltc_hash_ctx_t *ctx, ltc_hash_algo_t algo, const uint8_t *key, uint32_t keySize)
- {
- status_t ret;
- ltc_hash_ctx_internal_t *ctxInternal;
- uint32_t i;
- ret = ltc_hash_check_input_args(base, ctx, algo, key, keySize);
- if (ret != kStatus_Success)
- {
- return ret;
- }
- /* set algorithm in context struct for later use */
- ctxInternal = (ltc_hash_ctx_internal_t *)ctx;
- ctxInternal->algo = algo;
- for (i = 0; i < kLTC_HashCtxNumWords; i++)
- {
- ctxInternal->word[i] = 0u;
- }
- /* Steps required only using AES engine */
- if (ltc_hash_alg_is_cmac(algo))
- {
- /* store input key and key length in context struct for later use */
- ctxInternal->word[kLTC_HashCtxKeySize] = keySize;
- ltc_memcpy(&ctxInternal->word[kLTC_HashCtxKeyStartIdx], key, keySize);
- }
- ctxInternal->blksz = 0u;
- for (i = 0; i < sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); i++)
- {
- ctxInternal->blk.w[0] = 0u;
- }
- ctxInternal->state = kLTC_HashInit;
- ctxInternal->base = base;
- return kStatus_Success;
- }
- status_t LTC_HASH_Update(ltc_hash_ctx_t *ctx, const uint8_t *input, uint32_t inputSize)
- {
- bool isUpdateState;
- ltc_mode_t modeReg = 0; /* read and write LTC mode register */
- LTC_Type *base;
- status_t status;
- ltc_hash_ctx_internal_t *ctxInternal;
- uint32_t blockSize;
- ctxInternal = (ltc_hash_ctx_internal_t *)ctx;
- status = ltc_hash_check_context(ctxInternal, input);
- if (kStatus_Success != status)
- {
- return status;
- }
- base = ctxInternal->base;
- blockSize = ltc_hash_get_block_size(ctxInternal->algo);
- /* if we are still less than 64 bytes, keep only in context */
- if ((ctxInternal->blksz + inputSize) <= blockSize)
- {
- ltc_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize);
- ctxInternal->blksz += inputSize;
- return status;
- }
- else
- {
- isUpdateState = ctxInternal->state == kLTC_HashUpdate;
- if (ctxInternal->state == kLTC_HashInit)
- {
- /* set LTC mode register to INITIALIZE job */
- ltc_hash_engine_init(ctxInternal);
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- if (ltc_hash_alg_is_cmac(ctxInternal->algo))
- {
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- ctxInternal->state = kLTC_HashUpdate;
- isUpdateState = true;
- base->DS = 0u;
- status = ltc_wait(base);
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- }
- else
- {
- /* Set the proper block and algorithm mode. */
- modeReg = ltc_hash_algo2mode(ctxInternal->algo, kLTC_ModeInit, NULL);
- base->MD = modeReg;
- ctxInternal->state = kLTC_HashUpdate;
- status = ltc_hash_process_input_data(ctxInternal, input, inputSize, modeReg);
- ltc_hash_save_context(ctxInternal);
- }
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- }
- else if (isUpdateState)
- {
- /* restore LTC context from context struct */
- ltc_hash_restore_context(ctxInternal);
- }
- else
- {
- /* nothing special at this place */
- }
- }
- if (kStatus_Success != status)
- {
- return status;
- }
- if (isUpdateState)
- {
- /* set LTC mode register to UPDATE job */
- ltc_hash_prepare_context_switch(base);
- base->CW = kLTC_ClearDataSize;
- modeReg = ltc_hash_algo2mode(ctxInternal->algo, kLTC_ModeUpdate, NULL);
- base->MD = modeReg;
- /* process input data and save LTC context to context structure */
- status = ltc_hash_process_input_data(ctxInternal, input, inputSize, modeReg);
- ltc_hash_save_context(ctxInternal);
- }
- ltc_clear_all(base, false);
- return status;
- }
- status_t LTC_HASH_Finish(ltc_hash_ctx_t *ctx, uint8_t *output, uint32_t *outputSize)
- {
- ltc_mode_t modeReg; /* read and write LTC mode register */
- LTC_Type *base;
- uint32_t algOutSize = 0;
- status_t status;
- ltc_hash_ctx_internal_t *ctxInternal;
- uint32_t *ctxW;
- uint32_t i;
- ctxInternal = (ltc_hash_ctx_internal_t *)ctx;
- status = ltc_hash_check_context(ctxInternal, output);
- if (kStatus_Success != status)
- {
- return status;
- }
- base = ctxInternal->base;
- ltc_hash_prepare_context_switch(base);
- base->CW = kLTC_ClearDataSize;
- if (ctxInternal->state == kLTC_HashInit)
- {
- ltc_hash_engine_init(ctxInternal);
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- if (ltc_hash_alg_is_cmac(ctxInternal->algo))
- {
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- base->DS = 0u;
- status = ltc_wait(base);
- if (kStatus_Success != status)
- {
- return status;
- }
- modeReg = ltc_hash_algo2mode(ctxInternal->algo, kLTC_ModeFinalize, &algOutSize);
- #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
- }
- else
- {
- modeReg = ltc_hash_algo2mode(ctxInternal->algo, kLTC_ModeInitFinal, &algOutSize);
- }
- #endif /* FSL_FEATURE_LTC_HAS_SHA */
- base->MD = modeReg;
- }
- else
- {
- modeReg = ltc_hash_algo2mode(ctxInternal->algo, kLTC_ModeFinalize, &algOutSize);
- base->MD = modeReg;
- /* restore LTC context from context struct */
- ltc_hash_restore_context(ctxInternal);
- }
- /* flush message last incomplete block, if there is any, or write zero to data size register. */
- base->DS = ctxInternal->blksz;
- ltc_hash_block_to_ififo(base, &ctxInternal->blk, ctxInternal->blksz, ltc_hash_get_block_size(ctxInternal->algo));
- /* Wait for finish of the encryption */
- status = ltc_wait(base);
- if (outputSize)
- {
- if (algOutSize < *outputSize)
- {
- *outputSize = algOutSize;
- }
- else
- {
- algOutSize = *outputSize;
- }
- }
- ltc_get_context(base, &output[0], algOutSize, 0u);
- ctxW = (uint32_t *)ctx;
- for (i = 0; i < LTC_HASH_CTX_SIZE; i++)
- {
- ctxW[i] = 0u;
- }
- ltc_clear_all(base, false);
- return status;
- }
- status_t LTC_HASH(LTC_Type *base,
- ltc_hash_algo_t algo,
- const uint8_t *input,
- uint32_t inputSize,
- const uint8_t *key,
- uint32_t keySize,
- uint8_t *output,
- uint32_t *outputSize)
- {
- status_t status;
- ltc_hash_ctx_t ctx;
- status = LTC_HASH_Init(base, &ctx, algo, key, keySize);
- if (status != kStatus_Success)
- {
- return status;
- }
- status = LTC_HASH_Update(&ctx, input, inputSize);
- if (status != kStatus_Success)
- {
- return status;
- }
- status = LTC_HASH_Finish(&ctx, output, outputSize);
- return status;
- }
- /*******************************************************************************
- * PKHA Code static
- ******************************************************************************/
- #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
- static status_t ltc_pkha_clear_regabne(LTC_Type *base, bool A, bool B, bool N, bool E)
- {
- ltc_mode_t mode;
- /* Set the PKHA algorithm and the appropriate function. */
- mode = (uint32_t)kLTC_AlgorithmPKHA | 1U;
- /* Set ram area to clear. Clear all. */
- if (A)
- {
- mode |= 1U << 19U;
- }
- if (B)
- {
- mode |= 1U << 18U;
- }
- if (N)
- {
- mode |= 1U << 16U;
- }
- if (E)
- {
- mode |= 1U << 17U;
- }
- /* Write the mode register to the hardware.
- * NOTE: This will begin the operation. */
- base->MDPK = mode;
- /* Wait for 'done' */
- return ltc_wait(base);
- }
- static void ltc_pkha_default_parms(ltc_pkha_mode_params_t *params)
- {
- params->func = (ltc_pkha_func_t)0;
- params->arithType = kLTC_PKHA_IntegerArith;
- params->montFormIn = kLTC_PKHA_NormalValue;
- params->montFormOut = kLTC_PKHA_NormalValue;
- params->srcReg = kLTC_PKHA_RegAll;
- params->srcQuad = kLTC_PKHA_Quad0;
- params->dstReg = kLTC_PKHA_RegAll;
- params->dstQuad = kLTC_PKHA_Quad0;
- params->equalTime = kLTC_PKHA_NoTimingEqualized;
- params->r2modn = kLTC_PKHA_CalcR2;
- }
- static void ltc_pkha_write_word(LTC_Type *base, ltc_pkha_reg_area_t reg, uint8_t index, uint32_t data)
- {
- switch (reg)
- {
- case kLTC_PKHA_RegA:
- base->PKA[index] = data;
- break;
- case kLTC_PKHA_RegB:
- base->PKB[index] = data;
- break;
- case kLTC_PKHA_RegN:
- base->PKN[index] = data;
- break;
- case kLTC_PKHA_RegE:
- base->PKE[index] = data;
- break;
- default:
- break;
- }
- }
- static uint32_t ltc_pkha_read_word(LTC_Type *base, ltc_pkha_reg_area_t reg, uint8_t index)
- {
- uint32_t retval;
- switch (reg)
- {
- case kLTC_PKHA_RegA:
- retval = base->PKA[index];
- break;
- case kLTC_PKHA_RegB:
- retval = base->PKB[index];
- break;
- case kLTC_PKHA_RegN:
- retval = base->PKN[index];
- break;
- case kLTC_PKHA_RegE:
- retval = base->PKE[index];
- break;
- default:
- retval = 0;
- break;
- }
- return retval;
- }
- static status_t ltc_pkha_write_reg(
- LTC_Type *base, ltc_pkha_reg_area_t reg, uint8_t quad, const uint8_t *data, uint16_t dataSize)
- {
- /* Select the word-based start index for each quadrant of 64 bytes. */
- uint8_t startIndex = (quad * 16u);
- uint32_t outWord;
- while (dataSize > 0)
- {
- if (dataSize >= sizeof(uint32_t))
- {
- ltc_pkha_write_word(base, reg, startIndex++, ltc_get_word_from_unaligned(data));
- dataSize -= sizeof(uint32_t);
- data += sizeof(uint32_t);
- }
- else /* (dataSize > 0) && (dataSize < 4) */
- {
- outWord = 0;
- ltc_memcpy(&outWord, data, dataSize);
- ltc_pkha_write_word(base, reg, startIndex, outWord);
- dataSize = 0;
- }
- }
- return kStatus_Success;
- }
- static void ltc_pkha_read_reg(LTC_Type *base, ltc_pkha_reg_area_t reg, uint8_t quad, uint8_t *data, uint16_t dataSize)
- {
- /* Select the word-based start index for each quadrant of 64 bytes. */
- uint8_t startIndex = (quad * 16u);
- uint16_t calcSize;
- uint32_t word;
- while (dataSize > 0)
- {
- word = ltc_pkha_read_word(base, reg, startIndex++);
- calcSize = (dataSize >= sizeof(uint32_t)) ? sizeof(uint32_t) : dataSize;
- ltc_memcpy(data, &word, calcSize);
- data += calcSize;
- dataSize -= calcSize;
- }
- }
- static void ltc_pkha_init_data(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *B,
- uint16_t sizeB,
- const uint8_t *N,
- uint16_t sizeN,
- const uint8_t *E,
- uint16_t sizeE)
- {
- uint32_t clearMask = kLTC_ClearMode; /* clear Mode Register */
- /* Clear internal register states. */
- if (sizeA)
- {
- clearMask |= kLTC_ClearPkhaSizeA;
- }
- if (sizeB)
- {
- clearMask |= kLTC_ClearPkhaSizeB;
- }
- if (sizeN)
- {
- clearMask |= kLTC_ClearPkhaSizeN;
- }
- if (sizeE)
- {
- clearMask |= kLTC_ClearPkhaSizeE;
- }
- base->CW = clearMask;
- base->STA = kLTC_StatusDoneIsr;
- ltc_pkha_clear_regabne(base, A, B, N, E);
- /* Write register sizes. */
- /* Write modulus (N) and A and B register arguments. */
- if (sizeN)
- {
- base->PKNSZ = sizeN;
- if (N)
- {
- ltc_pkha_write_reg(base, kLTC_PKHA_RegN, 0, N, sizeN);
- }
- }
- if (sizeA)
- {
- base->PKASZ = sizeA;
- if (A)
- {
- ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 0, A, sizeA);
- }
- }
- if (sizeB)
- {
- base->PKBSZ = sizeB;
- if (B)
- {
- ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 0, B, sizeB);
- }
- }
- if (sizeE)
- {
- base->PKESZ = sizeE;
- if (E)
- {
- ltc_pkha_write_reg(base, kLTC_PKHA_RegE, 0, E, sizeE);
- }
- }
- }
- static void ltc_pkha_mode_set_src_reg_copy(ltc_mode_t *outMode, ltc_pkha_reg_area_t reg)
- {
- int i = 0;
- do
- {
- reg = (ltc_pkha_reg_area_t)(((uint32_t)reg) >> 1u);
- i++;
- } while (reg);
- i = 4 - i;
- /* Source register must not be E. */
- if (i != 2)
- {
- *outMode |= ((uint32_t)i << 17u);
- }
- }
- static void ltc_pkha_mode_set_dst_reg_copy(ltc_mode_t *outMode, ltc_pkha_reg_area_t reg)
- {
- int i = 0;
- do
- {
- reg = (ltc_pkha_reg_area_t)(((uint32_t)reg) >> 1u);
- i++;
- } while (reg);
- i = 4 - i;
- *outMode |= ((uint32_t)i << 10u);
- }
- static void ltc_pkha_mode_set_src_seg_copy(ltc_mode_t *outMode, const ltc_pkha_quad_area_t quad)
- {
- *outMode |= ((uint32_t)quad << 8u);
- }
- static void ltc_pkha_mode_set_dst_seg_copy(ltc_mode_t *outMode, const ltc_pkha_quad_area_t quad)
- {
- *outMode |= ((uint32_t)quad << 6u);
- }
- /*!
- * @brief Starts the PKHA operation.
- *
- * This function starts an operation configured by the params parameter.
- *
- * @param base LTC peripheral base address
- * @param params Configuration structure containing all settings required for PKHA operation.
- */
- static status_t ltc_pkha_init_mode(LTC_Type *base, const ltc_pkha_mode_params_t *params)
- {
- ltc_mode_t modeReg;
- status_t retval;
- /* Set the PKHA algorithm and the appropriate function. */
- modeReg = kLTC_AlgorithmPKHA;
- modeReg |= (uint32_t)params->func;
- if ((params->func == kLTC_PKHA_CopyMemSizeN) || (params->func == kLTC_PKHA_CopyMemSizeSrc))
- {
- /* Set source and destination registers and quads. */
- ltc_pkha_mode_set_src_reg_copy(&modeReg, params->srcReg);
- ltc_pkha_mode_set_dst_reg_copy(&modeReg, params->dstReg);
- ltc_pkha_mode_set_src_seg_copy(&modeReg, params->srcQuad);
- ltc_pkha_mode_set_dst_seg_copy(&modeReg, params->dstQuad);
- }
- else
- {
- /* Set the arithmetic type - integer or binary polynomial (F2m). */
- modeReg |= ((uint32_t)params->arithType << 17u);
- /* Set to use Montgomery form of inputs and/or outputs. */
- modeReg |= ((uint32_t)params->montFormIn << 19u);
- modeReg |= ((uint32_t)params->montFormOut << 18u);
- /* Set to use pre-computed R2modN */
- modeReg |= ((uint32_t)params->r2modn << 16u);
- }
- modeReg |= ((uint32_t)params->equalTime << 10u);
- /* Write the mode register to the hardware.
- * NOTE: This will begin the operation. */
- base->MDPK = modeReg;
- retval = ltc_wait(base);
- return (retval);
- }
- static status_t ltc_pkha_modR2(
- LTC_Type *base, const uint8_t *N, uint16_t sizeN, uint8_t *result, uint16_t *resultSize, ltc_pkha_f2m_t arithType)
- {
- status_t status;
- ltc_pkha_mode_params_t params;
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithModR2;
- params.arithType = arithType;
- ltc_pkha_init_data(base, NULL, 0, NULL, 0, N, sizeN, NULL, 0);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the result and size from register B0. */
- if (resultSize && result)
- {
- *resultSize = base->PKBSZ;
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize);
- }
- }
- return status;
- }
- static status_t ltc_pkha_modmul(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *B,
- uint16_t sizeB,
- const uint8_t *N,
- uint16_t sizeN,
- uint8_t *result,
- uint16_t *resultSize,
- ltc_pkha_f2m_t arithType,
- ltc_pkha_montgomery_form_t montIn,
- ltc_pkha_montgomery_form_t montOut,
- ltc_pkha_timing_t equalTime)
- {
- ltc_pkha_mode_params_t params;
- status_t status;
- if (arithType == kLTC_PKHA_IntegerArith)
- {
- if (LTC_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
- {
- return (kStatus_InvalidArgument);
- }
- if (LTC_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
- {
- return (kStatus_InvalidArgument);
- }
- }
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithModMul;
- params.arithType = arithType;
- params.montFormIn = montIn;
- params.montFormOut = montOut;
- params.equalTime = equalTime;
- ltc_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the result and size from register B0. */
- if (resultSize && result)
- {
- *resultSize = base->PKBSZ;
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize);
- }
- }
- return status;
- }
- /*******************************************************************************
- * PKHA Code public
- ******************************************************************************/
- int LTC_PKHA_CompareBigNum(const uint8_t *a, size_t sizeA, const uint8_t *b, size_t sizeB)
- {
- int retval = 0;
- /* skip zero msbytes - integer a */
- while ((sizeA) && (0u == a[sizeA - 1]))
- {
- sizeA--;
- }
- /* skip zero msbytes - integer b */
- while ((sizeB) && (0u == b[sizeB - 1]))
- {
- sizeB--;
- }
- if (sizeA > sizeB)
- {
- retval = 1;
- } /* int a has more non-zero bytes, thus it is bigger than b */
- else if (sizeA < sizeB)
- {
- retval = -1;
- } /* int b has more non-zero bytes, thus it is bigger than a */
- else if (sizeA == 0)
- {
- retval = 0;
- } /* sizeA = sizeB = 0 */
- else
- {
- int n;
- int i;
- int val;
- uint32_t equal;
- n = sizeA - 1;
- i = 0;
- equal = 0;
- while (n >= 0)
- {
- uint32_t chXor = a[i] ^ b[i];
- equal |= chXor;
- val = (int)chXor * (a[i] - b[i]);
- if (val < 0)
- {
- *(volatile int*)&retval = -1;
- }
- if (val > 0)
- {
- *(volatile int*)&retval = 1;
- }
- if (val == 0)
- {
- *(volatile int*)&val = 1;
- }
- i++;
- n--;
- }
- if (0 == equal)
- {
- retval = 0;
- }
- }
- return (retval);
- }
- status_t LTC_PKHA_NormalToMontgomery(LTC_Type *base,
- const uint8_t *N,
- uint16_t sizeN,
- uint8_t *A,
- uint16_t *sizeA,
- uint8_t *B,
- uint16_t *sizeB,
- uint8_t *R2,
- uint16_t *sizeR2,
- ltc_pkha_timing_t equalTime,
- ltc_pkha_f2m_t arithType)
- {
- status_t status;
- /* need to convert our Integer inputs into Montgomery format */
- if (N && sizeN && R2 && sizeR2)
- {
- /* 1. R2 = MOD_R2(N) */
- status = ltc_pkha_modR2(base, N, sizeN, R2, sizeR2, arithType);
- if (status != kStatus_Success)
- {
- return status;
- }
- /* 2. A(Montgomery) = MOD_MUL_IM_OM(A, R2, N) */
- if (A && sizeA)
- {
- status = ltc_pkha_modmul(base, A, *sizeA, R2, *sizeR2, N, sizeN, A, sizeA, arithType,
- kLTC_PKHA_MontgomeryFormat, kLTC_PKHA_MontgomeryFormat, equalTime);
- if (status != kStatus_Success)
- {
- return status;
- }
- }
- /* 2. B(Montgomery) = MOD_MUL_IM_OM(B, R2, N) */
- if (B && sizeB)
- {
- status = ltc_pkha_modmul(base, B, *sizeB, R2, *sizeR2, N, sizeN, B, sizeB, arithType,
- kLTC_PKHA_MontgomeryFormat, kLTC_PKHA_MontgomeryFormat, equalTime);
- if (status != kStatus_Success)
- {
- return status;
- }
- }
- ltc_clear_all(base, true);
- }
- else
- {
- status = kStatus_InvalidArgument;
- }
- return status;
- }
- status_t LTC_PKHA_MontgomeryToNormal(LTC_Type *base,
- const uint8_t *N,
- uint16_t sizeN,
- uint8_t *A,
- uint16_t *sizeA,
- uint8_t *B,
- uint16_t *sizeB,
- ltc_pkha_timing_t equalTime,
- ltc_pkha_f2m_t arithType)
- {
- uint8_t one = 1;
- status_t status = kStatus_InvalidArgument;
- /* A = MOD_MUL_IM_OM(A(Montgomery), 1, N) */
- if (A && sizeA)
- {
- status = ltc_pkha_modmul(base, A, *sizeA, &one, sizeof(one), N, sizeN, A, sizeA, arithType,
- kLTC_PKHA_MontgomeryFormat, kLTC_PKHA_MontgomeryFormat, equalTime);
- if (kStatus_Success != status)
- {
- return status;
- }
- }
- /* B = MOD_MUL_IM_OM(B(Montgomery), 1, N) */
- if (B && sizeB)
- {
- status = ltc_pkha_modmul(base, B, *sizeB, &one, sizeof(one), N, sizeN, B, sizeB, arithType,
- kLTC_PKHA_MontgomeryFormat, kLTC_PKHA_MontgomeryFormat, equalTime);
- if (kStatus_Success != status)
- {
- return status;
- }
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ModAdd(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *B,
- uint16_t sizeB,
- const uint8_t *N,
- uint16_t sizeN,
- uint8_t *result,
- uint16_t *resultSize,
- ltc_pkha_f2m_t arithType)
- {
- ltc_pkha_mode_params_t params;
- status_t status;
- if (arithType == kLTC_PKHA_IntegerArith)
- {
- if (LTC_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
- {
- return (kStatus_InvalidArgument);
- }
- if (LTC_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
- {
- return (kStatus_InvalidArgument);
- }
- }
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithModAdd;
- params.arithType = arithType;
- ltc_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the result and size from register B0. */
- if (resultSize && result)
- {
- *resultSize = base->PKBSZ;
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize);
- }
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ModSub1(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *B,
- uint16_t sizeB,
- const uint8_t *N,
- uint16_t sizeN,
- uint8_t *result,
- uint16_t *resultSize)
- {
- ltc_pkha_mode_params_t params;
- status_t status;
- if (LTC_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
- {
- return (kStatus_InvalidArgument);
- }
- if (LTC_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
- {
- return (kStatus_InvalidArgument);
- }
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithModSub1;
- ltc_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the result and size from register B0. */
- if (resultSize && result)
- {
- *resultSize = base->PKBSZ;
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize);
- }
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ModSub2(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *B,
- uint16_t sizeB,
- const uint8_t *N,
- uint16_t sizeN,
- uint8_t *result,
- uint16_t *resultSize)
- {
- ltc_pkha_mode_params_t params;
- status_t status;
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithModSub2;
- ltc_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the result and size from register B0. */
- if (resultSize && result)
- {
- *resultSize = base->PKBSZ;
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize);
- }
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ModMul(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *B,
- uint16_t sizeB,
- const uint8_t *N,
- uint16_t sizeN,
- uint8_t *result,
- uint16_t *resultSize,
- ltc_pkha_f2m_t arithType,
- ltc_pkha_montgomery_form_t montIn,
- ltc_pkha_montgomery_form_t montOut,
- ltc_pkha_timing_t equalTime)
- {
- status_t status;
- status =
- ltc_pkha_modmul(base, A, sizeA, B, sizeB, N, sizeN, result, resultSize, arithType, montIn, montOut, equalTime);
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ModExp(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *N,
- uint16_t sizeN,
- const uint8_t *E,
- uint16_t sizeE,
- uint8_t *result,
- uint16_t *resultSize,
- ltc_pkha_f2m_t arithType,
- ltc_pkha_montgomery_form_t montIn,
- ltc_pkha_timing_t equalTime)
- {
- ltc_pkha_mode_params_t params;
- status_t status;
- if (arithType == kLTC_PKHA_IntegerArith)
- {
- if (LTC_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
- {
- return (kStatus_InvalidArgument);
- }
- }
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithModExp;
- params.arithType = arithType;
- params.montFormIn = montIn;
- params.equalTime = equalTime;
- ltc_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, E, sizeE);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the result and size from register B0. */
- if (resultSize && result)
- {
- *resultSize = base->PKBSZ;
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize);
- }
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ModRed(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *N,
- uint16_t sizeN,
- uint8_t *result,
- uint16_t *resultSize,
- ltc_pkha_f2m_t arithType)
- {
- ltc_pkha_mode_params_t params;
- status_t status;
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithModRed;
- params.arithType = arithType;
- ltc_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the result and size from register B0. */
- if (resultSize && result)
- {
- *resultSize = base->PKBSZ;
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize);
- }
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ModInv(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *N,
- uint16_t sizeN,
- uint8_t *result,
- uint16_t *resultSize,
- ltc_pkha_f2m_t arithType)
- {
- ltc_pkha_mode_params_t params;
- status_t status;
- /* A must be less than N -> LTC_PKHA_CompareBigNum() must return -1 */
- if (arithType == kLTC_PKHA_IntegerArith)
- {
- if (LTC_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
- {
- return (kStatus_InvalidArgument);
- }
- }
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithModInv;
- params.arithType = arithType;
- ltc_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the result and size from register B0. */
- if (resultSize && result)
- {
- *resultSize = base->PKBSZ;
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize);
- }
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ModR2(
- LTC_Type *base, const uint8_t *N, uint16_t sizeN, uint8_t *result, uint16_t *resultSize, ltc_pkha_f2m_t arithType)
- {
- status_t status;
- status = ltc_pkha_modR2(base, N, sizeN, result, resultSize, arithType);
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_GCD(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *N,
- uint16_t sizeN,
- uint8_t *result,
- uint16_t *resultSize,
- ltc_pkha_f2m_t arithType)
- {
- ltc_pkha_mode_params_t params;
- status_t status;
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithGcd;
- params.arithType = arithType;
- ltc_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the result and size from register B0. */
- if (resultSize && result)
- {
- *resultSize = base->PKBSZ;
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, result, *resultSize);
- }
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_PrimalityTest(LTC_Type *base,
- const uint8_t *A,
- uint16_t sizeA,
- const uint8_t *B,
- uint16_t sizeB,
- const uint8_t *N,
- uint16_t sizeN,
- bool *res)
- {
- uint8_t result;
- ltc_pkha_mode_params_t params;
- status_t status;
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithPrimalityTest;
- ltc_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 0, &result, 1);
- *res = (bool)result;
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ECC_PointAdd(LTC_Type *base,
- const ltc_pkha_ecc_point_t *A,
- const ltc_pkha_ecc_point_t *B,
- const uint8_t *N,
- const uint8_t *R2modN,
- const uint8_t *aCurveParam,
- const uint8_t *bCurveParam,
- uint8_t size,
- ltc_pkha_f2m_t arithType,
- ltc_pkha_ecc_point_t *result)
- {
- ltc_pkha_mode_params_t params;
- uint32_t clearMask;
- status_t status;
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithEccAdd;
- params.arithType = arithType;
- params.r2modn = R2modN ? kLTC_PKHA_InputR2 : kLTC_PKHA_CalcR2;
- clearMask = kLTC_ClearMode;
- /* Clear internal register states. */
- clearMask |= kLTC_ClearPkhaSizeA;
- clearMask |= kLTC_ClearPkhaSizeB;
- clearMask |= kLTC_ClearPkhaSizeN;
- clearMask |= kLTC_ClearPkhaSizeE;
- base->CW = clearMask;
- base->STA = kLTC_StatusDoneIsr;
- ltc_pkha_clear_regabne(base, true, true, true, false);
- /* sizeN should be less than 64 bytes. */
- base->PKNSZ = size;
- ltc_pkha_write_reg(base, kLTC_PKHA_RegN, 0, N, size);
- base->PKASZ = size;
- ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 0, A->X, size);
- ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 1, A->Y, size);
- ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 3, aCurveParam, size);
- base->PKBSZ = size;
- ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 0, bCurveParam, size);
- ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 1, B->X, size);
- ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 2, B->Y, size);
- if (R2modN)
- {
- ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 3, R2modN, size);
- }
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 1, result->X, size);
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 2, result->Y, size);
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ECC_PointDouble(LTC_Type *base,
- const ltc_pkha_ecc_point_t *B,
- const uint8_t *N,
- const uint8_t *aCurveParam,
- const uint8_t *bCurveParam,
- uint8_t size,
- ltc_pkha_f2m_t arithType,
- ltc_pkha_ecc_point_t *result)
- {
- ltc_pkha_mode_params_t params;
- uint32_t clearMask;
- status_t status;
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithEccDouble;
- params.arithType = arithType;
- clearMask = kLTC_ClearMode;
- /* Clear internal register states. */
- clearMask |= kLTC_ClearPkhaSizeA;
- clearMask |= kLTC_ClearPkhaSizeB;
- clearMask |= kLTC_ClearPkhaSizeN;
- clearMask |= kLTC_ClearPkhaSizeE;
- base->CW = clearMask;
- base->STA = kLTC_StatusDoneIsr;
- ltc_pkha_clear_regabne(base, true, true, true, false);
- /* sizeN should be less than 64 bytes. */
- base->PKNSZ = size;
- ltc_pkha_write_reg(base, kLTC_PKHA_RegN, 0, N, size);
- base->PKASZ = size;
- ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 3, aCurveParam, size);
- base->PKBSZ = size;
- ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 0, bCurveParam, size);
- ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 1, B->X, size);
- ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 2, B->Y, size);
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 1, result->X, size);
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 2, result->Y, size);
- }
- ltc_clear_all(base, true);
- return status;
- }
- status_t LTC_PKHA_ECC_PointMul(LTC_Type *base,
- const ltc_pkha_ecc_point_t *A,
- const uint8_t *E,
- uint8_t sizeE,
- const uint8_t *N,
- const uint8_t *R2modN,
- const uint8_t *aCurveParam,
- const uint8_t *bCurveParam,
- uint8_t size,
- ltc_pkha_timing_t equalTime,
- ltc_pkha_f2m_t arithType,
- ltc_pkha_ecc_point_t *result,
- bool *infinity)
- {
- ltc_pkha_mode_params_t params;
- uint32_t clearMask;
- status_t status;
- ltc_pkha_default_parms(¶ms);
- params.func = kLTC_PKHA_ArithEccMul;
- params.equalTime = equalTime;
- params.arithType = arithType;
- params.r2modn = R2modN ? kLTC_PKHA_InputR2 : kLTC_PKHA_CalcR2;
- clearMask = kLTC_ClearMode;
- /* Clear internal register states. */
- clearMask |= kLTC_ClearPkhaSizeA;
- clearMask |= kLTC_ClearPkhaSizeB;
- clearMask |= kLTC_ClearPkhaSizeN;
- clearMask |= kLTC_ClearPkhaSizeE;
- base->CW = clearMask;
- base->STA = kLTC_StatusDoneIsr;
- ltc_pkha_clear_regabne(base, true, true, true, true);
- /* sizeN should be less than 64 bytes. */
- base->PKNSZ = size;
- ltc_pkha_write_reg(base, kLTC_PKHA_RegN, 0, N, size);
- base->PKESZ = sizeE;
- ltc_pkha_write_reg(base, kLTC_PKHA_RegE, 0, E, sizeE);
- base->PKASZ = size;
- ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 0, A->X, size);
- ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 1, A->Y, size);
- ltc_pkha_write_reg(base, kLTC_PKHA_RegA, 3, aCurveParam, size);
- base->PKBSZ = size;
- ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 0, bCurveParam, size);
- if (R2modN)
- {
- ltc_pkha_write_reg(base, kLTC_PKHA_RegB, 1, R2modN, size);
- }
- status = ltc_pkha_init_mode(base, ¶ms);
- if (status == kStatus_Success)
- {
- /* Read the data from the result register into place. */
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 1, result->X, size);
- ltc_pkha_read_reg(base, kLTC_PKHA_RegB, 2, result->Y, size);
- if (infinity)
- {
- *infinity = (bool)(base->STA & kLTC_StatusPublicKeyOpZero);
- }
- }
- ltc_clear_all(base, true);
- return status;
- }
- #endif /* FSL_FEATURE_LTC_HAS_PKHA */
|