123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407 |
- /* evp.c
- *
- * Copyright (C) 2006-2022 wolfSSL Inc.
- *
- * This file is part of wolfSSL.
- *
- * wolfSSL is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * wolfSSL is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <wolfssl/wolfcrypt/settings.h>
- #if !defined(WOLFSSL_EVP_INCLUDED)
- #ifndef WOLFSSL_IGNORE_FILE_WARN
- #warning evp.c does not need to be compiled separately from ssl.c
- #endif
- #elif defined(WOLFCRYPT_ONLY)
- #else
- #if defined(OPENSSL_EXTRA)
- #if !defined(HAVE_PKCS7) && \
- ((defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
- (HAVE_FIPS_VERSION == 2)) || defined(HAVE_SELFTEST))
- #include <wolfssl/wolfcrypt/aes.h>
- #endif
- #include <wolfssl/openssl/ecdsa.h>
- #include <wolfssl/openssl/evp.h>
- #include <wolfssl/openssl/kdf.h>
- #include <wolfssl/wolfcrypt/integer.h>
- #ifndef NO_AES
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- #ifdef WOLFSSL_AES_128
- static const char EVP_AES_128_CBC[] = "AES-128-CBC";
- #endif
- #ifdef WOLFSSL_AES_192
- static const char EVP_AES_192_CBC[] = "AES-192-CBC";
- #endif
- #ifdef WOLFSSL_AES_256
- static const char EVP_AES_256_CBC[] = "AES-256-CBC";
- #endif
- #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
- #ifdef WOLFSSL_AES_OFB
- #ifdef WOLFSSL_AES_128
- static const char EVP_AES_128_OFB[] = "AES-128-OFB";
- #endif
- #ifdef WOLFSSL_AES_192
- static const char EVP_AES_192_OFB[] = "AES-192-OFB";
- #endif
- #ifdef WOLFSSL_AES_256
- static const char EVP_AES_256_OFB[] = "AES-256-OFB";
- #endif
- #endif /* WOLFSSL_AES_OFB */
- #ifdef WOLFSSL_AES_XTS
- #ifdef WOLFSSL_AES_128
- static const char EVP_AES_128_XTS[] = "AES-128-XTS";
- #endif
- #ifdef WOLFSSL_AES_256
- static const char EVP_AES_256_XTS[] = "AES-256-XTS";
- #endif
- #endif /* WOLFSSL_AES_XTS */
- #ifdef WOLFSSL_AES_CFB
- #ifdef WOLFSSL_AES_128
- static const char EVP_AES_128_CFB1[] = "AES-128-CFB1";
- #endif
- #ifdef WOLFSSL_AES_192
- static const char EVP_AES_192_CFB1[] = "AES-192-CFB1";
- #endif
- #ifdef WOLFSSL_AES_256
- static const char EVP_AES_256_CFB1[] = "AES-256-CFB1";
- #endif
- #ifdef WOLFSSL_AES_128
- static const char EVP_AES_128_CFB8[] = "AES-128-CFB8";
- #endif
- #ifdef WOLFSSL_AES_192
- static const char EVP_AES_192_CFB8[] = "AES-192-CFB8";
- #endif
- #ifdef WOLFSSL_AES_256
- static const char EVP_AES_256_CFB8[] = "AES-256-CFB8";
- #endif
- #ifdef WOLFSSL_AES_128
- static const char EVP_AES_128_CFB128[] = "AES-128-CFB128";
- #endif
- #ifdef WOLFSSL_AES_192
- static const char EVP_AES_192_CFB128[] = "AES-192-CFB128";
- #endif
- #ifdef WOLFSSL_AES_256
- static const char EVP_AES_256_CFB128[] = "AES-256-CFB128";
- #endif
- #endif /* WOLFSSL_AES_CFB */
- #ifdef HAVE_AESGCM
- #ifdef WOLFSSL_AES_128
- static const char EVP_AES_128_GCM[] = "AES-128-GCM";
- #endif
- #ifdef WOLFSSL_AES_192
- static const char EVP_AES_192_GCM[] = "AES-192-GCM";
- #endif
- #ifdef WOLFSSL_AES_256
- static const char EVP_AES_256_GCM[] = "AES-256-GCM";
- #endif
- #endif /* HAVE_AESGCM */
- #ifdef WOLFSSL_AES_COUNTER
- #ifdef WOLFSSL_AES_128
- static const char EVP_AES_128_CTR[] = "AES-128-CTR";
- #endif
- #ifdef WOLFSSL_AES_192
- static const char EVP_AES_192_CTR[] = "AES-192-CTR";
- #endif
- #ifdef WOLFSSL_AES_256
- static const char EVP_AES_256_CTR[] = "AES-256-CTR";
- #endif
- #endif
- #ifdef HAVE_AES_ECB
- #ifdef WOLFSSL_AES_128
- static const char EVP_AES_128_ECB[] = "AES-128-ECB";
- #endif
- #ifdef WOLFSSL_AES_192
- static const char EVP_AES_192_ECB[] = "AES-192-ECB";
- #endif
- #ifdef WOLFSSL_AES_256
- static const char EVP_AES_256_ECB[] = "AES-256-ECB";
- #endif
- #endif
- #endif
- #ifndef NO_DES3
- static const char EVP_DES_CBC[] = "DES-CBC";
- static const char EVP_DES_ECB[] = "DES-ECB";
- static const char EVP_DES_EDE3_CBC[] = "DES-EDE3-CBC";
- static const char EVP_DES_EDE3_ECB[] = "DES-EDE3-ECB";
- #endif
- #ifndef NO_RC4
- static const char EVP_ARC4[] = "ARC4";
- #endif
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- static const char EVP_CHACHA20_POLY1305[] = "CHACHA20-POLY1305";
- #endif
- static const char EVP_NULL[] = "NULL";
- #define EVP_CIPHER_TYPE_MATCHES(x, y) (XSTRCMP(x,y) == 0)
- #define EVP_PKEY_PRINT_LINE_WIDTH_MAX 80
- #define EVP_PKEY_PRINT_DIGITS_PER_LINE 15
- static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher);
- static enum wc_HashType EvpMd2MacType(const WOLFSSL_EVP_MD *md);
- /* Getter function for cipher key length
- *
- * c WOLFSSL_EVP_CIPHER structure to get key length from
- *
- * NOTE: OpenSSL_add_all_ciphers() should be called first before using this
- * function
- *
- * Returns size of key in bytes
- */
- int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_Cipher_key_length");
- if (c == NULL) {
- return 0;
- }
- switch (cipherType(c)) {
- #if !defined(NO_AES)
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- case AES_128_CBC_TYPE: return 16;
- case AES_192_CBC_TYPE: return 24;
- case AES_256_CBC_TYPE: return 32;
- #endif
- #if defined(WOLFSSL_AES_CFB)
- case AES_128_CFB1_TYPE: return 16;
- case AES_192_CFB1_TYPE: return 24;
- case AES_256_CFB1_TYPE: return 32;
- case AES_128_CFB8_TYPE: return 16;
- case AES_192_CFB8_TYPE: return 24;
- case AES_256_CFB8_TYPE: return 32;
- case AES_128_CFB128_TYPE: return 16;
- case AES_192_CFB128_TYPE: return 24;
- case AES_256_CFB128_TYPE: return 32;
- #endif
- #if defined(WOLFSSL_AES_OFB)
- case AES_128_OFB_TYPE: return 16;
- case AES_192_OFB_TYPE: return 24;
- case AES_256_OFB_TYPE: return 32;
- #endif
- #if defined(WOLFSSL_AES_XTS)
- /* Two keys for XTS. */
- case AES_128_XTS_TYPE: return 16 * 2;
- case AES_256_XTS_TYPE: return 32 * 2;
- #endif
- #if defined(HAVE_AESGCM)
- case AES_128_GCM_TYPE: return 16;
- case AES_192_GCM_TYPE: return 24;
- case AES_256_GCM_TYPE: return 32;
- #endif
- #if defined(WOLFSSL_AES_COUNTER)
- case AES_128_CTR_TYPE: return 16;
- case AES_192_CTR_TYPE: return 24;
- case AES_256_CTR_TYPE: return 32;
- #endif
- #if defined(HAVE_AES_ECB)
- case AES_128_ECB_TYPE: return 16;
- case AES_192_ECB_TYPE: return 24;
- case AES_256_ECB_TYPE: return 32;
- #endif
- #endif /* !NO_AES */
- #ifndef NO_DES3
- case DES_CBC_TYPE: return 8;
- case DES_EDE3_CBC_TYPE: return 24;
- case DES_ECB_TYPE: return 8;
- case DES_EDE3_ECB_TYPE: return 24;
- #endif
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- case CHACHA20_POLY1305_TYPE: return 32;
- #endif
- default:
- return 0;
- }
- }
- int wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
- const WOLFSSL_EVP_CIPHER* type,
- const unsigned char* key,
- const unsigned char* iv)
- {
- return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 1);
- }
- int wolfSSL_EVP_EncryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
- const WOLFSSL_EVP_CIPHER* type,
- WOLFSSL_ENGINE *impl,
- const unsigned char* key,
- const unsigned char* iv)
- {
- (void) impl;
- return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 1);
- }
- int wolfSSL_EVP_DecryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
- const WOLFSSL_EVP_CIPHER* type,
- const unsigned char* key,
- const unsigned char* iv)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
- return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 0);
- }
- int wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
- const WOLFSSL_EVP_CIPHER* type,
- WOLFSSL_ENGINE *impl,
- const unsigned char* key,
- const unsigned char* iv)
- {
- (void) impl;
- WOLFSSL_ENTER("wolfSSL_EVP_DecryptInit");
- return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 0);
- }
- WOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void)
- {
- WOLFSSL_EVP_CIPHER_CTX *ctx = (WOLFSSL_EVP_CIPHER_CTX*)XMALLOC(sizeof *ctx,
- NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if (ctx) {
- WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_new");
- wolfSSL_EVP_CIPHER_CTX_init(ctx);
- }
- return ctx;
- }
- void wolfSSL_EVP_CIPHER_CTX_free(WOLFSSL_EVP_CIPHER_CTX *ctx)
- {
- if (ctx) {
- WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_free");
- wolfSSL_EVP_CIPHER_CTX_cleanup(ctx);
- XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- }
- }
- int wolfSSL_EVP_CIPHER_CTX_reset(WOLFSSL_EVP_CIPHER_CTX *ctx)
- {
- int ret = WOLFSSL_FAILURE;
- if (ctx != NULL) {
- WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_reset");
- wolfSSL_EVP_CIPHER_CTX_cleanup(ctx);
- ret = WOLFSSL_SUCCESS;
- }
- return ret;
- }
- unsigned long wolfSSL_EVP_CIPHER_CTX_mode(const WOLFSSL_EVP_CIPHER_CTX *ctx)
- {
- if (ctx == NULL) return 0;
- return ctx->flags & WOLFSSL_EVP_CIPH_MODE;
- }
- unsigned long wolfSSL_EVP_CIPHER_CTX_flags(const WOLFSSL_EVP_CIPHER_CTX *ctx)
- {
- if (ctx == NULL) return 0;
- return ctx->flags;
- }
- int wolfSSL_EVP_EncryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
- unsigned char *out, int *outl)
- {
- if (ctx && ctx->enc) {
- WOLFSSL_ENTER("wolfSSL_EVP_EncryptFinal");
- return wolfSSL_EVP_CipherFinal(ctx, out, outl);
- }
- else
- return WOLFSSL_FAILURE;
- }
- int wolfSSL_EVP_CipherInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
- const WOLFSSL_EVP_CIPHER* type,
- WOLFSSL_ENGINE *impl,
- const unsigned char* key,
- const unsigned char* iv,
- int enc)
- {
- (void)impl;
- return wolfSSL_EVP_CipherInit(ctx, type, key, iv, enc);
- }
- int wolfSSL_EVP_EncryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx,
- unsigned char *out, int *outl)
- {
- if (ctx && ctx->enc) {
- WOLFSSL_ENTER("wolfSSL_EVP_EncryptFinal_ex");
- return wolfSSL_EVP_CipherFinal(ctx, out, outl);
- }
- else
- return WOLFSSL_FAILURE;
- }
- int wolfSSL_EVP_DecryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
- unsigned char *out, int *outl)
- {
- if (ctx && !ctx->enc) {
- WOLFSSL_ENTER("wolfSSL_EVP_DecryptFinal");
- return wolfSSL_EVP_CipherFinal(ctx, out, outl);
- }
- else {
- return WOLFSSL_FAILURE;
- }
- }
- int wolfSSL_EVP_DecryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx,
- unsigned char *out, int *outl)
- {
- if (ctx && !ctx->enc) {
- WOLFSSL_ENTER("wolfSSL_EVP_DecryptFinal_ex");
- return wolfSSL_EVP_CipherFinal(ctx, out, outl);
- }
- else {
- return WOLFSSL_FAILURE;
- }
- }
- int wolfSSL_EVP_DigestInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
- const WOLFSSL_EVP_MD* type,
- WOLFSSL_ENGINE *impl)
- {
- (void) impl;
- WOLFSSL_ENTER("wolfSSL_EVP_DigestInit_ex");
- return wolfSSL_EVP_DigestInit(ctx, type);
- }
- #ifdef DEBUG_WOLFSSL_EVP
- #define PRINT_BUF(b, sz) { int _i; for(_i=0; _i<(sz); _i++) { \
- printf("%02x(%c),", (b)[_i], (b)[_i]); if ((_i+1)%8==0)printf("\n");}}
- #else
- #define PRINT_BUF(b, sz)
- #endif
- static int fillBuff(WOLFSSL_EVP_CIPHER_CTX *ctx, const unsigned char *in, int sz)
- {
- int fill;
- if (sz > 0) {
- if ((sz+ctx->bufUsed) > ctx->block_size) {
- fill = ctx->block_size - ctx->bufUsed;
- } else {
- fill = sz;
- }
- XMEMCPY(&(ctx->buf[ctx->bufUsed]), in, fill);
- ctx->bufUsed += fill;
- return fill;
- } else return 0;
- }
- static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx,
- unsigned char *out,
- const unsigned char *in, int inl)
- {
- int ret = 0;
- switch (ctx->cipherType) {
- #if !defined(NO_AES)
- #if defined(HAVE_AES_CBC)
- case AES_128_CBC_TYPE:
- case AES_192_CBC_TYPE:
- case AES_256_CBC_TYPE:
- if (ctx->enc)
- ret = wc_AesCbcEncrypt(&ctx->cipher.aes, out, in, inl);
- else
- ret = wc_AesCbcDecrypt(&ctx->cipher.aes, out, in, inl);
- break;
- #endif
- #if defined(WOLFSSL_AES_COUNTER)
- case AES_128_CTR_TYPE:
- case AES_192_CTR_TYPE:
- case AES_256_CTR_TYPE:
- ret = wc_AesCtrEncrypt(&ctx->cipher.aes, out, in, inl);
- break;
- #endif
- #if defined(HAVE_AES_ECB)
- case AES_128_ECB_TYPE:
- case AES_192_ECB_TYPE:
- case AES_256_ECB_TYPE:
- if (ctx->enc)
- ret = wc_AesEcbEncrypt(&ctx->cipher.aes, out, in, inl);
- else
- ret = wc_AesEcbDecrypt(&ctx->cipher.aes, out, in, inl);
- break;
- #endif
- #if defined(WOLFSSL_AES_OFB)
- case AES_128_OFB_TYPE:
- case AES_192_OFB_TYPE:
- case AES_256_OFB_TYPE:
- if (ctx->enc)
- ret = wc_AesOfbEncrypt(&ctx->cipher.aes, out, in, inl);
- else
- ret = wc_AesOfbDecrypt(&ctx->cipher.aes, out, in, inl);
- break;
- #endif
- #if defined(WOLFSSL_AES_CFB)
- #if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
- case AES_128_CFB1_TYPE:
- case AES_192_CFB1_TYPE:
- case AES_256_CFB1_TYPE:
- if (ctx->enc)
- ret = wc_AesCfb1Encrypt(&ctx->cipher.aes, out, in,
- inl * WOLFSSL_BIT_SIZE);
- else
- ret = wc_AesCfb1Decrypt(&ctx->cipher.aes, out, in,
- inl * WOLFSSL_BIT_SIZE);
- break;
- case AES_128_CFB8_TYPE:
- case AES_192_CFB8_TYPE:
- case AES_256_CFB8_TYPE:
- if (ctx->enc)
- ret = wc_AesCfb8Encrypt(&ctx->cipher.aes, out, in, inl);
- else
- ret = wc_AesCfb8Decrypt(&ctx->cipher.aes, out, in, inl);
- break;
- #endif /* !HAVE_SELFTEST && !HAVE_FIPS */
- case AES_128_CFB128_TYPE:
- case AES_192_CFB128_TYPE:
- case AES_256_CFB128_TYPE:
- if (ctx->enc)
- ret = wc_AesCfbEncrypt(&ctx->cipher.aes, out, in, inl);
- else
- ret = wc_AesCfbDecrypt(&ctx->cipher.aes, out, in, inl);
- break;
- #endif
- #if defined(WOLFSSL_AES_XTS)
- case AES_128_XTS_TYPE:
- case AES_256_XTS_TYPE:
- if (ctx->enc)
- ret = wc_AesXtsEncrypt(&ctx->cipher.xts, out, in, inl,
- ctx->iv, ctx->ivSz);
- else
- ret = wc_AesXtsDecrypt(&ctx->cipher.xts, out, in, inl,
- ctx->iv, ctx->ivSz);
- break;
- #endif
- #endif /* !NO_AES */
- #ifndef NO_DES3
- case DES_CBC_TYPE:
- if (ctx->enc)
- ret = wc_Des_CbcEncrypt(&ctx->cipher.des, out, in, inl);
- else
- ret = wc_Des_CbcDecrypt(&ctx->cipher.des, out, in, inl);
- break;
- case DES_EDE3_CBC_TYPE:
- if (ctx->enc)
- ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, out, in, inl);
- else
- ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, out, in, inl);
- break;
- #if defined(WOLFSSL_DES_ECB)
- case DES_ECB_TYPE:
- ret = wc_Des_EcbEncrypt(&ctx->cipher.des, out, in, inl);
- break;
- case DES_EDE3_ECB_TYPE:
- ret = wc_Des3_EcbEncrypt(&ctx->cipher.des3, out, in, inl);
- break;
- #endif
- #endif
- #ifndef NO_RC4
- case ARC4_TYPE:
- wc_Arc4Process(&ctx->cipher.arc4, out, in, inl);
- break;
- #endif
- default:
- ret = WOLFSSL_FAILURE;
- }
- (void)in;
- (void)inl;
- (void)out;
- return (ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
- }
- #if defined(HAVE_AESGCM)
- #ifndef WOLFSSL_AESGCM_STREAM
- static int wolfSSL_EVP_CipherUpdate_GCM_AAD(WOLFSSL_EVP_CIPHER_CTX *ctx,
- const unsigned char *in, int inl) {
- if (in && inl > 0) {
- byte* tmp = (byte*)XREALLOC(ctx->gcmAuthIn,
- ctx->gcmAuthInSz + inl, NULL, DYNAMIC_TYPE_OPENSSL);
- if (tmp) {
- ctx->gcmAuthIn = tmp;
- XMEMCPY(ctx->gcmAuthIn + ctx->gcmAuthInSz, in, inl);
- ctx->gcmAuthInSz += inl;
- }
- else {
- WOLFSSL_MSG("realloc error");
- return MEMORY_E;
- }
- }
- return 0;
- }
- #endif /* WOLFSSL_AESGCM_STREAM */
- static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
- unsigned char *out, int *outl,
- const unsigned char *in, int inl)
- {
- #ifndef WOLFSSL_AESGCM_STREAM
- int ret = 0;
- *outl = inl;
- if (out) {
- /* Buffer input for one-shot API */
- if (inl > 0) {
- byte* tmp;
- tmp = (byte*)XREALLOC(ctx->gcmBuffer,
- ctx->gcmBufferLen + inl, NULL,
- DYNAMIC_TYPE_OPENSSL);
- if (tmp) {
- XMEMCPY(tmp + ctx->gcmBufferLen, in, inl);
- ctx->gcmBufferLen += inl;
- ctx->gcmBuffer = tmp;
- *outl = 0;
- }
- else {
- ret = MEMORY_E;
- }
- }
- }
- else {
- ret = wolfSSL_EVP_CipherUpdate_GCM_AAD(ctx, in, inl);
- }
- if (ret != 0) {
- *outl = 0;
- return WOLFSSL_FAILURE;
- }
- return WOLFSSL_SUCCESS;
- #else
- int ret;
- /* When out is NULL then this is AAD. */
- if (out == NULL) {
- if (ctx->enc) {
- ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, NULL, NULL, 0, in,
- inl);
- }
- else {
- ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, NULL, NULL, 0, in,
- inl);
- }
- }
- /* When out is not NULL then this is plaintext/cipher text. */
- else {
- if (ctx->enc) {
- ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, out, in, inl, NULL,
- 0);
- }
- else {
- ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, out, in, inl, NULL,
- 0);
- }
- }
- *outl = inl;
- if (ret == 0) {
- ret = WOLFSSL_SUCCESS;
- }
- else {
- ret = WOLFSSL_FAILURE;
- }
- return ret;
- #endif /* WOLFSSL_AESGCM_STREAM */
- }
- #endif /* HAVE_AESGCM */
- /* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
- int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
- unsigned char *out, int *outl,
- const unsigned char *in, int inl)
- {
- int blocks;
- int fill;
- WOLFSSL_ENTER("wolfSSL_EVP_CipherUpdate");
- if (inl == 0 && in == NULL ) {
- /* Nothing to do in this case. Just return. */
- return WOLFSSL_SUCCESS;
- }
- if ((ctx == NULL) || (inl < 0) || (outl == NULL) || (in == NULL)) {
- WOLFSSL_MSG("Bad argument");
- return WOLFSSL_FAILURE;
- }
- *outl = 0;
- switch (ctx->cipherType) {
- #if !defined(NO_AES) && defined(HAVE_AESGCM)
- case AES_128_GCM_TYPE:
- case AES_192_GCM_TYPE:
- case AES_256_GCM_TYPE:
- /* if out == NULL, in/inl contains the additional authenticated data * for GCM */
- return wolfSSL_EVP_CipherUpdate_GCM(ctx, out, outl, in, inl);
- #endif /* !defined(NO_AES) && defined(HAVE_AESGCM) */
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- case CHACHA20_POLY1305_TYPE:
- if (out == NULL) {
- if (wc_ChaCha20Poly1305_UpdateAad(&ctx->cipher.chachaPoly, in,
- inl) != 0) {
- WOLFSSL_MSG("wc_ChaCha20Poly1305_UpdateAad failed");
- return WOLFSSL_FAILURE;
- }
- else {
- *outl = inl;
- return WOLFSSL_SUCCESS;
- }
- }
- else {
- if (wc_ChaCha20Poly1305_UpdateData(&ctx->cipher.chachaPoly, in,
- out, inl) != 0) {
- WOLFSSL_MSG("wc_ChaCha20Poly1305_UpdateData failed");
- return WOLFSSL_FAILURE;
- }
- else {
- *outl = inl;
- return WOLFSSL_SUCCESS;
- }
- }
- #endif
- default:
- /* fall-through */
- break;
- }
- if (out == NULL) {
- return WOLFSSL_FAILURE;
- }
- /* if(inl == 0)wolfSSL_EVP_CipherUpdate_GCM to get tag */
- if (inl == 0) {
- return WOLFSSL_SUCCESS;
- }
- if (ctx->bufUsed > 0) { /* concatenate them if there is anything */
- fill = fillBuff(ctx, in, inl);
- inl -= fill;
- in += fill;
- }
- /* check if the buff is full, and if so flash it out */
- if (ctx->bufUsed == ctx->block_size) {
- byte* output = out;
- /* During decryption we save the last block to check padding on Final.
- * Update the last block stored if one has already been stored */
- if (ctx->enc == 0) {
- if (ctx->lastUsed == 1) {
- XMEMCPY(out, ctx->lastBlock, ctx->block_size);
- *outl+= ctx->block_size;
- out += ctx->block_size;
- }
- output = ctx->lastBlock; /* redirect output to last block buffer */
- ctx->lastUsed = 1;
- }
- PRINT_BUF(ctx->buf, ctx->block_size);
- if (evpCipherBlock(ctx, output, ctx->buf, ctx->block_size) == 0) {
- return WOLFSSL_FAILURE;
- }
- PRINT_BUF(out, ctx->block_size);
- ctx->bufUsed = 0;
- /* if doing encryption update the new output block, decryption will
- * always have the last block saved for when Final is called */
- if ((ctx->enc != 0)) {
- *outl+= ctx->block_size;
- out += ctx->block_size;
- }
- }
- blocks = inl / ctx->block_size;
- if (blocks > 0) {
- /* During decryption we save the last block to check padding on Final.
- * Update the last block stored if one has already been stored */
- if ((ctx->enc == 0) && (ctx->lastUsed == 1)) {
- PRINT_BUF(ctx->lastBlock, ctx->block_size);
- XMEMCPY(out, ctx->lastBlock, ctx->block_size);
- *outl += ctx->block_size;
- out += ctx->block_size;
- ctx->lastUsed = 0;
- }
- /* process blocks */
- if (evpCipherBlock(ctx, out, in, blocks * ctx->block_size) == 0) {
- return WOLFSSL_FAILURE;
- }
- PRINT_BUF(in, ctx->block_size*blocks);
- PRINT_BUF(out,ctx->block_size*blocks);
- inl -= ctx->block_size * blocks;
- in += ctx->block_size * blocks;
- if (ctx->enc == 0) {
- if ((ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) ||
- (ctx->block_size == 1)) {
- ctx->lastUsed = 0;
- *outl += ctx->block_size * blocks;
- } else {
- /* in the case of decryption and padding, store the last block
- * here in order to verify the padding when Final is called */
- if (inl == 0) { /* if not 0 then we know leftovers are checked*/
- ctx->lastUsed = 1;
- blocks = blocks - 1; /* save last block to check padding in
- * EVP_CipherFinal call */
- XMEMCPY(ctx->lastBlock, &out[ctx->block_size * blocks],
- ctx->block_size);
- }
- *outl += ctx->block_size * blocks;
- }
- } else {
- *outl += ctx->block_size * blocks;
- }
- }
- if (inl > 0) {
- /* put fraction into buff */
- fillBuff(ctx, in, inl);
- /* no increase of outl */
- }
- (void)out; /* silence warning in case not read */
- return WOLFSSL_SUCCESS;
- }
- static void padBlock(WOLFSSL_EVP_CIPHER_CTX *ctx)
- {
- int i;
- for (i = ctx->bufUsed; i < ctx->block_size; i++)
- ctx->buf[i] = (byte)(ctx->block_size - ctx->bufUsed);
- }
- static int checkPad(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *buff)
- {
- int i;
- int n;
- n = buff[ctx->block_size-1];
- if (n > ctx->block_size) return -1;
- for (i = 0; i < n; i++) {
- if (buff[ctx->block_size-i-1] != n)
- return -1;
- }
- return ctx->block_size - n;
- }
- #if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
- || FIPS_VERSION_GE(2,0))
- static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
- {
- int i;
- for (i = ctrSz-1; i >= 0; i--) {
- if (++ctr[i])
- break;
- }
- }
- #endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
- * HAVE_FIPS_VERSION >= 2 */
- int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out,
- int *outl)
- {
- int fl;
- int ret = WOLFSSL_SUCCESS;
- #if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
- || FIPS_VERSION_GE(2,0))
- byte tmp = 0;
- #endif
- if (!ctx || !outl)
- return WOLFSSL_FAILURE;
- WOLFSSL_ENTER("wolfSSL_EVP_CipherFinal");
- switch (ctx->cipherType) {
- #if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
- || FIPS_VERSION_GE(2,0))
- case AES_128_GCM_TYPE:
- case AES_192_GCM_TYPE:
- case AES_256_GCM_TYPE:
- #ifndef WOLFSSL_AESGCM_STREAM
- if ((ctx->gcmBuffer && ctx->gcmBufferLen > 0)
- || (ctx->gcmBufferLen == 0)) {
- if (ctx->enc)
- ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out,
- ctx->gcmBuffer, ctx->gcmBufferLen,
- ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
- ctx->gcmAuthIn, ctx->gcmAuthInSz);
- else
- ret = wc_AesGcmDecrypt(&ctx->cipher.aes, out,
- ctx->gcmBuffer, ctx->gcmBufferLen,
- ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
- ctx->gcmAuthIn, ctx->gcmAuthInSz);
- if (ret == 0) {
- ret = WOLFSSL_SUCCESS;
- *outl = ctx->gcmBufferLen;
- }
- else {
- ret = WOLFSSL_FAILURE;
- *outl = 0;
- }
- XFREE(ctx->gcmBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
- ctx->gcmBuffer = NULL;
- ctx->gcmBufferLen = 0;
- if (ctx->gcmIncIv) {
- IncCtr((byte*)ctx->cipher.aes.reg,
- ctx->cipher.aes.nonceSz);
- ctx->gcmIncIv = 0;
- }
- }
- else {
- *outl = 0;
- }
- #else
- /* No data to return - all handled in Update. */
- *outl = 0;
- if (ctx->enc) {
- ret = wc_AesGcmEncryptFinal(&ctx->cipher.aes, ctx->authTag,
- ctx->authTagSz);
- }
- else {
- ret = wc_AesGcmDecryptFinal(&ctx->cipher.aes, ctx->authTag,
- ctx->authTagSz);
- if (ctx->gcmIncIv) {
- IncCtr((byte*)ctx->cipher.aes.reg, ctx->cipher.aes.nonceSz);
- }
- }
- if (ret == 0) {
- /* Reinitialize for subsequent wolfSSL_EVP_Cipher calls. */
- if (wc_AesGcmInit(&ctx->cipher.aes, NULL, 0,
- (byte*)ctx->cipher.aes.reg,
- ctx->ivSz) != 0) {
- WOLFSSL_MSG("wc_AesGcmInit failed");
- ret = WOLFSSL_FAILURE;
- }
- else {
- ret = WOLFSSL_SUCCESS;
- }
- }
- else {
- ret = WOLFSSL_FAILURE;
- }
- #endif /* WOLFSSL_AESGCM_STREAM */
- if (ret == WOLFSSL_SUCCESS) {
- if (ctx->gcmIncIv) {
- ctx->gcmIncIv = 0;
- }
- else {
- /* Clear IV, since IV reuse is not recommended for AES GCM. */
- XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);
- }
- if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) {
- ret = WOLFSSL_FAILURE;
- }
- }
- break;
- #endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
- * HAVE_FIPS_VERSION >= 2 */
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- case CHACHA20_POLY1305_TYPE:
- if (wc_ChaCha20Poly1305_Final(&ctx->cipher.chachaPoly,
- ctx->authTag) != 0) {
- WOLFSSL_MSG("wc_ChaCha20Poly1305_Final failed");
- return WOLFSSL_FAILURE;
- }
- else {
- *outl = 0;
- return WOLFSSL_SUCCESS;
- }
- #endif
- default:
- if (!out)
- return WOLFSSL_FAILURE;
- if (ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) {
- if (ctx->bufUsed != 0) return WOLFSSL_FAILURE;
- *outl = 0;
- }
- else if (ctx->enc) {
- if (ctx->block_size == 1) {
- *outl = 0;
- }
- else if ((ctx->bufUsed >= 0) && (ctx->block_size != 1)) {
- padBlock(ctx);
- PRINT_BUF(ctx->buf, ctx->block_size);
- if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) {
- WOLFSSL_MSG("Final Cipher Block failed");
- ret = WOLFSSL_FAILURE;
- }
- else {
- PRINT_BUF(out, ctx->block_size);
- *outl = ctx->block_size;
- }
- }
- }
- else {
- if (ctx->block_size == 1) {
- *outl = 0;
- }
- else if ((ctx->bufUsed % ctx->block_size) != 0) {
- *outl = 0;
- /* not enough padding for decrypt */
- WOLFSSL_MSG("Final Cipher Block not enough padding");
- ret = WOLFSSL_FAILURE;
- }
- else if (ctx->lastUsed) {
- PRINT_BUF(ctx->lastBlock, ctx->block_size);
- if ((fl = checkPad(ctx, ctx->lastBlock)) >= 0) {
- XMEMCPY(out, ctx->lastBlock, fl);
- *outl = fl;
- if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
- /* return error in cases where the block length is
- * incorrect */
- WOLFSSL_MSG("Final Cipher Block bad length");
- ret = WOLFSSL_FAILURE;
- }
- }
- else {
- ret = WOLFSSL_FAILURE;
- }
- }
- else if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
- /* return error in cases where the block length is
- * incorrect */
- ret = WOLFSSL_FAILURE;
- }
- }
- break;
- }
- if (ret == WOLFSSL_SUCCESS) {
- #if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
- || FIPS_VERSION_GE(2,0))
- /*
- * This flag needs to retain its value between wolfSSL_EVP_CipherFinal
- * calls. wolfSSL_EVP_CipherInit will clear it, so we save and restore
- * it here.
- */
- if (ctx->cipherType == AES_128_GCM_TYPE ||
- ctx->cipherType == AES_192_GCM_TYPE ||
- ctx->cipherType == AES_256_GCM_TYPE) {
- tmp = ctx->gcmIvGenEnable;
- }
- #endif
- /* reset cipher state after final */
- ret = wolfSSL_EVP_CipherInit(ctx, NULL, NULL, NULL, -1);
- #if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
- || FIPS_VERSION_GE(2,0))
- if (ctx->cipherType == AES_128_GCM_TYPE ||
- ctx->cipherType == AES_192_GCM_TYPE ||
- ctx->cipherType == AES_256_GCM_TYPE) {
- ctx->gcmIvGenEnable = tmp;
- }
- #endif
- }
- return ret;
- }
- #ifdef WOLFSSL_EVP_DECRYPT_LEGACY
- /* This is a version of DecryptFinal to work with data encrypted with
- * wolfSSL_EVP_EncryptFinal() with the broken padding. (pre-v3.12.0)
- * Only call this after wolfSSL_EVP_CipherFinal() fails on a decrypt.
- * Note, you don't know if the padding is good or bad with the old
- * encrypt, but it is likely to be or bad. It will update the output
- * length with the block_size so the last block is still captured. */
- int wolfSSL_EVP_DecryptFinal_legacy(WOLFSSL_EVP_CIPHER_CTX *ctx,
- unsigned char *out, int *outl)
- {
- int fl;
- if (ctx == NULL || out == NULL || outl == NULL)
- return BAD_FUNC_ARG;
- WOLFSSL_ENTER("wolfSSL_EVP_DecryptFinal_legacy");
- if (ctx->block_size == 1) {
- *outl = 0;
- return WOLFSSL_SUCCESS;
- }
- if ((ctx->bufUsed % ctx->block_size) != 0) {
- *outl = 0;
- /* not enough padding for decrypt */
- return WOLFSSL_FAILURE;
- }
- /* The original behavior of CipherFinal() was like it is now,
- * but checkPad would return 0 in case of a bad pad. It would
- * treat the pad as 0, and leave the data in the output buffer,
- * and not try to copy anything. This converts checkPad's -1 error
- * code to block_size.
- */
- if (ctx->lastUsed) {
- PRINT_BUF(ctx->lastBlock, ctx->block_size);
- if ((fl = checkPad(ctx, ctx->lastBlock)) < 0) {
- fl = ctx->block_size;
- }
- else {
- XMEMCPY(out, ctx->lastBlock, fl);
- }
- *outl = fl;
- }
- /* return error in cases where the block length is incorrect */
- if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
- return WOLFSSL_FAILURE;
- }
- return WOLFSSL_SUCCESS;
- }
- #endif
- int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx)
- {
- if (ctx == NULL) return BAD_FUNC_ARG;
- switch (ctx->cipherType) {
- #if !defined(NO_AES) || !defined(NO_DES3)
- #if !defined(NO_AES)
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- case AES_128_CBC_TYPE:
- case AES_192_CBC_TYPE:
- case AES_256_CBC_TYPE:
- #endif
- #if defined(HAVE_AESGCM)
- case AES_128_GCM_TYPE:
- case AES_192_GCM_TYPE:
- case AES_256_GCM_TYPE:
- #endif
- #if defined(WOLFSSL_AES_COUNTER)
- case AES_128_CTR_TYPE:
- case AES_192_CTR_TYPE:
- case AES_256_CTR_TYPE:
- #endif
- #if defined(WOLFSSL_AES_CFB)
- case AES_128_CFB1_TYPE:
- case AES_192_CFB1_TYPE:
- case AES_256_CFB1_TYPE:
- case AES_128_CFB8_TYPE:
- case AES_192_CFB8_TYPE:
- case AES_256_CFB8_TYPE:
- case AES_128_CFB128_TYPE:
- case AES_192_CFB128_TYPE:
- case AES_256_CFB128_TYPE:
- #endif
- #if defined(WOLFSSL_AES_OFB)
- case AES_128_OFB_TYPE:
- case AES_192_OFB_TYPE:
- case AES_256_OFB_TYPE:
- #endif
- #if defined(WOLFSSL_AES_XTS)
- case AES_128_XTS_TYPE:
- case AES_256_XTS_TYPE:
- #endif
- case AES_128_ECB_TYPE:
- case AES_192_ECB_TYPE:
- case AES_256_ECB_TYPE:
- #endif /* !NO_AES */
- #ifndef NO_DES3
- case DES_CBC_TYPE:
- case DES_ECB_TYPE:
- case DES_EDE3_CBC_TYPE:
- case DES_EDE3_ECB_TYPE:
- #endif
- return ctx->block_size;
- #endif /* !NO_AES || !NO_DES3 */
- default:
- return 0;
- }
- }
- static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher)
- {
- if (cipher == NULL) return 0; /* dummy for #ifdef */
- #ifndef NO_DES3
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_DES_CBC))
- return DES_CBC_TYPE;
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_DES_EDE3_CBC))
- return DES_EDE3_CBC_TYPE;
- #if !defined(NO_DES3)
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_DES_ECB))
- return DES_ECB_TYPE;
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_DES_EDE3_ECB))
- return DES_EDE3_ECB_TYPE;
- #endif /* NO_DES3 && HAVE_AES_ECB */
- #endif
- #if !defined(NO_AES)
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- #ifdef WOLFSSL_AES_128
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_CBC))
- return AES_128_CBC_TYPE;
- #endif
- #ifdef WOLFSSL_AES_192
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_192_CBC))
- return AES_192_CBC_TYPE;
- #endif
- #ifdef WOLFSSL_AES_256
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_256_CBC))
- return AES_256_CBC_TYPE;
- #endif
- #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
- #if defined(HAVE_AESGCM)
- #ifdef WOLFSSL_AES_128
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_GCM))
- return AES_128_GCM_TYPE;
- #endif
- #ifdef WOLFSSL_AES_192
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_192_GCM))
- return AES_192_GCM_TYPE;
- #endif
- #ifdef WOLFSSL_AES_256
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_256_GCM))
- return AES_256_GCM_TYPE;
- #endif
- #endif /* HAVE_AESGCM */
- #if defined(WOLFSSL_AES_COUNTER)
- #ifdef WOLFSSL_AES_128
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_CTR))
- return AES_128_CTR_TYPE;
- #endif
- #ifdef WOLFSSL_AES_192
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_192_CTR))
- return AES_192_CTR_TYPE;
- #endif
- #ifdef WOLFSSL_AES_256
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_256_CTR))
- return AES_256_CTR_TYPE;
- #endif
- #endif /* HAVE_AES_CBC */
- #if defined(HAVE_AES_ECB)
- #ifdef WOLFSSL_AES_128
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_ECB))
- return AES_128_ECB_TYPE;
- #endif
- #ifdef WOLFSSL_AES_192
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_192_ECB))
- return AES_192_ECB_TYPE;
- #endif
- #ifdef WOLFSSL_AES_256
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_256_ECB))
- return AES_256_ECB_TYPE;
- #endif
- #endif /*HAVE_AES_CBC */
- #if defined(WOLFSSL_AES_XTS)
- #ifdef WOLFSSL_AES_128
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_XTS))
- return AES_128_XTS_TYPE;
- #endif
- #ifdef WOLFSSL_AES_256
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_256_XTS))
- return AES_256_XTS_TYPE;
- #endif
- #endif /* WOLFSSL_AES_XTS */
- #if defined(WOLFSSL_AES_CFB)
- #ifdef WOLFSSL_AES_128
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_CFB1))
- return AES_128_CFB1_TYPE;
- #endif
- #ifdef WOLFSSL_AES_192
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_192_CFB1))
- return AES_192_CFB1_TYPE;
- #endif
- #ifdef WOLFSSL_AES_256
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_256_CFB1))
- return AES_256_CFB1_TYPE;
- #endif
- #ifdef WOLFSSL_AES_128
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_CFB8))
- return AES_128_CFB8_TYPE;
- #endif
- #ifdef WOLFSSL_AES_192
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_192_CFB8))
- return AES_192_CFB8_TYPE;
- #endif
- #ifdef WOLFSSL_AES_256
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_256_CFB8))
- return AES_256_CFB8_TYPE;
- #endif
- #ifdef WOLFSSL_AES_128
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_CFB128))
- return AES_128_CFB128_TYPE;
- #endif
- #ifdef WOLFSSL_AES_192
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_192_CFB128))
- return AES_192_CFB128_TYPE;
- #endif
- #ifdef WOLFSSL_AES_256
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_256_CFB128))
- return AES_256_CFB128_TYPE;
- #endif
- #endif /*HAVE_AES_CBC */
- #if defined(WOLFSSL_AES_OFB)
- #ifdef WOLFSSL_AES_128
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_OFB))
- return AES_128_OFB_TYPE;
- #endif
- #ifdef WOLFSSL_AES_192
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_192_OFB))
- return AES_192_OFB_TYPE;
- #endif
- #ifdef WOLFSSL_AES_256
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_256_OFB))
- return AES_256_OFB_TYPE;
- #endif
- #endif
- #endif /* !NO_AES */
- #ifndef NO_RC4
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_ARC4))
- return ARC4_TYPE;
- #endif
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_CHACHA20_POLY1305))
- return CHACHA20_POLY1305_TYPE;
- #endif
- else return 0;
- }
- int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher)
- {
- if (cipher == NULL) return BAD_FUNC_ARG;
- switch (cipherType(cipher)) {
- #if !defined(NO_AES)
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- case AES_128_CBC_TYPE:
- case AES_192_CBC_TYPE:
- case AES_256_CBC_TYPE:
- return AES_BLOCK_SIZE;
- #endif
- #if defined(HAVE_AESGCM)
- case AES_128_GCM_TYPE:
- case AES_192_GCM_TYPE:
- case AES_256_GCM_TYPE:
- return 1;
- #endif
- #if defined(WOLFSSL_AES_COUNTER)
- case AES_128_CTR_TYPE:
- case AES_192_CTR_TYPE:
- case AES_256_CTR_TYPE:
- return 1;
- #endif
- #if defined(HAVE_AES_ECB)
- case AES_128_ECB_TYPE:
- case AES_192_ECB_TYPE:
- case AES_256_ECB_TYPE:
- return AES_BLOCK_SIZE;
- #endif
- #if defined(WOLFSSL_AES_CFB)
- case AES_128_CFB1_TYPE:
- case AES_192_CFB1_TYPE:
- case AES_256_CFB1_TYPE:
- case AES_128_CFB8_TYPE:
- case AES_192_CFB8_TYPE:
- case AES_256_CFB8_TYPE:
- case AES_128_CFB128_TYPE:
- case AES_192_CFB128_TYPE:
- case AES_256_CFB128_TYPE:
- return 1;
- #endif
- #if defined(WOLFSSL_AES_OFB)
- case AES_128_OFB_TYPE:
- case AES_192_OFB_TYPE:
- case AES_256_OFB_TYPE:
- return 1;
- #endif
- #if defined(WOLFSSL_AES_XTS)
- case AES_128_XTS_TYPE:
- case AES_256_XTS_TYPE:
- return 1;
- #endif
- #endif /* NO_AES */
- #ifndef NO_RC4
- case ARC4_TYPE:
- return 1;
- #endif
- #ifndef NO_DES3
- case DES_CBC_TYPE: return 8;
- case DES_EDE3_CBC_TYPE: return 8;
- case DES_ECB_TYPE: return 8;
- case DES_EDE3_ECB_TYPE: return 8;
- #endif
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- case CHACHA20_POLY1305_TYPE:
- return 1;
- #endif
- default:
- return 0;
- }
- }
- unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher)
- {
- switch (cipherType(cipher)) {
- #if !defined(NO_AES)
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- case AES_128_CBC_TYPE:
- case AES_192_CBC_TYPE:
- case AES_256_CBC_TYPE:
- return WOLFSSL_EVP_CIPH_CBC_MODE;
- #endif
- #if defined(HAVE_AESGCM)
- case AES_128_GCM_TYPE:
- case AES_192_GCM_TYPE:
- case AES_256_GCM_TYPE:
- return WOLFSSL_EVP_CIPH_GCM_MODE |
- WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
- #endif
- #if defined(WOLFSSL_AES_COUNTER)
- case AES_128_CTR_TYPE:
- case AES_192_CTR_TYPE:
- case AES_256_CTR_TYPE:
- return WOLFSSL_EVP_CIPH_CTR_MODE;
- #endif
- #if defined(WOLFSSL_AES_CFB)
- case AES_128_CFB1_TYPE:
- case AES_192_CFB1_TYPE:
- case AES_256_CFB1_TYPE:
- case AES_128_CFB8_TYPE:
- case AES_192_CFB8_TYPE:
- case AES_256_CFB8_TYPE:
- case AES_128_CFB128_TYPE:
- case AES_192_CFB128_TYPE:
- case AES_256_CFB128_TYPE:
- return WOLFSSL_EVP_CIPH_CFB_MODE;
- #endif
- #if defined(WOLFSSL_AES_OFB)
- case AES_128_OFB_TYPE:
- case AES_192_OFB_TYPE:
- case AES_256_OFB_TYPE:
- return WOLFSSL_EVP_CIPH_OFB_MODE;
- #endif
- #if defined(WOLFSSL_AES_XTS)
- case AES_128_XTS_TYPE:
- case AES_256_XTS_TYPE:
- return WOLFSSL_EVP_CIPH_XTS_MODE;
- #endif
- case AES_128_ECB_TYPE:
- case AES_192_ECB_TYPE:
- case AES_256_ECB_TYPE:
- return WOLFSSL_EVP_CIPH_ECB_MODE;
- #endif /* !NO_AES */
- #ifndef NO_DES3
- case DES_CBC_TYPE:
- case DES_EDE3_CBC_TYPE:
- return WOLFSSL_EVP_CIPH_CBC_MODE;
- case DES_ECB_TYPE:
- case DES_EDE3_ECB_TYPE:
- return WOLFSSL_EVP_CIPH_ECB_MODE;
- #endif
- #ifndef NO_RC4
- case ARC4_TYPE:
- return EVP_CIPH_STREAM_CIPHER;
- #endif
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- case CHACHA20_POLY1305_TYPE:
- return WOLFSSL_EVP_CIPH_STREAM_CIPHER |
- WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
- #endif
- default:
- return 0;
- }
- }
- unsigned long WOLFSSL_EVP_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher)
- {
- if (cipher == NULL) return 0;
- return WOLFSSL_CIPHER_mode(cipher) & WOLFSSL_EVP_CIPH_MODE;
- }
- void wolfSSL_EVP_CIPHER_CTX_set_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags)
- {
- if (ctx != NULL) {
- ctx->flags |= flags;
- }
- }
- void wolfSSL_EVP_CIPHER_CTX_clear_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags)
- {
- if (ctx != NULL) {
- ctx->flags &= ~flags;
- }
- }
- unsigned long wolfSSL_EVP_CIPHER_flags(const WOLFSSL_EVP_CIPHER *cipher)
- {
- if (cipher == NULL) return 0;
- return WOLFSSL_CIPHER_mode(cipher);
- }
- int wolfSSL_EVP_CIPHER_CTX_set_padding(WOLFSSL_EVP_CIPHER_CTX *ctx, int padding)
- {
- if (ctx == NULL) return BAD_FUNC_ARG;
- if (padding) {
- ctx->flags &= ~WOLFSSL_EVP_CIPH_NO_PADDING;
- }
- else {
- ctx->flags |= WOLFSSL_EVP_CIPH_NO_PADDING;
- }
- return 1;
- }
- int wolfSSL_EVP_add_digest(const WOLFSSL_EVP_MD *digest)
- {
- (void)digest;
- /* nothing to do */
- return 0;
- }
- /* Frees the WOLFSSL_EVP_PKEY_CTX passed in.
- *
- * return WOLFSSL_SUCCESS on success
- */
- #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
- void wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx)
- #else
- int wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx)
- #endif
- {
- if (ctx == NULL)
- #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
- return;
- #else
- return 0;
- #endif
- WOLFSSL_ENTER("EVP_PKEY_CTX_free");
- if (ctx->pkey != NULL)
- wolfSSL_EVP_PKEY_free(ctx->pkey);
- if (ctx->peerKey != NULL)
- wolfSSL_EVP_PKEY_free(ctx->peerKey);
- XFREE(ctx, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
- #if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L
- return WOLFSSL_SUCCESS;
- #endif
- }
- /* Creates a new WOLFSSL_EVP_PKEY_CTX structure.
- *
- * pkey key structure to use with new WOLFSSL_EVP_PKEY_CTX
- * e engine to use. It should be NULL at this time.
- *
- * return the new structure on success and NULL if failed.
- */
- WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_ENGINE *e)
- {
- WOLFSSL_EVP_PKEY_CTX* ctx;
- if (pkey == NULL) return 0;
- if (e != NULL) return 0;
- WOLFSSL_ENTER("EVP_PKEY_CTX_new");
- ctx = (WOLFSSL_EVP_PKEY_CTX*)XMALLOC(sizeof(WOLFSSL_EVP_PKEY_CTX), NULL,
- DYNAMIC_TYPE_PUBLIC_KEY);
- if (ctx == NULL) return NULL;
- XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_PKEY_CTX));
- ctx->pkey = pkey;
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- ctx->padding = RSA_PKCS1_PADDING;
- ctx->md = NULL;
- #endif
- #ifdef HAVE_ECC
- if (pkey->ecc && pkey->ecc->group) {
- /* set curve NID from pkey if available */
- ctx->curveNID = pkey->ecc->group->curve_nid;
- }
- else {
- ctx->curveNID = ECC_CURVE_DEF;
- }
- #endif
- if (wolfSSL_EVP_PKEY_up_ref(pkey) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("Couldn't increase key reference count");
- }
- return ctx;
- }
- /* Sets the type of RSA padding to use.
- *
- * ctx structure to set padding in.
- * padding RSA padding type
- *
- * returns WOLFSSL_SUCCESS on success.
- */
- int wolfSSL_EVP_PKEY_CTX_set_rsa_padding(WOLFSSL_EVP_PKEY_CTX *ctx, int padding)
- {
- if (ctx == NULL) return 0;
- WOLFSSL_ENTER("EVP_PKEY_CTX_set_rsa_padding");
- ctx->padding = padding;
- return WOLFSSL_SUCCESS;
- }
- /* Sets the message digest type for RSA padding to use.
- *
- * ctx structure to set padding in.
- * md Message digest
- *
- * returns WOLFSSL_SUCCESS on success.
- */
- int wolfSSL_EVP_PKEY_CTX_set_signature_md(WOLFSSL_EVP_PKEY_CTX *ctx,
- const EVP_MD* md)
- {
- if (ctx == NULL) return 0;
- WOLFSSL_ENTER("EVP_PKEY_CTX_set_signature_md");
- #ifndef NO_RSA
- ctx->md = md;
- #else
- (void)md;
- #endif
- return WOLFSSL_SUCCESS;
- }
- /* create a PKEY context and return it */
- WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new_id(int id, WOLFSSL_ENGINE *e)
- {
- WOLFSSL_EVP_PKEY* pkey;
- WOLFSSL_EVP_PKEY_CTX* ctx = NULL;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_new_id");
- pkey = wolfSSL_EVP_PKEY_new_ex(NULL);
- if (pkey) {
- pkey->type = id;
- ctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e);
- /* wolfSSL_EVP_PKEY_CTX_new calls wolfSSL_EVP_PKEY_up_ref so we need
- * to always call wolfSSL_EVP_PKEY_free (either to free it if an
- * error occurred in the previous function or to decrease the reference
- * count so that pkey is actually free'd when wolfSSL_EVP_PKEY_CTX_free
- * is called) */
- wolfSSL_EVP_PKEY_free(pkey);
- }
- return ctx;
- }
- /* Returns WOLFSSL_SUCCESS or error */
- int wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits(WOLFSSL_EVP_PKEY_CTX *ctx, int bits)
- {
- if (ctx) {
- ctx->nbits = bits;
- }
- return WOLFSSL_SUCCESS;
- }
- int wolfSSL_EVP_PKEY_derive_init(WOLFSSL_EVP_PKEY_CTX *ctx)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_derive_init");
- if (!ctx) {
- return WOLFSSL_FAILURE;
- }
- wolfSSL_EVP_PKEY_free(ctx->peerKey);
- ctx->op = EVP_PKEY_OP_DERIVE;
- ctx->padding = 0;
- ctx->nbits = 0;
- return WOLFSSL_SUCCESS;
- }
- int wolfSSL_EVP_PKEY_derive_set_peer(WOLFSSL_EVP_PKEY_CTX *ctx, WOLFSSL_EVP_PKEY *peer)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_derive_set_peer");
- if (!ctx || ctx->op != EVP_PKEY_OP_DERIVE) {
- return WOLFSSL_FAILURE;
- }
- wolfSSL_EVP_PKEY_free(ctx->peerKey);
- ctx->peerKey = peer;
- if (!wolfSSL_EVP_PKEY_up_ref(peer)) {
- ctx->peerKey = NULL;
- return WOLFSSL_FAILURE;
- }
- return WOLFSSL_SUCCESS;
- }
- #ifndef NO_WOLFSSL_STUB
- int wolfSSL_EVP_PKEY_CTX_ctrl_str(WOLFSSL_EVP_PKEY_CTX *ctx,
- const char *name, const char *value)
- {
- WOLFSSL_STUB("wolfSSL_EVP_PKEY_CTX_ctrl_str");
- (void)ctx;
- (void)name;
- (void)value;
- return WOLFSSL_FAILURE;
- }
- #endif /* NO_WOLFSSL_STUB */
- #if (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || defined(HAVE_ECC) || \
- defined(HAVE_HKDF)
- int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
- {
- int len;
- #ifdef HAVE_HKDF
- enum wc_HashType hkdfHashType;
- int hkdfHashSz;
- #endif
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_derive");
- if (!ctx || ctx->op != EVP_PKEY_OP_DERIVE || !ctx->pkey || (!ctx->peerKey
- && ctx->pkey->type != EVP_PKEY_HKDF) || !keylen || (ctx->pkey->type
- != EVP_PKEY_HKDF && ctx->pkey->type != ctx->peerKey->type)) {
- return WOLFSSL_FAILURE;
- }
- switch (ctx->pkey->type) {
- #ifndef NO_DH
- case EVP_PKEY_DH:
- /* Use DH */
- if (!ctx->pkey->dh || !ctx->peerKey->dh) {
- return WOLFSSL_FAILURE;
- }
- /* set internal peer key if not done */
- if (!ctx->peerKey->dh->inSet) {
- if (SetDhInternal(ctx->peerKey->dh) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("SetDhInternal failed");
- return WOLFSSL_FAILURE;
- }
- }
- if (!ctx->peerKey->dh->pub_key) {
- WOLFSSL_MSG("SetDhInternal failed, pub_key is NULL");
- return WOLFSSL_FAILURE;
- }
- if ((len = wolfSSL_DH_size(ctx->pkey->dh)) <= 0) {
- return WOLFSSL_FAILURE;
- }
- if (key) {
- if (*keylen < (size_t)len) {
- return WOLFSSL_FAILURE;
- }
- /* computed DH agreement can be less than DH size if leading zeros */
- if (wolfSSL_DH_compute_key(key, ctx->peerKey->dh->pub_key,
- ctx->pkey->dh) <= 0) {
- return WOLFSSL_FAILURE;
- }
- }
- *keylen = (size_t)len;
- break;
- #endif
- #if defined(HAVE_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
- case EVP_PKEY_EC:
- /* Use ECDH */
- if (!ctx->pkey->ecc || !ctx->peerKey->ecc) {
- return WOLFSSL_FAILURE;
- }
- /* set internal key if not done */
- if (!ctx->pkey->ecc->inSet) {
- if (SetECKeyInternal(ctx->pkey->ecc) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("SetECKeyInternal failed");
- return WOLFSSL_FAILURE;
- }
- }
- if (!ctx->peerKey->ecc->exSet || !ctx->peerKey->ecc->pub_key->internal) {
- if (SetECKeyExternal(ctx->peerKey->ecc) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("SetECKeyExternal failed");
- return WOLFSSL_FAILURE;
- }
- }
- if (!(len = wc_ecc_size((ecc_key*)ctx->pkey->ecc->internal))) {
- return WOLFSSL_FAILURE;
- }
- if (key) {
- word32 len32 = (word32)len;
- #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) \
- && (!defined(HAVE_FIPS) || \
- (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2))
- WC_RNG rng;
- if (wc_InitRng(&rng) != MP_OKAY) {
- WOLFSSL_MSG("Init RNG failed");
- return WOLFSSL_FAILURE;
- }
- ((ecc_key*)ctx->pkey->ecc->internal)->rng = &rng;
- #endif
- if (*keylen < len32) {
- WOLFSSL_MSG("buffer too short");
- #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) \
- && (!defined(HAVE_FIPS) || \
- (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2))
- ((ecc_key*)ctx->pkey->ecc->internal)->rng = NULL;
- wc_FreeRng(&rng);
- #endif
- return WOLFSSL_FAILURE;
- }
- if (wc_ecc_shared_secret_ssh((ecc_key*)ctx->pkey->ecc->internal,
- (ecc_point*)ctx->peerKey->ecc->pub_key->internal,
- key, &len32) != MP_OKAY) {
- WOLFSSL_MSG("wc_ecc_shared_secret failed");
- #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) \
- && (!defined(HAVE_FIPS) || \
- (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2))
- ((ecc_key*)ctx->pkey->ecc->internal)->rng = NULL;
- wc_FreeRng(&rng);
- #endif
- return WOLFSSL_FAILURE;
- }
- #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) \
- && (!defined(HAVE_FIPS) || \
- (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2))
- ((ecc_key*)ctx->pkey->ecc->internal)->rng = NULL;
- wc_FreeRng(&rng);
- #endif
- len = (int)len32;
- }
- *keylen = (size_t)len;
- break;
- #endif
- #ifdef HAVE_HKDF
- case EVP_PKEY_HKDF:
- (void)len;
- hkdfHashType = EvpMd2MacType(ctx->pkey->hkdfMd);
- if (hkdfHashType == WC_HASH_TYPE_NONE) {
- WOLFSSL_MSG("Invalid hash type for HKDF.");
- return WOLFSSL_FAILURE;
- }
- if (ctx->pkey->hkdfMode == EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) {
- if (wc_HKDF(hkdfHashType, ctx->pkey->hkdfKey, ctx->pkey->hkdfKeySz,
- ctx->pkey->hkdfSalt, ctx->pkey->hkdfSaltSz,
- ctx->pkey->hkdfInfo, ctx->pkey->hkdfInfoSz, key,
- (word32)*keylen) != 0) {
- WOLFSSL_MSG("wc_HKDF failed.");
- return WOLFSSL_FAILURE;
- }
- }
- else if (ctx->pkey->hkdfMode == EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) {
- if (wc_HKDF_Extract(hkdfHashType, ctx->pkey->hkdfSalt,
- ctx->pkey->hkdfSaltSz, ctx->pkey->hkdfKey,
- ctx->pkey->hkdfKeySz, key) != 0) {
- WOLFSSL_MSG("wc_HKDF_Extract failed.");
- return WOLFSSL_FAILURE;
- }
- else {
- hkdfHashSz = wolfSSL_EVP_MD_size(ctx->pkey->hkdfMd);
- if (hkdfHashSz <= 0) {
- WOLFSSL_MSG("Failed to get block size for HKDF hash.");
- return WOLFSSL_FAILURE;
- }
- /* Length of extract only is always the length of the hash. */
- *keylen = hkdfHashSz;
- }
- }
- else if (ctx->pkey->hkdfMode == EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) {
- if (wc_HKDF_Expand(hkdfHashType, ctx->pkey->hkdfKey,
- ctx->pkey->hkdfKeySz, ctx->pkey->hkdfInfo,
- ctx->pkey->hkdfInfoSz, key,
- (word32)*keylen) != 0) {
- WOLFSSL_MSG("wc_HKDF_Expand failed.");
- return WOLFSSL_FAILURE;
- }
- }
- else {
- WOLFSSL_MSG("Invalid HKDF mode.");
- return WOLFSSL_FAILURE;
- }
- break;
- #endif /* HAVE_HKDF */
- default:
- WOLFSSL_MSG("Unknown key type");
- return WOLFSSL_FAILURE;
- }
- return WOLFSSL_SUCCESS;
- }
- #endif /* (!NO_DH && WOLFSSL_DH_EXTRA) || HAVE_ECC || HAVE_HKDF */
- #ifdef HAVE_HKDF
- int wolfSSL_EVP_PKEY_CTX_set_hkdf_md(WOLFSSL_EVP_PKEY_CTX* ctx,
- const WOLFSSL_EVP_MD* md)
- {
- int ret = WOLFSSL_SUCCESS;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_set_hkdf_md");
- if (ctx == NULL || ctx->pkey == NULL || md == NULL) {
- WOLFSSL_MSG("Bad argument.");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS) {
- ctx->pkey->hkdfMd = md;
- }
- WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_CTX_set_hkdf_md", ret);
- return ret;
- }
- int wolfSSL_EVP_PKEY_CTX_set1_hkdf_salt(WOLFSSL_EVP_PKEY_CTX* ctx, byte* salt,
- int saltSz)
- {
- int ret = WOLFSSL_SUCCESS;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_set1_hkdf_salt");
- if (ctx == NULL || ctx->pkey == NULL || saltSz < 0) {
- WOLFSSL_MSG("Bad argument.");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS && ctx->pkey->type != EVP_PKEY_HKDF) {
- WOLFSSL_MSG("WOLFSSL_EVP_PKEY type is not HKDF.");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS && salt != NULL && saltSz > 0) {
- if (ctx->pkey->hkdfSalt != NULL) {
- XFREE(ctx->pkey->hkdfSalt, NULL, DYNAMIC_TYPE_SALT);
- }
- ctx->pkey->hkdfSalt = (byte*)XMALLOC(saltSz, NULL, DYNAMIC_TYPE_SALT);
- if (ctx->pkey->hkdfSalt == NULL) {
- WOLFSSL_MSG("Failed to allocate HKDF salt buffer.");
- ret = WOLFSSL_FAILURE;
- }
- else {
- XMEMCPY(ctx->pkey->hkdfSalt, salt, saltSz);
- ctx->pkey->hkdfSaltSz = saltSz;
- }
- }
- WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_CTX_set1_hkdf_salt", ret);
- return ret;
- }
- int wolfSSL_EVP_PKEY_CTX_set1_hkdf_key(WOLFSSL_EVP_PKEY_CTX* ctx, byte* key,
- int keySz)
- {
- int ret = WOLFSSL_SUCCESS;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_set1_hkdf_key");
- if (ctx == NULL || ctx->pkey == NULL || key == NULL || keySz <= 0) {
- WOLFSSL_MSG("Bad argument.");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS && ctx->pkey->type != EVP_PKEY_HKDF) {
- WOLFSSL_MSG("WOLFSSL_EVP_PKEY type is not HKDF.");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS) {
- if (ctx->pkey->hkdfKey != NULL) {
- XFREE(ctx->pkey->hkdfKey, NULL, DYNAMIC_TYPE_KEY);
- }
- ctx->pkey->hkdfKey = (byte*)XMALLOC(keySz, NULL, DYNAMIC_TYPE_KEY);
- if (ctx->pkey->hkdfKey == NULL) {
- WOLFSSL_MSG("Failed to allocate HKDF key buffer.");
- ret = WOLFSSL_FAILURE;
- }
- else {
- XMEMCPY(ctx->pkey->hkdfKey, key, keySz);
- ctx->pkey->hkdfKeySz = keySz;
- }
- }
- WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_CTX_set1_hkdf_key", ret);
- return ret;
- }
- int wolfSSL_EVP_PKEY_CTX_add1_hkdf_info(WOLFSSL_EVP_PKEY_CTX* ctx, byte* info,
- int infoSz)
- {
- int ret = WOLFSSL_SUCCESS;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_add1_hkdf_info");
- if (ctx == NULL || ctx->pkey == NULL || infoSz < 0) {
- WOLFSSL_MSG("Bad argument.");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS && ctx->pkey->type != EVP_PKEY_HKDF) {
- WOLFSSL_MSG("WOLFSSL_EVP_PKEY type is not HKDF.");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS && info != NULL && infoSz > 0) {
- /* If there's already info in the buffer, append. */
- ctx->pkey->hkdfInfo = (byte*)XREALLOC(ctx->pkey->hkdfInfo,
- ctx->pkey->hkdfInfoSz + infoSz, NULL, DYNAMIC_TYPE_INFO);
- if (ctx->pkey->hkdfInfo == NULL) {
- WOLFSSL_MSG("Failed to reallocate larger HKDF info buffer.");
- ret = WOLFSSL_FAILURE;
- }
- else {
- XMEMCPY(ctx->pkey->hkdfInfo + ctx->pkey->hkdfInfoSz, info,
- infoSz);
- ctx->pkey->hkdfInfoSz += infoSz;
- }
- }
- WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_CTX_add1_hkdf_info", ret);
- return ret;
- }
- int wolfSSL_EVP_PKEY_CTX_hkdf_mode(WOLFSSL_EVP_PKEY_CTX* ctx, int mode)
- {
- int ret = WOLFSSL_SUCCESS;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_hkdf_mode");
- if (ctx == NULL || ctx->pkey == NULL) {
- WOLFSSL_MSG("Bad argument.");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS &&
- mode != EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND &&
- mode != EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY &&
- mode != EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) {
- WOLFSSL_MSG("Invalid HKDF mode.");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS) {
- ctx->pkey->hkdfMode = mode;
- }
- WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_CTX_hkdf_mode", ret);
- return ret;
- }
- #endif /* HAVE_HKDF */
- /* Uses the WOLFSSL_EVP_PKEY_CTX to decrypt a buffer.
- *
- * ctx EVP_PKEY context of operation.
- * out Decrypted output buffer. If NULL, puts the maximum output buffer size
- in outLen and returns success.
- * outLen If out is NULL, see above. If out is non-NULL, on input outLen holds
- * the size of out. On output holds the length of actual decryption.
- * in Encrypted input buffer.
- * inLen Length of encrypted data.
- *
- * Returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure.
- */
- int wolfSSL_EVP_PKEY_decrypt(WOLFSSL_EVP_PKEY_CTX *ctx,
- unsigned char *out, size_t *outLen,
- const unsigned char *in, size_t inLen)
- {
- int len = 0;
- WOLFSSL_ENTER("EVP_PKEY_decrypt");
- if (ctx == NULL || ctx->pkey == NULL) {
- WOLFSSL_MSG("Bad parameter.");
- return 0;
- }
- (void)out;
- (void)outLen;
- (void)in;
- (void)inLen;
- (void)len;
- switch (ctx->pkey->type) {
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA:
- if (out == NULL) {
- if (ctx->pkey->rsa == NULL) {
- WOLFSSL_MSG("Internal wolfCrypt RSA object is NULL.");
- return WOLFSSL_FAILURE;
- }
- len = wolfSSL_RSA_size(ctx->pkey->rsa);
- if (len <= 0) {
- WOLFSSL_MSG("Error getting RSA size.");
- return WOLFSSL_FAILURE;
- }
- if (outLen == NULL) {
- WOLFSSL_MSG("outLen is NULL.");
- return WOLFSSL_FAILURE;
- }
- *outLen = len;
- return WOLFSSL_SUCCESS;
- }
- len = wolfSSL_RSA_private_decrypt((int)inLen, (unsigned char*)in, out,
- ctx->pkey->rsa, ctx->padding);
- if (len < 0) break;
- else {
- *outLen = len;
- return WOLFSSL_SUCCESS;
- }
- #endif /* NO_RSA */
- case EVP_PKEY_EC:
- WOLFSSL_MSG("EVP_PKEY_EC not implemented.");
- FALL_THROUGH;
- default:
- break;
- }
- return WOLFSSL_FAILURE;
- }
- /* Initialize a WOLFSSL_EVP_PKEY_CTX structure for decryption
- *
- * ctx WOLFSSL_EVP_PKEY_CTX structure to use with decryption
- *
- * Returns WOLFSSL_FAILURE on failure and WOLFSSL_SUCCESS on success
- */
- int wolfSSL_EVP_PKEY_decrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx)
- {
- if (ctx == NULL) return WOLFSSL_FAILURE;
- WOLFSSL_ENTER("EVP_PKEY_decrypt_init");
- switch (ctx->pkey->type) {
- case EVP_PKEY_RSA:
- ctx->op = EVP_PKEY_OP_DECRYPT;
- return WOLFSSL_SUCCESS;
- case EVP_PKEY_EC:
- WOLFSSL_MSG("not implemented");
- FALL_THROUGH;
- default:
- break;
- }
- return WOLFSSL_FAILURE;
- }
- /* Uses the WOLFSSL_EVP_PKEY_CTX to encrypt a buffer.
- *
- * ctx EVP_PKEY context of operation.
- * out Encrypted output buffer. If NULL, puts the maximum output buffer size
- * in outlen and returns success.
- * outLen If out is NULL, see above. If out is non-NULL, on input outLen holds
- * the size of out. On output holds the length of actual encryption.
- * in Plaintext input buffer.
- * inLen Length of plaintext.
- *
- * Returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure.
- */
- int wolfSSL_EVP_PKEY_encrypt(WOLFSSL_EVP_PKEY_CTX *ctx,
- unsigned char *out, size_t *outLen,
- const unsigned char *in, size_t inLen)
- {
- int len = 0;
- WOLFSSL_ENTER("EVP_PKEY_encrypt");
- if (ctx == NULL || ctx->pkey == NULL) {
- WOLFSSL_MSG("Bad parameter.");
- return 0;
- }
- if (ctx->op != EVP_PKEY_OP_ENCRYPT) {
- WOLFSSL_MSG("ctx->op must be set to EVP_PKEY_OP_ENCRYPT. Use "
- "wolfSSL_EVP_PKEY_encrypt_init.");
- return WOLFSSL_FAILURE;
- }
- (void)out;
- (void)outLen;
- (void)in;
- (void)inLen;
- (void)len;
- switch (ctx->pkey->type) {
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA:
- if (out == NULL) {
- if (ctx->pkey->rsa == NULL) {
- WOLFSSL_MSG("Internal wolfCrypt RSA object is NULL.");
- return WOLFSSL_FAILURE;
- }
- len = wolfSSL_RSA_size(ctx->pkey->rsa);
- if (len <= 0) {
- WOLFSSL_MSG("Error getting RSA size.");
- return WOLFSSL_FAILURE;
- }
- if (outLen == NULL) {
- WOLFSSL_MSG("outLen is NULL.");
- return WOLFSSL_FAILURE;
- }
- *outLen = len;
- return WOLFSSL_SUCCESS;
- }
- len = wolfSSL_RSA_public_encrypt((int)inLen, (unsigned char *)in, out,
- ctx->pkey->rsa, ctx->padding);
- if (len < 0)
- break;
- else {
- *outLen = len;
- return WOLFSSL_SUCCESS;
- }
- #endif /* NO_RSA */
- case EVP_PKEY_EC:
- WOLFSSL_MSG("EVP_PKEY_EC not implemented");
- FALL_THROUGH;
- default:
- break;
- }
- return WOLFSSL_FAILURE;
- }
- /* Initialize a WOLFSSL_EVP_PKEY_CTX structure to encrypt data
- *
- * ctx WOLFSSL_EVP_PKEY_CTX structure to use with encryption
- *
- * Returns WOLFSSL_FAILURE on failure and WOLFSSL_SUCCESS on success
- */
- int wolfSSL_EVP_PKEY_encrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx)
- {
- if (ctx == NULL) return WOLFSSL_FAILURE;
- WOLFSSL_ENTER("EVP_PKEY_encrypt_init");
- switch (ctx->pkey->type) {
- case EVP_PKEY_RSA:
- ctx->op = EVP_PKEY_OP_ENCRYPT;
- return WOLFSSL_SUCCESS;
- case EVP_PKEY_EC:
- WOLFSSL_MSG("not implemented");
- FALL_THROUGH;
- default:
- break;
- }
- return WOLFSSL_FAILURE;
- }
- /******************************************************************************
- * wolfSSL_EVP_PKEY_sign_init - initializes a public key algorithm context for
- * a signing operation.
- *
- * RETURNS:
- * returns WOLFSSL_SUCCESS on success, otherwise returns -2
- */
- int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx)
- {
- int ret = -2;
- WOLFSSL_MSG("wolfSSL_EVP_PKEY_sign_init");
- if (!ctx || !ctx->pkey)
- return ret;
- switch (ctx->pkey->type) {
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA:
- ctx->op = EVP_PKEY_OP_SIGN;
- ret = WOLFSSL_SUCCESS;
- break;
- #endif /* NO_RSA */
- #ifndef NO_DSA
- case EVP_PKEY_DSA:
- ctx->op = EVP_PKEY_OP_SIGN;
- ret = WOLFSSL_SUCCESS;
- break;
- #endif /* NO_DSA */
- #ifdef HAVE_ECC
- case EVP_PKEY_EC:
- ctx->op = EVP_PKEY_OP_SIGN;
- ret = WOLFSSL_SUCCESS;
- break;
- #endif /* HAVE_ECC */
- default:
- ret = -2;
- }
- return ret;
- }
- /******************************************************************************
- * wolfSSL_EVP_PKEY_sign - performs a public key signing operation using ctx
- * The data to be signed should be hashed since the function does not hash the data.
- *
- * RETURNS:
- * returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
- */
- int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *sig,
- size_t *siglen, const unsigned char *tbs, size_t tbslen)
- {
- WOLFSSL_MSG("wolfSSL_EVP_PKEY_sign");
- if (!ctx || ctx->op != EVP_PKEY_OP_SIGN || !ctx->pkey || !siglen)
- return WOLFSSL_FAILURE;
- (void)sig;
- (void)siglen;
- (void)tbs;
- (void)tbslen;
- switch (ctx->pkey->type) {
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA: {
- int len;
- unsigned int usiglen = (unsigned int)*siglen;
- if (!sig) {
- if (!ctx->pkey->rsa)
- return WOLFSSL_FAILURE;
- len = wc_RsaEncryptSize((RsaKey*)ctx->pkey->rsa->internal);
- if (len < 0)
- return WOLFSSL_FAILURE;
- *siglen = (size_t)len;
- return WOLFSSL_SUCCESS;
- }
- /* wolfSSL_RSA_sign_generic_padding performs a check that the output
- * sig buffer is large enough */
- if (wolfSSL_RSA_sign_generic_padding(wolfSSL_EVP_MD_type(ctx->md), tbs,
- (unsigned int)tbslen, sig, &usiglen, ctx->pkey->rsa, 1,
- ctx->padding) != WOLFSSL_SUCCESS) {
- return WOLFSSL_FAILURE;
- }
- *siglen = (size_t)usiglen;
- return WOLFSSL_SUCCESS;
- }
- #endif /* NO_RSA */
- #ifndef NO_DSA
- case EVP_PKEY_DSA: {
- int bytes;
- int ret;
- if (!ctx->pkey->dsa)
- return WOLFSSL_FAILURE;
- bytes = wolfSSL_BN_num_bytes(ctx->pkey->dsa->q);
- if (bytes == WOLFSSL_FAILURE)
- return WOLFSSL_FAILURE;
- bytes *= 2;
- if (!sig) {
- *siglen = bytes;
- return WOLFSSL_SUCCESS;
- }
- if ((int)*siglen < bytes)
- return WOLFSSL_FAILURE;
- ret = wolfSSL_DSA_do_sign(tbs, sig, ctx->pkey->dsa);
- /* wolfSSL_DSA_do_sign() can return WOLFSSL_FATAL_ERROR */
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- if (bytes == WOLFSSL_FAILURE)
- return WOLFSSL_FAILURE;
- *siglen = bytes;
- return WOLFSSL_SUCCESS;
- }
- #endif /* NO_DSA */
- #ifdef HAVE_ECC
- case EVP_PKEY_EC: {
- int ret;
- WOLFSSL_ECDSA_SIG *ecdsaSig;
- if (!sig) {
- WOLFSSL_EC_KEY *key = ctx->pkey->ecc;
- ecc_key* eckey;
- if (!key)
- return WOLFSSL_FAILURE;
- /* set internal key if not done */
- if (key->inSet == 0 && SetECKeyInternal(key) != WOLFSSL_SUCCESS)
- return WOLFSSL_FAILURE;
- eckey = (ecc_key*)ctx->pkey->ecc->internal;
- if (!eckey)
- return WOLFSSL_FAILURE;
- ret = wc_ecc_sig_size(eckey);
- if (ret == 0)
- return WOLFSSL_FAILURE;
- *siglen = ret;
- return WOLFSSL_SUCCESS;
- }
- ecdsaSig = wolfSSL_ECDSA_do_sign(tbs, (int)tbslen, ctx->pkey->ecc);
- if (ecdsaSig == NULL)
- return WOLFSSL_FAILURE;
- ret = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, NULL);
- if (ret == 0 || ret > (int)*siglen) {
- wolfSSL_ECDSA_SIG_free(ecdsaSig);
- return WOLFSSL_FAILURE;
- }
- ret = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig);
- wolfSSL_ECDSA_SIG_free(ecdsaSig);
- if (ret == 0)
- return WOLFSSL_FAILURE;
- *siglen = ret;
- return WOLFSSL_SUCCESS;
- }
- #endif /* HAVE_ECC */
- default:
- break;
- }
- return WOLFSSL_FAILURE;
- }
- /******************************************************************************
- * wolfSSL_EVP_PKEY_verify_init - initializes a public key algorithm context for
- * a verification operation.
- *
- * RETURNS:
- * returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. In particular
- * a return value of -2 indicates the operation is not supported by the public
- * key algorithm.
- */
- int wolfSSL_EVP_PKEY_verify_init(WOLFSSL_EVP_PKEY_CTX *ctx)
- {
- WOLFSSL_MSG("wolfSSL_EVP_PKEY_verify_init");
- if (!ctx || !ctx->pkey)
- return WOLFSSL_FAILURE;
- switch (ctx->pkey->type) {
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA:
- ctx->op = EVP_PKEY_OP_VERIFY;
- return WOLFSSL_SUCCESS;
- #endif /* NO_RSA */
- #ifndef NO_DSA
- case EVP_PKEY_DSA:
- ctx->op = EVP_PKEY_OP_VERIFY;
- return WOLFSSL_SUCCESS;
- #endif /* NO_DSA */
- #ifdef HAVE_ECC
- case EVP_PKEY_EC:
- ctx->op = EVP_PKEY_OP_VERIFY;
- return WOLFSSL_SUCCESS;
- #endif /* HAVE_ECC */
- default:
- return -2;
- }
- }
- /******************************************************************************
- * wolfSSL_EVP_PKEY_verify - verifies a signature using ctx
- *
- * RETURNS:
- * returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. In particular
- * a return value of -2 indicates the operation is not supported by the public
- * key algorithm.
- */
- int wolfSSL_EVP_PKEY_verify(WOLFSSL_EVP_PKEY_CTX *ctx, const unsigned char *sig,
- size_t siglen, const unsigned char *tbs,
- size_t tbslen)
- {
- WOLFSSL_MSG("wolfSSL_EVP_PKEY_verify");
- if (!ctx || ctx->op != EVP_PKEY_OP_VERIFY || !ctx->pkey)
- return WOLFSSL_FAILURE;
- switch (ctx->pkey->type) {
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA:
- return wolfSSL_RSA_verify_ex(WC_HASH_TYPE_NONE, tbs,
- (unsigned int)tbslen, sig, (unsigned int)siglen, ctx->pkey->rsa,
- ctx->padding);
- #endif /* NO_RSA */
- #ifndef NO_DSA
- case EVP_PKEY_DSA: {
- int dsacheck = 0;
- if (wolfSSL_DSA_do_verify(tbs, (unsigned char *)sig, ctx->pkey->dsa,
- &dsacheck) != WOLFSSL_SUCCESS || dsacheck != 1)
- return WOLFSSL_FAILURE;
- return WOLFSSL_SUCCESS;
- }
- #endif /* NO_DSA */
- #ifdef HAVE_ECC
- case EVP_PKEY_EC: {
- int ret;
- WOLFSSL_ECDSA_SIG *ecdsaSig = wolfSSL_d2i_ECDSA_SIG(
- NULL, (const unsigned char **)&sig, (long)siglen);
- if (ecdsaSig == NULL)
- return WOLFSSL_FAILURE;
- ret = wolfSSL_ECDSA_do_verify(tbs, (int)tbslen, ecdsaSig,
- ctx->pkey->ecc);
- wolfSSL_ECDSA_SIG_free(ecdsaSig);
- return ret;
- }
- #endif /* HAVE_ECC */
- default:
- return -2;
- }
- }
- /* Get the size in bits for WOLFSSL_EVP_PKEY key
- *
- * pkey WOLFSSL_EVP_PKEY structure to get key size of
- *
- * returns the size in bits of key on success
- */
- int wolfSSL_EVP_PKEY_bits(const WOLFSSL_EVP_PKEY *pkey)
- {
- int bytes;
- if (pkey == NULL) return 0;
- WOLFSSL_ENTER("EVP_PKEY_bits");
- if ((bytes = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey)) ==0) return 0;
- return bytes*8;
- }
- int wolfSSL_EVP_PKEY_paramgen_init(WOLFSSL_EVP_PKEY_CTX *ctx)
- {
- (void)ctx;
- return WOLFSSL_SUCCESS;
- }
- int wolfSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(WOLFSSL_EVP_PKEY_CTX *ctx,
- int nid)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid");
- #ifdef HAVE_ECC
- if (ctx != NULL && ctx->pkey != NULL && ctx->pkey->type == EVP_PKEY_EC) {
- ctx->curveNID = nid;
- return WOLFSSL_SUCCESS;
- }
- else
- #endif
- {
- #ifndef HAVE_ECC
- (void)ctx;
- (void)nid;
- WOLFSSL_MSG("Support not compiled in");
- #else
- WOLFSSL_MSG("Bad parameter");
- #endif
- return WOLFSSL_FAILURE;
- }
- }
- int wolfSSL_EVP_PKEY_paramgen(WOLFSSL_EVP_PKEY_CTX* ctx,
- WOLFSSL_EVP_PKEY** pkey)
- {
- int ret = WOLFSSL_SUCCESS;
- int ownPkey = 0;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_paramgen");
- if (ctx == NULL || pkey == NULL) {
- WOLFSSL_MSG("Bad parameter");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS && *pkey == NULL) {
- /* Only ECC is supported currently. */
- if (ctx->pkey == NULL || ctx->pkey->type != EVP_PKEY_EC) {
- WOLFSSL_MSG("Key not set or key type not supported.");
- ret = WOLFSSL_FAILURE;
- }
- else {
- *pkey = wolfSSL_EVP_PKEY_new();
- if (*pkey == NULL) {
- WOLFSSL_MSG("Failed to create WOLFSSL_EVP_PKEY.");
- ret = WOLFSSL_FAILURE;
- }
- else {
- (*pkey)->type = ctx->pkey->type;
- ownPkey = 1;
- }
- }
- }
- if (ret == WOLFSSL_SUCCESS) {
- switch ((*pkey)->type) {
- #ifdef HAVE_ECC
- /* For ECC parameter generation we just need to set the group, which
- * wolfSSL_EC_KEY_new_by_curve_name will do. */
- case EVP_PKEY_EC:
- (*pkey)->ecc = wolfSSL_EC_KEY_new_by_curve_name(ctx->curveNID);
- if ((*pkey)->ecc == NULL) {
- WOLFSSL_MSG("Failed to create WOLFSSL_EC_KEY.");
- ret = WOLFSSL_FAILURE;
- }
- else {
- (*pkey)->ownEcc = 1;
- }
- break;
- #endif
- default:
- ret = WOLFSSL_FAILURE;
- break;
- }
- }
- if (ret != WOLFSSL_SUCCESS && ownPkey) {
- wolfSSL_EVP_PKEY_free(*pkey);
- *pkey = NULL;
- }
- WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_paramgen", ret);
- return ret;
- }
- /* wolfSSL only supports writing out named curves so no need to store the flag.
- * In short, it is preferred to write out the name of the curve chosen instead
- * of the explicit parameters.
- * The difference is nicely explained and illustrated in section
- * "ECDH and Named Curves" of
- * https://wiki.openssl.org/index.php/Elliptic_Curve_Diffie_Hellman */
- int wolfSSL_EVP_PKEY_CTX_set_ec_param_enc(WOLFSSL_EVP_PKEY_CTX *ctx,
- int flag)
- {
- (void)ctx;
- (void)flag;
- return WOLFSSL_SUCCESS;
- }
- int wolfSSL_EVP_PKEY_keygen_init(WOLFSSL_EVP_PKEY_CTX *ctx)
- {
- (void)ctx;
- return WOLFSSL_SUCCESS;
- }
- int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
- WOLFSSL_EVP_PKEY **ppkey)
- {
- int ret = WOLFSSL_FAILURE;
- int ownPkey = 0;
- WOLFSSL_EVP_PKEY* pkey;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_keygen");
- if (ctx == NULL || ppkey == NULL) {
- return BAD_FUNC_ARG;
- }
- pkey = *ppkey;
- if (pkey == NULL) {
- if (ctx->pkey == NULL ||
- (ctx->pkey->type != EVP_PKEY_EC &&
- ctx->pkey->type != EVP_PKEY_RSA &&
- ctx->pkey->type != EVP_PKEY_DH)) {
- WOLFSSL_MSG("Key not set or key type not supported");
- return BAD_FUNC_ARG;
- }
- pkey = wolfSSL_EVP_PKEY_new();
- if (pkey == NULL) {
- return MEMORY_E;
- }
- ownPkey = 1;
- pkey->type = ctx->pkey->type;
- }
- switch (pkey->type) {
- #if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
- !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA:
- pkey->rsa = wolfSSL_RSA_generate_key(ctx->nbits, WC_RSA_EXPONENT,
- NULL, NULL);
- if (pkey->rsa) {
- pkey->ownRsa = 1;
- pkey->pkey_sz = wolfSSL_i2d_RSAPrivateKey(pkey->rsa,
- (unsigned char**)&pkey->pkey.ptr);
- ret = WOLFSSL_SUCCESS;
- }
- break;
- #endif
- #ifdef HAVE_ECC
- case EVP_PKEY_EC:
- /* pkey->ecc may not be NULL, if, for example, it was populated by a
- * prior call to wolfSSL_EVP_PKEY_paramgen. */
- if (pkey->ecc == NULL) {
- pkey->ecc = wolfSSL_EC_KEY_new_by_curve_name(ctx->curveNID);
- }
- if (pkey->ecc) {
- ret = wolfSSL_EC_KEY_generate_key(pkey->ecc);
- if (ret == WOLFSSL_SUCCESS) {
- pkey->ownEcc = 1;
- }
- }
- break;
- #endif
- #if !defined(NO_DH) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
- case EVP_PKEY_DH:
- pkey->dh = wolfSSL_DH_new();
- if (pkey->dh) {
- pkey->ownDh = 1;
- /* load DH params from CTX */
- ret = wolfSSL_DH_LoadDer(pkey->dh,
- (const unsigned char*)ctx->pkey->pkey.ptr,
- ctx->pkey->pkey_sz);
- if (ret == WOLFSSL_SUCCESS) {
- ret = wolfSSL_DH_generate_key(pkey->dh);
- }
- if (ret == WOLFSSL_SUCCESS) {
- /* copy private/public key from external to internal */
- ret = SetDhInternal(pkey->dh);
- }
- }
- break;
- #endif
- default:
- break;
- }
- if (ret != WOLFSSL_SUCCESS && ownPkey) {
- wolfSSL_EVP_PKEY_free(pkey);
- pkey = NULL;
- }
- *ppkey = pkey;
- return ret;
- }
- /* Get the size in bytes for WOLFSSL_EVP_PKEY key
- *
- * pkey WOLFSSL_EVP_PKEY structure to get key size of
- *
- * returns the size of a key on success which is the maximum size of a
- * signature
- */
- int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey)
- {
- if (pkey == NULL) return 0;
- WOLFSSL_ENTER("EVP_PKEY_size");
- switch (pkey->type) {
- #ifndef NO_RSA
- case EVP_PKEY_RSA:
- return (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(pkey->rsa));
- #endif /* !NO_RSA */
- #ifndef NO_DSA
- case EVP_PKEY_DSA:
- if (pkey->dsa == NULL ||
- (!pkey->dsa->exSet &&
- SetDsaExternal(pkey->dsa) != WOLFSSL_SUCCESS))
- return WOLFSSL_FAILURE;
- return wolfSSL_BN_num_bytes(pkey->dsa->p);
- #endif
- #ifdef HAVE_ECC
- case EVP_PKEY_EC:
- if (pkey->ecc == NULL || pkey->ecc->internal == NULL) {
- WOLFSSL_MSG("No ECC key has been set");
- break;
- }
- return wc_ecc_size((ecc_key*)(pkey->ecc->internal));
- #endif /* HAVE_ECC */
- default:
- break;
- }
- return 0;
- }
- int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to,
- const WOLFSSL_EVP_PKEY *from)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_copy_parameters");
- if (!to || !from) {
- WOLFSSL_MSG("Bad parameter");
- return WOLFSSL_FAILURE;
- }
- if (to->type == EVP_PKEY_NONE) {
- to->type = from->type;
- }
- else if (to->type != from->type) {
- WOLFSSL_MSG("Different key types");
- return WOLFSSL_FAILURE;
- }
- switch(from->type) {
- #ifdef HAVE_ECC
- case EVP_PKEY_EC:
- if (from->ecc) {
- if (!to->ecc) {
- if ((to->ecc = wolfSSL_EC_KEY_new()) == NULL) {
- WOLFSSL_MSG("wolfSSL_EC_KEY_new error");
- return WOLFSSL_FAILURE;
- }
- to->ownEcc = 1;
- }
- to->ecc->group->curve_idx = from->ecc->group->curve_idx;
- to->ecc->group->curve_nid = from->ecc->group->curve_nid;
- to->ecc->group->curve_oid = from->ecc->group->curve_oid;
- }
- else {
- WOLFSSL_MSG("Missing ECC struct");
- return WOLFSSL_FAILURE;
- }
- break;
- #endif
- #ifndef NO_DSA
- case EVP_PKEY_DSA:
- if (from->dsa) {
- WOLFSSL_BIGNUM* cpy;
- if (!to->dsa) {
- if ((to->dsa = wolfSSL_DSA_new()) == NULL) {
- WOLFSSL_MSG("wolfSSL_DSA_new error");
- return WOLFSSL_FAILURE;
- }
- to->ownDsa = 1;
- }
- /* free existing BIGNUMs if needed before copying over new */
- wolfSSL_BN_free(to->dsa->p);
- wolfSSL_BN_free(to->dsa->g);
- wolfSSL_BN_free(to->dsa->q);
- to->dsa->p = NULL;
- to->dsa->g = NULL;
- to->dsa->q = NULL;
- if (!(cpy = wolfSSL_BN_dup(from->dsa->p))) {
- WOLFSSL_MSG("wolfSSL_BN_dup error");
- return WOLFSSL_FAILURE;
- }
- to->dsa->p = cpy;
- if (!(cpy = wolfSSL_BN_dup(from->dsa->q))) {
- WOLFSSL_MSG("wolfSSL_BN_dup error");
- return WOLFSSL_FAILURE;
- }
- to->dsa->q = cpy;
- if (!(cpy = wolfSSL_BN_dup(from->dsa->g))) {
- WOLFSSL_MSG("wolfSSL_BN_dup error");
- return WOLFSSL_FAILURE;
- }
- to->dsa->g = cpy;
- }
- else {
- WOLFSSL_MSG("Missing DSA struct");
- return WOLFSSL_FAILURE;
- }
- break;
- #endif
- #ifndef NO_DH
- case EVP_PKEY_DH:
- if (from->dh) {
- WOLFSSL_BIGNUM* cpy;
- if (!to->dh) {
- if ((to->dh = wolfSSL_DH_new()) == NULL) {
- WOLFSSL_MSG("wolfSSL_DH_new error");
- return WOLFSSL_FAILURE;
- }
- to->ownDh = 1;
- }
- /* free existing BIGNUMs if needed before copying over new */
- wolfSSL_BN_free(to->dh->p);
- wolfSSL_BN_free(to->dh->g);
- wolfSSL_BN_free(to->dh->q);
- to->dh->p = NULL;
- to->dh->g = NULL;
- to->dh->q = NULL;
- if (!(cpy = wolfSSL_BN_dup(from->dh->p))) {
- WOLFSSL_MSG("wolfSSL_BN_dup error, DH p");
- return WOLFSSL_FAILURE;
- }
- to->dh->p = cpy;
- if (!(cpy = wolfSSL_BN_dup(from->dh->g))) {
- WOLFSSL_MSG("wolfSSL_BN_dup error, DH g");
- return WOLFSSL_FAILURE;
- }
- to->dh->g = cpy;
- if (!(cpy = wolfSSL_BN_dup(from->dh->q))) {
- WOLFSSL_MSG("wolfSSL_BN_dup error, DH q");
- return WOLFSSL_FAILURE;
- }
- to->dh->q = cpy;
- }
- else {
- WOLFSSL_MSG("Missing DH struct");
- return WOLFSSL_FAILURE;
- }
- break;
- #endif
- #ifndef NO_RSA
- case EVP_PKEY_RSA:
- #endif
- default:
- WOLFSSL_MSG("Copy parameters not available for this key type");
- return WOLFSSL_FAILURE;
- }
- return WOLFSSL_SUCCESS;
- }
- #ifndef NO_WOLFSSL_STUB
- int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey)
- {
- (void)pkey;
- /* not using missing params callback and returning zero to indicate success */
- return 0;
- }
- #endif
- /* wolfSSL_EVP_PKEY_cmp
- * returns 0 on success, -1 on failure.
- *
- * This behavior is different from openssl.
- * EVP_PKEY_cmp returns:
- * 1 : two keys match
- * 0 : do not match
- * -1: key types are different
- * -2: the operation is not supported
- * If you want this function behave the same as openSSL,
- * define WOLFSSL_ERROR_CODE_OPENSSL so that WS_RETURN_CODE translates return
- * codes to match OpenSSL equivalent behavior.
- */
- int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b)
- {
- int ret = -1; /* failure */
- int a_sz = 0, b_sz = 0;
- if (a == NULL || b == NULL)
- return WS_RETURN_CODE(ret, WOLFSSL_FAILURE);
- /* check its the same type of key */
- if (a->type != b->type)
- return WS_RETURN_CODE(ret, -1);
- /* get size based on key type */
- switch (a->type) {
- #ifndef NO_RSA
- case EVP_PKEY_RSA:
- a_sz = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(a->rsa));
- b_sz = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(b->rsa));
- break;
- #endif /* !NO_RSA */
- #ifdef HAVE_ECC
- case EVP_PKEY_EC:
- if (a->ecc == NULL || a->ecc->internal == NULL ||
- b->ecc == NULL || b->ecc->internal == NULL) {
- return ret;
- }
- a_sz = wc_ecc_size((ecc_key*)(a->ecc->internal));
- b_sz = wc_ecc_size((ecc_key*)(b->ecc->internal));
- break;
- #endif /* HAVE_ECC */
- default:
- return WS_RETURN_CODE(ret, -2);
- } /* switch (a->type) */
- /* check size */
- if (a_sz <= 0 || b_sz <= 0 || a_sz != b_sz) {
- return WS_RETURN_CODE(ret, WOLFSSL_FAILURE);
- }
- /* check public key size */
- if (a->pkey_sz > 0 && b->pkey_sz > 0 && a->pkey_sz != b->pkey_sz) {
- return WS_RETURN_CODE(ret, WOLFSSL_FAILURE);
- }
- /* check public key */
- if (a->pkey.ptr && b->pkey.ptr) {
- if (XMEMCMP(a->pkey.ptr, b->pkey.ptr, a->pkey_sz) != 0) {
- return WS_RETURN_CODE(ret, WOLFSSL_FAILURE);
- }
- }
- #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
- ret = 1; /* the keys match */
- #else
- ret = 0; /* success */
- #endif
- return ret;
- }
- /**
- * validate DH algorithm parameters
- * @param dh_key a pointer to WOLFSSL_EVP_PKEY_CTX structure
- * @return WOLFSSL_SUCCESS on success, otherwise failure
- */
- static int DH_param_check(WOLFSSL_DH* dh_key)
- {
- int ret = WOLFSSL_SUCCESS;
- WOLFSSL_BN_CTX* ctx = NULL;
- WOLFSSL_BIGNUM *num1 = NULL;
- WOLFSSL_BIGNUM *num2 = NULL;
- WOLFSSL_ENTER("DH_param_check");
- ctx = wolfSSL_BN_CTX_new();
- if (ctx == NULL) {
- WOLFSSL_MSG("failed to allocate memory");
- return WOLFSSL_FAILURE;
- }
- num1 = wolfSSL_BN_new();
- num2 = wolfSSL_BN_new();
- if (num1 == NULL || num2 == NULL) {
- WOLFSSL_MSG("failed to assign big number");
- ret = WOLFSSL_FAILURE;
- }
- /* prime check */
- if (ret == WOLFSSL_SUCCESS &&
- wolfSSL_BN_is_odd(dh_key->p) == 0){
- WOLFSSL_MSG("dh_key->p is not prime");
- ret = WOLFSSL_FAILURE;
- } /* TODO safe prime check. need BN_rshift1 */
- /* generator check */
- if (ret == WOLFSSL_SUCCESS &&
- (wolfSSL_BN_is_one(dh_key->g) ||
- wolfSSL_BN_is_negative(dh_key->g) ||
- wolfSSL_BN_is_zero(dh_key->g))) {
- WOLFSSL_MSG("dh_key->g is not suitable generator");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS &&
- wolfSSL_BN_cmp(dh_key->p, dh_key->g) <= 0) {
- WOLFSSL_MSG("dh_key->g is not suitable generator");
- ret = WOLFSSL_FAILURE;
- }
- if (ret == WOLFSSL_SUCCESS &&
- dh_key->q != NULL)
- {
- if (ret == WOLFSSL_SUCCESS &&
- wolfSSL_BN_mod_exp(num1, dh_key->g, dh_key->q, dh_key->p, ctx) ==
- WOLFSSL_FAILURE) {
- WOLFSSL_MSG("BN_mod_exp failed");
- ret = WOLFSSL_FAILURE;
- }
- else
- if (ret == WOLFSSL_SUCCESS &&
- wolfSSL_BN_is_one(num1) == WOLFSSL_FAILURE) {
- WOLFSSL_MSG("dh_key->g is not suitable generator");
- ret = WOLFSSL_FAILURE;
- }
- #if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
- /* test if the number q is prime. */
- if (ret == WOLFSSL_SUCCESS &&
- (wolfSSL_BN_is_prime_ex(dh_key->q, 64, ctx, NULL) <= 0)) {
- WOLFSSL_MSG("dh_key->q is not prime or error during check.");
- ret = WOLFSSL_FAILURE;
- } /* else TODO check q div q - 1. need BN_div */
- #endif
- }
- /* clean up */
- wolfSSL_BN_CTX_free(ctx);
- wolfSSL_BN_free(num1);
- wolfSSL_BN_free(num2);
- WOLFSSL_LEAVE("DH_param_check", WOLFSSL_SUCCESS);
- return ret;
- }
- /**
- * validate the algorithm parameters
- * @param ctx a pointer to WOLFSSL_EVP_PKEY_CTX structure
- * @return WOLFSSL_SUCCESS on success, otherwise failure
- */
- int wolfSSL_EVP_PKEY_param_check(WOLFSSL_EVP_PKEY_CTX* ctx)
- {
- int type;
- int ret;
- WOLFSSL_DH* dh_key = NULL;
- /* sanity check */
- if (ctx == NULL) {
- return WOLFSSL_FAILURE;
- }
- type = wolfSSL_EVP_PKEY_type(wolfSSL_EVP_PKEY_base_id(ctx->pkey));
- switch (type) {
- #if !defined(NO_RSA)
- case EVP_PKEY_RSA:
- WOLFSSL_MSG("EVP_PKEY_RSA not yet implemented");
- return WOLFSSL_FAILURE;
- #endif
- #if defined(HAVE_ECC)
- case EVP_PKEY_EC:
- WOLFSSL_MSG("EVP_PKEY_EC not yet implemented");
- return WOLFSSL_FAILURE;
- #endif
- #if !defined(NO_DSA)
- case EVP_PKEY_DSA:
- WOLFSSL_MSG("EVP_PKEY_DSA not yet implemented");
- return WOLFSSL_FAILURE;
- #endif
- #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_OPENSSH)
- #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
- case EVP_PKEY_DH:
- dh_key = wolfSSL_EVP_PKEY_get1_DH(ctx->pkey);
- if (dh_key != NULL) {
- ret = DH_param_check(dh_key);
- wolfSSL_DH_free(dh_key);
- }
- else
- ret = WOLFSSL_FAILURE;
- return ret;
- #endif
- #endif
- default:
- WOLFSSL_MSG("Unknown PKEY type");
- break;
- }
- (void)ret;
- (void)DH_param_check;
- (void)dh_key;
- return WOLFSSL_FAILURE;
- }
- /* Initialize structure for signing
- *
- * ctx WOLFSSL_EVP_MD_CTX structure to initialize
- * type is the type of message digest to use
- *
- * returns WOLFSSL_SUCCESS on success
- */
- int wolfSSL_EVP_SignInit(WOLFSSL_EVP_MD_CTX *ctx, const WOLFSSL_EVP_MD *type)
- {
- if (ctx == NULL) return WOLFSSL_FAILURE;
- WOLFSSL_ENTER("EVP_SignInit");
- return wolfSSL_EVP_DigestInit(ctx,type);
- }
- int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
- const WOLFSSL_EVP_MD* type,
- WOLFSSL_ENGINE *impl)
- {
- if (ctx == NULL) return WOLFSSL_FAILURE;
- WOLFSSL_ENTER("EVP_SignInit");
- return wolfSSL_EVP_DigestInit_ex(ctx,type,impl);
- }
- /* Update structure with data for signing
- *
- * ctx WOLFSSL_EVP_MD_CTX structure to update
- * data buffer holding data to update with for sign
- * len length of data buffer
- *
- * returns WOLFSSL_SUCCESS on success
- */
- int wolfSSL_EVP_SignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *data, size_t len)
- {
- if (ctx == NULL) return 0;
- WOLFSSL_ENTER("EVP_SignUpdate(");
- return wolfSSL_EVP_DigestUpdate(ctx, data, len);
- }
- static const struct s_ent {
- const enum wc_HashType macType;
- const int nid;
- const char *name;
- } md_tbl[] = {
- #ifndef NO_MD4
- {WC_HASH_TYPE_MD4, NID_md4, "MD4"},
- #endif /* NO_MD4 */
- #ifndef NO_MD5
- {WC_HASH_TYPE_MD5, NID_md5, "MD5"},
- #endif /* NO_MD5 */
- #ifndef NO_SHA
- {WC_HASH_TYPE_SHA, NID_sha1, "SHA1"},
- {WC_HASH_TYPE_SHA, NID_sha1, "SHA"}, /* Leave for backwards compatibility */
- #endif /* NO_SHA */
- #ifdef WOLFSSL_SHA224
- {WC_HASH_TYPE_SHA224, NID_sha224, "SHA224"},
- #endif /* WOLFSSL_SHA224 */
- #ifndef NO_SHA256
- {WC_HASH_TYPE_SHA256, NID_sha256, "SHA256"},
- #endif
- #ifdef WOLFSSL_SHA384
- {WC_HASH_TYPE_SHA384, NID_sha384, "SHA384"},
- #endif /* WOLFSSL_SHA384 */
- #ifdef WOLFSSL_SHA512
- {WC_HASH_TYPE_SHA512, NID_sha512, "SHA512"},
- #endif /* WOLFSSL_SHA512 */
- #if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224)
- {WC_HASH_TYPE_SHA512_224, NID_sha512_224, "SHA512_224"},
- #endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_224 */
- #if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256)
- {WC_HASH_TYPE_SHA512_256, NID_sha512_256, "SHA512_256"},
- #endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_256 */
- #ifndef WOLFSSL_NOSHA3_224
- {WC_HASH_TYPE_SHA3_224, NID_sha3_224, "SHA3_224"},
- #endif
- #ifndef WOLFSSL_NOSHA3_256
- {WC_HASH_TYPE_SHA3_256, NID_sha3_256, "SHA3_256"},
- #endif
- #ifndef WOLFSSL_NOSHA3_384
- {WC_HASH_TYPE_SHA3_384, NID_sha3_384, "SHA3_384"},
- #endif
- #ifndef WOLFSSL_NOSHA3_512
- {WC_HASH_TYPE_SHA3_512, NID_sha3_512, "SHA3_512"},
- #endif
- #ifdef HAVE_BLAKE2
- {WC_HASH_TYPE_BLAKE2B, NID_blake2b512, "BLAKE2B512"},
- #endif
- #ifdef HAVE_BLAKE2S
- {WC_HASH_TYPE_BLAKE2S, NID_blake2s256, "BLAKE2S256"},
- #endif
- #ifdef WOLFSSL_SHAKE128
- {WC_HASH_TYPE_SHAKE128, NID_shake128, "SHAKE128"},
- #endif
- #ifdef WOLFSSL_SHAKE256
- {WC_HASH_TYPE_SHAKE256, NID_shake256, "SHAKE256"},
- #endif
- {WC_HASH_TYPE_NONE, 0, NULL}
- };
- static enum wc_HashType EvpMd2MacType(const WOLFSSL_EVP_MD *md)
- {
- const struct s_ent *ent ;
- if (md != NULL) {
- for (ent = md_tbl; ent->name != NULL; ent++) {
- if (XSTRCMP((const char *)md, ent->name) == 0) {
- return ent->macType;
- }
- }
- }
- return WC_HASH_TYPE_NONE;
- }
- static const WOLFSSL_EVP_MD* wolfSSL_macType2EVP_md(enum wc_HashType type)
- {
- const struct s_ent *ent ;
- for (ent = md_tbl; ent->name != NULL; ent++) {
- if (ent->macType == type) {
- return ent->name;
- }
- }
- return NULL;
- }
- /* Finalize structure for signing
- *
- * ctx WOLFSSL_EVP_MD_CTX structure to finalize
- * sigret buffer to hold resulting signature
- * siglen length of sigret buffer
- * pkey key to sign with
- *
- * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
- */
- int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret,
- unsigned int *siglen, WOLFSSL_EVP_PKEY *pkey)
- {
- unsigned int mdsize;
- unsigned char md[WC_MAX_DIGEST_SIZE];
- int ret;
- (void)sigret;
- (void)siglen;
- WOLFSSL_ENTER("EVP_SignFinal");
- if (ctx == NULL)
- return WOLFSSL_FAILURE;
- ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize);
- if (ret <= 0)
- return ret;
- switch (pkey->type) {
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA: {
- int nid;
- const WOLFSSL_EVP_MD *ctxmd;
- ctxmd = wolfSSL_EVP_MD_CTX_md(ctx);
- if (ctxmd == NULL)
- return WOLFSSL_FAILURE;
- nid = wolfSSL_EVP_MD_type(ctxmd);
- if (nid < 0)
- return WOLFSSL_FAILURE;
- return wolfSSL_RSA_sign(nid, md, mdsize, sigret,
- siglen, pkey->rsa);
- }
- #endif /* NO_RSA */
- #ifndef NO_DSA
- case EVP_PKEY_DSA: {
- int bytes;
- ret = wolfSSL_DSA_do_sign(md, sigret, pkey->dsa);
- /* wolfSSL_DSA_do_sign() can return WOLFSSL_FATAL_ERROR */
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- bytes = wolfSSL_BN_num_bytes(pkey->dsa->q);
- if (bytes == WOLFSSL_FAILURE || (int)*siglen < bytes * 2)
- return WOLFSSL_FAILURE;
- *siglen = bytes * 2;
- return WOLFSSL_SUCCESS;
- }
- #endif
- case EVP_PKEY_EC:
- WOLFSSL_MSG("not implemented");
- FALL_THROUGH;
- default:
- break;
- }
- return WOLFSSL_FAILURE;
- }
- /* Initialize structure for verifying signature
- *
- * ctx WOLFSSL_EVP_MD_CTX structure to initialize
- * type is the type of message digest to use
- *
- * returns WOLFSSL_SUCCESS on success
- */
- int wolfSSL_EVP_VerifyInit(WOLFSSL_EVP_MD_CTX *ctx, const WOLFSSL_EVP_MD *type)
- {
- if (ctx == NULL) return WOLFSSL_FAILURE;
- WOLFSSL_ENTER("EVP_VerifyInit");
- return wolfSSL_EVP_DigestInit(ctx,type);
- }
- /* Update structure for verifying signature
- *
- * ctx WOLFSSL_EVP_MD_CTX structure to update
- * data buffer holding data to update with for verify
- * len length of data buffer
- *
- * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
- */
- int wolfSSL_EVP_VerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *data, size_t len)
- {
- if (ctx == NULL) return WOLFSSL_FAILURE;
- WOLFSSL_ENTER("EVP_VerifyUpdate");
- return wolfSSL_EVP_DigestUpdate(ctx, data, len);
- }
- /* Finalize structure for verifying signature
- *
- * ctx WOLFSSL_EVP_MD_CTX structure to finalize
- * sig buffer holding signature
- * siglen length of sig buffer
- * pkey key to verify with
- *
- * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
- */
- int wolfSSL_EVP_VerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,
- const unsigned char*sig, unsigned int siglen, WOLFSSL_EVP_PKEY *pkey)
- {
- int ret;
- unsigned char md[WC_MAX_DIGEST_SIZE];
- unsigned int mdsize;
- if (ctx == NULL) return WOLFSSL_FAILURE;
- WOLFSSL_ENTER("EVP_VerifyFinal");
- ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize);
- if (ret <= 0) return ret;
- (void)sig;
- (void)siglen;
- switch (pkey->type) {
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA: {
- int nid;
- const WOLFSSL_EVP_MD *ctxmd = wolfSSL_EVP_MD_CTX_md(ctx);
- if (ctxmd == NULL) break;
- nid = wolfSSL_EVP_MD_type(ctxmd);
- if (nid < 0) break;
- return wolfSSL_RSA_verify(nid, md, mdsize, sig,
- (unsigned int)siglen, pkey->rsa);
- }
- #endif /* NO_RSA */
- case EVP_PKEY_DSA:
- case EVP_PKEY_EC:
- WOLFSSL_MSG("not implemented");
- FALL_THROUGH;
- default:
- break;
- }
- return WOLFSSL_FAILURE;
- }
- int wolfSSL_EVP_add_cipher(const WOLFSSL_EVP_CIPHER *cipher)
- {
- (void)cipher;
- /* nothing to do */
- return 0;
- }
- WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_mac_key(int type, WOLFSSL_ENGINE* e,
- const unsigned char* key, int keylen)
- {
- WOLFSSL_EVP_PKEY* pkey;
- (void)e;
- if (type != EVP_PKEY_HMAC || (key == NULL && keylen != 0))
- return NULL;
- pkey = wolfSSL_EVP_PKEY_new();
- if (pkey != NULL) {
- pkey->pkey.ptr = (char*)XMALLOC(keylen, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
- if (pkey->pkey.ptr == NULL && keylen > 0) {
- wolfSSL_EVP_PKEY_free(pkey);
- pkey = NULL;
- }
- else {
- if (keylen) {
- XMEMCPY(pkey->pkey.ptr, key, keylen);
- }
- pkey->pkey_sz = keylen;
- pkey->type = pkey->save_type = type;
- }
- }
- return pkey;
- }
- const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PKEY* pkey,
- size_t* len)
- {
- if (pkey == NULL || len == NULL)
- return NULL;
- *len = (size_t)pkey->pkey_sz;
- return (const unsigned char*)pkey->pkey.ptr;
- }
- /* Initialize an EVP_DigestSign/Verify operation.
- * Initialize a digest for RSA and ECC keys, or HMAC for HMAC key.
- */
- static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx,
- WOLFSSL_EVP_PKEY_CTX **pctx,
- const WOLFSSL_EVP_MD *type,
- WOLFSSL_ENGINE *e,
- WOLFSSL_EVP_PKEY *pkey)
- {
- if (!type) {
- int default_digest;
- if (wolfSSL_EVP_PKEY_get_default_digest_nid(pkey, &default_digest)
- != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("Could not get default digest");
- return WOLFSSL_FAILURE;
- }
- type = wolfSSL_EVP_get_digestbynid(default_digest);
- if (!type) {
- return BAD_FUNC_ARG;
- }
- }
- if (pkey->type == EVP_PKEY_HMAC) {
- int hashType;
- const unsigned char* key;
- #ifndef NO_SHA256
- if (XSTRCMP(type, "SHA256") == 0) {
- hashType = WC_SHA256;
- } else
- #endif
- #ifndef NO_SHA
- if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) {
- hashType = WC_SHA;
- } else
- #endif /* NO_SHA */
- #ifdef WOLFSSL_SHA224
- if (XSTRCMP(type, "SHA224") == 0) {
- hashType = WC_SHA224;
- } else
- #endif
- #ifdef WOLFSSL_SHA384
- if (XSTRCMP(type, "SHA384") == 0) {
- hashType = WC_SHA384;
- } else
- #endif
- #ifdef WOLFSSL_SHA512
- if (XSTRCMP(type, "SHA512") == 0) {
- hashType = WC_SHA512;
- } else
- #endif
- #ifdef WOLFSSL_SHA3
- #ifndef WOLFSSL_NOSHA3_224
- if (XSTRCMP(type, "SHA3_224") == 0) {
- hashType = WC_SHA3_224;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_256
- if (XSTRCMP(type, "SHA3_256") == 0) {
- hashType = WC_SHA3_256;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_384
- if (XSTRCMP(type, "SHA3_384") == 0) {
- hashType = WC_SHA3_384;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_512
- if (XSTRCMP(type, "SHA3_512") == 0) {
- hashType = WC_SHA3_512;
- } else
- #endif
- #endif
- #ifndef NO_MD5
- if (XSTRCMP(type, "MD5") == 0) {
- hashType = WC_MD5;
- } else
- #endif
- return BAD_FUNC_ARG;
- {
- size_t keySz = 0;
- key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz);
- if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0)
- return WOLFSSL_FAILURE;
- if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0)
- return WOLFSSL_FAILURE;
- }
- ctx->isHMAC = 1;
- }
- else if (wolfSSL_EVP_DigestInit(ctx, type) != 1)
- return WOLFSSL_FAILURE;
- if (ctx->pctx == NULL) {
- ctx->pctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e);
- if (ctx->pctx == NULL)
- return WOLFSSL_FAILURE;
- }
- if (pctx != NULL)
- *pctx = ctx->pctx;
- return WOLFSSL_SUCCESS;
- }
- /* Update an EVP_DigestSign/Verify operation.
- * Update a digest for RSA and ECC keys, or HMAC for HMAC key.
- */
- static int wolfssl_evp_digest_pk_update(WOLFSSL_EVP_MD_CTX *ctx,
- const void *d, unsigned int cnt)
- {
- if (ctx->isHMAC) {
- if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, cnt) != 0)
- return WOLFSSL_FAILURE;
- return WOLFSSL_SUCCESS;
- }
- else
- return wolfSSL_EVP_DigestUpdate(ctx, d, cnt);
- }
- /* Finalize an EVP_DigestSign/Verify operation - common part only.
- * Finalize a digest for RSA and ECC keys, or HMAC for HMAC key.
- * Copies the digest so that you can keep updating.
- */
- static int wolfssl_evp_digest_pk_final(WOLFSSL_EVP_MD_CTX *ctx,
- unsigned char *md, unsigned int* mdlen)
- {
- int ret;
- if (ctx->isHMAC) {
- Hmac hmacCopy;
- if (wolfSSL_HmacCopy(&hmacCopy, &ctx->hash.hmac) != WOLFSSL_SUCCESS)
- return WOLFSSL_FAILURE;
- ret = wc_HmacFinal(&hmacCopy, md) == 0;
- wc_HmacFree(&hmacCopy);
- return ret;
- }
- else {
- WOLFSSL_EVP_MD_CTX ctxCopy;
- if (wolfSSL_EVP_MD_CTX_copy_ex(&ctxCopy, ctx) != WOLFSSL_SUCCESS)
- return WOLFSSL_FAILURE;
- ret = wolfSSL_EVP_DigestFinal(&ctxCopy, md, mdlen);
- wolfSSL_EVP_MD_CTX_cleanup(&ctxCopy);
- return ret;
- }
- }
- /* Get the length of the mac based on the digest algorithm. */
- static int wolfssl_mac_len(unsigned char macType)
- {
- int hashLen;
- switch (macType) {
- #ifndef NO_MD5
- case WC_MD5:
- hashLen = WC_MD5_DIGEST_SIZE;
- break;
- #endif /* !NO_MD5 */
- #ifndef NO_SHA
- case WC_SHA:
- hashLen = WC_SHA_DIGEST_SIZE;
- break;
- #endif /* !NO_SHA */
- #ifdef WOLFSSL_SHA224
- case WC_SHA224:
- hashLen = WC_SHA224_DIGEST_SIZE;
- break;
- #endif /* WOLFSSL_SHA224 */
- #ifndef NO_SHA256
- case WC_SHA256:
- hashLen = WC_SHA256_DIGEST_SIZE;
- break;
- #endif /* !NO_SHA256 */
- #ifdef WOLFSSL_SHA384
- case WC_SHA384:
- hashLen = WC_SHA384_DIGEST_SIZE;
- break;
- #endif /* WOLFSSL_SHA384 */
- #ifdef WOLFSSL_SHA512
- case WC_SHA512:
- hashLen = WC_SHA512_DIGEST_SIZE;
- break;
- #endif /* WOLFSSL_SHA512 */
- #ifdef HAVE_BLAKE2
- case BLAKE2B_ID:
- hashLen = BLAKE2B_OUTBYTES;
- break;
- #endif /* HAVE_BLAKE2 */
- #ifdef WOLFSSL_SHA3
- #ifndef WOLFSSL_NOSHA3_224
- case WC_SHA3_224:
- hashLen = WC_SHA3_224_DIGEST_SIZE;
- break;
- #endif
- #ifndef WOLFSSL_NOSHA3_256
- case WC_SHA3_256:
- hashLen = WC_SHA3_256_DIGEST_SIZE;
- break;
- #endif
- #ifndef WOLFSSL_NOSHA3_384
- case WC_SHA3_384:
- hashLen = WC_SHA3_384_DIGEST_SIZE;
- break;
- #endif
- #ifndef WOLFSSL_NOSHA3_512
- case WC_SHA3_512:
- hashLen = WC_SHA3_512_DIGEST_SIZE;
- break;
- #endif
- #endif
- default:
- hashLen = 0;
- }
- return hashLen;
- }
- int wolfSSL_EVP_DigestSignInit(WOLFSSL_EVP_MD_CTX *ctx,
- WOLFSSL_EVP_PKEY_CTX **pctx,
- const WOLFSSL_EVP_MD *type,
- WOLFSSL_ENGINE *e,
- WOLFSSL_EVP_PKEY *pkey)
- {
- WOLFSSL_ENTER("EVP_DigestSignInit");
- if (ctx == NULL || pkey == NULL)
- return BAD_FUNC_ARG;
- return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey);
- }
- int wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d,
- unsigned int cnt)
- {
- WOLFSSL_ENTER("EVP_DigestSignUpdate");
- if (ctx == NULL || d == NULL)
- return BAD_FUNC_ARG;
- return wolfssl_evp_digest_pk_update(ctx, d, cnt);
- }
- int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig,
- size_t *siglen)
- {
- unsigned char digest[WC_MAX_DIGEST_SIZE];
- unsigned int hashLen;
- int ret = WOLFSSL_FAILURE;
- WOLFSSL_ENTER("EVP_DigestSignFinal");
- if (ctx == NULL || siglen == NULL)
- return WOLFSSL_FAILURE;
- /* Return the maximum size of the signature when sig is NULL. */
- if (ctx->isHMAC) {
- hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);
- if (sig == NULL) {
- *siglen = hashLen;
- return WOLFSSL_SUCCESS;
- }
- }
- #ifndef NO_RSA
- else if (ctx->pctx->pkey->type == EVP_PKEY_RSA) {
- if (sig == NULL) {
- *siglen = wolfSSL_RSA_size(ctx->pctx->pkey->rsa);
- return WOLFSSL_SUCCESS;
- }
- }
- #endif /* !NO_RSA */
- #ifdef HAVE_ECC
- else if (ctx->pctx->pkey->type == EVP_PKEY_EC) {
- if (sig == NULL) {
- /* SEQ + INT + INT */
- *siglen = ecc_sets[ctx->pctx->pkey->ecc->group->curve_idx].size * 2
- + 8;
- return WOLFSSL_SUCCESS;
- }
- }
- #endif
- if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)
- return WOLFSSL_FAILURE;
- if (ctx->isHMAC) {
- /* Copy the HMAC result as signature. */
- if ((unsigned int)(*siglen) > hashLen)
- *siglen = hashLen;
- /* May be a truncated signature. */
- XMEMCPY(sig, digest, *siglen);
- ret = WOLFSSL_SUCCESS;
- }
- else {
- /* Sign the digest. */
- switch (ctx->pctx->pkey->type) {
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA: {
- unsigned int sigSz = (unsigned int)*siglen;
- int nid;
- const WOLFSSL_EVP_MD *md = wolfSSL_EVP_MD_CTX_md(ctx);
- if (md == NULL)
- break;
- nid = wolfSSL_EVP_MD_type(md);
- if (nid < 0)
- break;
- ret = wolfSSL_RSA_sign_generic_padding(nid, digest, hashLen,
- sig, &sigSz, ctx->pctx->pkey->rsa, 1, ctx->pctx->padding);
- if (ret >= 0)
- *siglen = sigSz;
- break;
- }
- #endif /* NO_RSA */
- #ifdef HAVE_ECC
- case EVP_PKEY_EC: {
- int len;
- WOLFSSL_ECDSA_SIG *ecdsaSig;
- ecdsaSig = wolfSSL_ECDSA_do_sign(digest, hashLen,
- ctx->pctx->pkey->ecc);
- if (ecdsaSig == NULL)
- break;
- len = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig);
- wolfSSL_ECDSA_SIG_free(ecdsaSig);
- if (len == 0)
- break;
- *siglen = len;
- ret = WOLFSSL_SUCCESS;
- break;
- }
- #endif
- default:
- break;
- }
- }
- ForceZero(digest, sizeof(digest));
- return ret;
- }
- int wolfSSL_EVP_DigestVerifyInit(WOLFSSL_EVP_MD_CTX *ctx,
- WOLFSSL_EVP_PKEY_CTX **pctx,
- const WOLFSSL_EVP_MD *type,
- WOLFSSL_ENGINE *e,
- WOLFSSL_EVP_PKEY *pkey)
- {
- WOLFSSL_ENTER("EVP_DigestVerifyInit");
- if (ctx == NULL || type == NULL || pkey == NULL)
- return BAD_FUNC_ARG;
- return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey);
- }
- int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d,
- size_t cnt)
- {
- WOLFSSL_ENTER("EVP_DigestVerifyUpdate");
- if (ctx == NULL || d == NULL)
- return BAD_FUNC_ARG;
- return wolfssl_evp_digest_pk_update(ctx, d, (unsigned int)cnt);
- }
- int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,
- const unsigned char *sig, size_t siglen)
- {
- unsigned char digest[WC_MAX_DIGEST_SIZE];
- unsigned int hashLen;
- WOLFSSL_ENTER("EVP_DigestVerifyFinal");
- if (ctx == NULL || sig == NULL)
- return WOLFSSL_FAILURE;
- if (ctx->isHMAC) {
- hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);
- if (siglen > hashLen)
- return WOLFSSL_FAILURE;
- /* May be a truncated signature. */
- }
- if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)
- return WOLFSSL_FAILURE;
- if (ctx->isHMAC) {
- /* Check HMAC result matches the signature. */
- if (XMEMCMP(sig, digest, siglen) == 0)
- return WOLFSSL_SUCCESS;
- return WOLFSSL_FAILURE;
- }
- else {
- /* Verify the signature with the digest. */
- switch (ctx->pctx->pkey->type) {
- #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
- case EVP_PKEY_RSA: {
- int nid;
- const WOLFSSL_EVP_MD *md = wolfSSL_EVP_MD_CTX_md(ctx);
- if (md == NULL)
- return WOLFSSL_FAILURE;
- nid = wolfSSL_EVP_MD_type(md);
- if (nid < 0)
- return WOLFSSL_FAILURE;
- return wolfSSL_RSA_verify_ex(nid, digest, hashLen, sig,
- (unsigned int)siglen,
- ctx->pctx->pkey->rsa, ctx->pctx->padding);
- }
- #endif /* NO_RSA */
- #ifdef HAVE_ECC
- case EVP_PKEY_EC: {
- int ret;
- WOLFSSL_ECDSA_SIG *ecdsaSig;
- ecdsaSig = wolfSSL_d2i_ECDSA_SIG(NULL, &sig, (long)siglen);
- if (ecdsaSig == NULL)
- return WOLFSSL_FAILURE;
- ret = wolfSSL_ECDSA_do_verify(digest, hashLen, ecdsaSig,
- ctx->pctx->pkey->ecc);
- wolfSSL_ECDSA_SIG_free(ecdsaSig);
- return ret;
- }
- #endif
- default:
- break;
- }
- }
- return WOLFSSL_FAILURE;
- }
- #ifdef WOLFSSL_APACHE_HTTPD
- #if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32)
- #include <termios.h>
- #endif
- #ifndef XGETPASSWD
- static int XGETPASSWD(char* buf, int bufSz) {
- int ret = WOLFSSL_SUCCESS;
- /* turn off echo for passwords */
- #ifdef USE_WINDOWS_API
- DWORD originalTerm;
- DWORD newTerm;
- CONSOLE_SCREEN_BUFFER_INFO screenOrig;
- HANDLE stdinHandle = GetStdHandle(STD_INPUT_HANDLE);
- if (GetConsoleMode(stdinHandle, &originalTerm) == 0) {
- WOLFSSL_MSG("Couldn't get the original terminal settings");
- return WOLFSSL_FAILURE;
- }
- newTerm = originalTerm;
- newTerm &= ~ENABLE_ECHO_INPUT;
- if (SetConsoleMode(stdinHandle, newTerm) == 0) {
- WOLFSSL_MSG("Couldn't turn off echo");
- return WOLFSSL_FAILURE;
- }
- #else
- struct termios originalTerm;
- struct termios newTerm;
- if (tcgetattr(STDIN_FILENO, &originalTerm) != 0) {
- WOLFSSL_MSG("Couldn't get the original terminal settings");
- return WOLFSSL_FAILURE;
- }
- XMEMCPY(&newTerm, &originalTerm, sizeof(struct termios));
- newTerm.c_lflag &= ~ECHO;
- newTerm.c_lflag |= (ICANON | ECHONL);
- if (tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) != 0) {
- WOLFSSL_MSG("Couldn't turn off echo");
- return WOLFSSL_FAILURE;
- }
- #endif
- if (XFGETS(buf, bufSz, stdin) == NULL) {
- ret = WOLFSSL_FAILURE;
- }
- /* restore default echo */
- #ifdef USE_WINDOWS_API
- if (SetConsoleMode(stdinHandle, originalTerm) == 0) {
- WOLFSSL_MSG("Couldn't restore the terminal settings");
- return WOLFSSL_FAILURE;
- }
- #else
- if (tcsetattr(STDIN_FILENO, TCSANOW, &originalTerm) != 0) {
- WOLFSSL_MSG("Couldn't restore the terminal settings");
- return WOLFSSL_FAILURE;
- }
- #endif
- return ret;
- }
- #endif
- /* returns 0 on success and -2 or -1 on failure */
- int wolfSSL_EVP_read_pw_string(char* buf, int bufSz, const char* banner, int v)
- {
- printf("%s", banner);
- if (XGETPASSWD(buf, bufSz) == WOLFSSL_FAILURE) {
- return -1;
- }
- (void)v; /* fgets always sanity checks size of input vs buffer */
- return 0;
- }
- #endif /* WOLFSSL_APACHE_HTTPD */
- #if !defined(NO_PWDBASED) && !defined(NO_SHA)
- int wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
- const unsigned char *salt,
- int saltlen, int iter,
- int keylen, unsigned char *out)
- {
- const char *nostring = "";
- int ret = 0;
- if (pass == NULL) {
- passlen = 0;
- pass = nostring;
- }
- else if (passlen == -1) {
- passlen = (int)XSTRLEN(pass);
- }
- ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen,
- iter, keylen, WC_SHA);
- if (ret == 0)
- return WOLFSSL_SUCCESS;
- else
- return WOLFSSL_FAILURE;
- }
- #endif /* !NO_PWDBASED !NO_SHA*/
- #if !defined(NO_PWDBASED)
- int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
- const unsigned char *salt,
- int saltlen, int iter,
- const WOLFSSL_EVP_MD *digest,
- int keylen, unsigned char *out)
- {
- const char *nostring = "";
- int ret = 0;
- if (pass == NULL) {
- passlen = 0;
- pass = nostring;
- } else if (passlen == -1) {
- passlen = (int)XSTRLEN(pass);
- }
- ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen,
- iter, keylen, EvpMd2MacType(digest));
- if (ret == 0)
- return WOLFSSL_SUCCESS;
- else
- return WOLFSSL_FAILURE;
- }
- #endif /* !NO_PWDBASED */
- #if defined(HAVE_SCRYPT) && defined(HAVE_PBKDF2) && !defined(NO_PWDBASED) && \
- !defined(NO_SHA256)
- /**
- * Derives a key from the specified password and the salt using SCRYPT
- * algorithm.
- *
- * Parameters:
- * - pass :password data. no need to be null-terminated. NULL is accepted.
- * - passlen :length of the password. Must be 0 when pass is NULL.
- * - salt :salt. NULL is accepted.
- * - saltlen :length of the salt. Must be 0 when salt is NULL.
- * - N :cost parameter. Must be grater or equal to 2 and be a power of 2.
- * - r :block size. Must 1 or greater.
- * - p :parallelism
- * - maxmem :maximum size of buffer used for calculation in definition,
- * Not referred in this implementation.
- * - key :derived key.
- * - keylen :length of the derived key
- *
- * Returns:
- * 1 on success, otherwise 0.
- */
- int wolfSSL_EVP_PBE_scrypt(const char *pass, size_t passlen,
- const unsigned char *salt, size_t saltlen,
- word64 N, word64 r, word64 p,
- word64 maxmem, unsigned char *key, size_t keylen)
- {
- int ret;
- int exp = 0;
- (void)maxmem;
- WOLFSSL_ENTER("wolfSSL_EVP_PBE_scrypt");
- if (r > INT32_MAX || p > INT32_MAX) {
- WOLFSSL_MSG("Doesn't support greater than 32 bit values of r and p");
- return WOLFSSL_FAILURE;
- }
- /* N must be a power of 2 and > 2.
- if (N & (N-1)) is zero, it means N is a power of 2.
- */
- if (N < 2 || (N & (N-1)) || r <= 0 || p <= 0)
- return WOLFSSL_FAILURE;
- if (key == NULL)
- return WOLFSSL_SUCCESS;
- /* get exponent of power of 2. Confirmed N is power of 2. */
- while (N != 1) {
- N >>= 1;
- exp++;
- }
- ret = wc_scrypt(key, (const byte*)pass, (int)passlen, salt, (int)saltlen,
- exp, (int)r, (int)p, (int)keylen);
- WOLFSSL_LEAVE("wolfSSL_EVP_PBE_scrypt", ret);
- if (ret == 0)
- return WOLFSSL_SUCCESS;
- else
- return WOLFSSL_FAILURE;
- }
- #endif /* HAVE_SCRYPT && HAVE_PBKDF2 && !NO_PWDBASED && !NO_SHA */
- static const struct cipher{
- unsigned char type;
- const char *name;
- int nid;
- } cipher_tbl[] = {
- #ifndef NO_AES
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- #ifdef WOLFSSL_AES_128
- {AES_128_CBC_TYPE, EVP_AES_128_CBC, NID_aes_128_cbc},
- #endif
- #ifdef WOLFSSL_AES_192
- {AES_192_CBC_TYPE, EVP_AES_192_CBC, NID_aes_192_cbc},
- #endif
- #ifdef WOLFSSL_AES_256
- {AES_256_CBC_TYPE, EVP_AES_256_CBC, NID_aes_256_cbc},
- #endif
- #endif
- #ifdef WOLFSSL_AES_CFB
- #ifdef WOLFSSL_AES_128
- {AES_128_CFB1_TYPE, EVP_AES_128_CFB1, NID_aes_128_cfb1},
- #endif
- #ifdef WOLFSSL_AES_192
- {AES_192_CFB1_TYPE, EVP_AES_192_CFB1, NID_aes_192_cfb1},
- #endif
- #ifdef WOLFSSL_AES_256
- {AES_256_CFB1_TYPE, EVP_AES_256_CFB1, NID_aes_256_cfb1},
- #endif
- #ifdef WOLFSSL_AES_128
- {AES_128_CFB8_TYPE, EVP_AES_128_CFB8, NID_aes_128_cfb8},
- #endif
- #ifdef WOLFSSL_AES_192
- {AES_192_CFB8_TYPE, EVP_AES_192_CFB8, NID_aes_192_cfb8},
- #endif
- #ifdef WOLFSSL_AES_256
- {AES_256_CFB8_TYPE, EVP_AES_256_CFB8, NID_aes_256_cfb8},
- #endif
- #ifdef WOLFSSL_AES_128
- {AES_128_CFB128_TYPE, EVP_AES_128_CFB128, NID_aes_128_cfb128},
- #endif
- #ifdef WOLFSSL_AES_192
- {AES_192_CFB128_TYPE, EVP_AES_192_CFB128, NID_aes_192_cfb128},
- #endif
- #ifdef WOLFSSL_AES_256
- {AES_256_CFB128_TYPE, EVP_AES_256_CFB128, NID_aes_256_cfb128},
- #endif
- #endif
- #ifdef HAVE_AES_OFB
- #ifdef WOLFSSL_AES_128
- {AES_128_OFB_TYPE, EVP_AES_128_OFB, NID_aes_128_ofb},
- #endif
- #ifdef WOLFSSL_AES_192
- {AES_192_OFB_TYPE, EVP_AES_192_OFB, NID_aes_192_ofb},
- #endif
- #ifdef WOLFSSL_AES_256
- {AES_256_OFB_TYPE, EVP_AES_256_OFB, NID_aes_256_ofb},
- #endif
- #endif
- #ifdef HAVE_AES_XTS
- #ifdef WOLFSSL_AES_128
- {AES_128_XTS_TYPE, EVP_AES_128_XTS, NID_aes_128_xts},
- #endif
- #ifdef WOLFSSL_AES_256
- {AES_256_XTS_TYPE, EVP_AES_256_XTS, NID_aes_256_xts},
- #endif
- #endif
- #ifdef HAVE_AESGCM
- #ifdef WOLFSSL_AES_128
- {AES_128_GCM_TYPE, EVP_AES_128_GCM, NID_aes_128_gcm},
- #endif
- #ifdef WOLFSSL_AES_192
- {AES_192_GCM_TYPE, EVP_AES_192_GCM, NID_aes_192_gcm},
- #endif
- #ifdef WOLFSSL_AES_256
- {AES_256_GCM_TYPE, EVP_AES_256_GCM, NID_aes_256_gcm},
- #endif
- #endif
- #ifdef WOLFSSL_AES_COUNTER
- #ifdef WOLFSSL_AES_128
- {AES_128_CTR_TYPE, EVP_AES_128_CTR, NID_aes_128_ctr},
- #endif
- #ifdef WOLFSSL_AES_192
- {AES_192_CTR_TYPE, EVP_AES_192_CTR, NID_aes_192_ctr},
- #endif
- #ifdef WOLFSSL_AES_256
- {AES_256_CTR_TYPE, EVP_AES_256_CTR, NID_aes_256_ctr},
- #endif
- #endif
- #ifdef HAVE_AES_ECB
- #ifdef WOLFSSL_AES_128
- {AES_128_ECB_TYPE, EVP_AES_128_ECB, NID_aes_128_ecb},
- #endif
- #ifdef WOLFSSL_AES_192
- {AES_192_ECB_TYPE, EVP_AES_192_ECB, NID_aes_192_ecb},
- #endif
- #ifdef WOLFSSL_AES_256
- {AES_256_ECB_TYPE, EVP_AES_256_ECB, NID_aes_256_ecb},
- #endif
- #endif
- #endif
- #ifndef NO_DES3
- {DES_CBC_TYPE, EVP_DES_CBC, NID_des_cbc},
- {DES_ECB_TYPE, EVP_DES_ECB, NID_des_ecb},
- {DES_EDE3_CBC_TYPE, EVP_DES_EDE3_CBC, NID_des_ede3_cbc},
- {DES_EDE3_ECB_TYPE, EVP_DES_EDE3_ECB, NID_des_ede3_ecb},
- #endif
- #ifndef NO_RC4
- {ARC4_TYPE, EVP_ARC4, NID_undef},
- #endif
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- {CHACHA20_POLY1305_TYPE, EVP_CHACHA20_POLY1305, NID_chacha20_poly1305},
- #endif
- { 0, NULL, 0}
- };
- /* returns cipher using provided ctx type */
- const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_CIPHER_CTX_cipher(
- const WOLFSSL_EVP_CIPHER_CTX *ctx)
- {
- const struct cipher* c;
- if (!ctx || !ctx->cipherType) {
- return NULL;
- }
- for (c = cipher_tbl; c->type != 0; c++) {
- if (ctx->cipherType == c->type) {
- return wolfSSL_EVP_get_cipherbyname(c->name);
- }
- }
- return NULL;
- }
- int wolfSSL_EVP_CIPHER_nid(const WOLFSSL_EVP_CIPHER *cipher)
- {
- const struct cipher* c;
- if (!cipher) {
- return 0;
- }
- for (c = cipher_tbl; c->type != 0; c++) {
- if (XSTRCMP(cipher, c->name) == 0) {
- return c->nid;
- }
- }
- return 0;
- }
- const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name)
- {
- const struct alias {
- const char *name;
- const char *alias;
- } cipher_alias_tbl[] = {
- #ifndef NO_DES3
- {EVP_DES_CBC, "des"},
- {EVP_DES_ECB, "des-ecb"},
- {EVP_DES_EDE3_CBC, "des3"},
- {EVP_DES_EDE3_CBC, "3des"},
- {EVP_DES_EDE3_ECB, "des-ede3"},
- {EVP_DES_EDE3_ECB, "des-ede3-ecb"},
- #endif
- #ifndef NO_AES
- #ifdef HAVE_AES_CBC
- #ifdef WOLFSSL_AES_128
- {EVP_AES_128_CBC, "aes128-cbc"},
- {EVP_AES_128_CBC, "aes128"},
- #endif
- #ifdef WOLFSSL_AES_192
- {EVP_AES_192_CBC, "aes192-cbc"},
- {EVP_AES_192_CBC, "aes192"},
- #endif
- #ifdef WOLFSSL_AES_256
- {EVP_AES_256_CBC, "aes256-cbc"},
- {EVP_AES_256_CBC, "aes256"},
- #endif
- #endif
- #ifdef HAVE_AES_ECB
- #ifdef WOLFSSL_AES_128
- {EVP_AES_128_ECB, "aes128-ecb"},
- #endif
- #ifdef WOLFSSL_AES_192
- {EVP_AES_192_ECB, "aes192-ecb"},
- #endif
- #ifdef WOLFSSL_AES_256
- {EVP_AES_256_ECB, "aes256-ecb"},
- #endif
- #endif
- #ifdef HAVE_AESGCM
- #ifdef WOLFSSL_AES_128
- {EVP_AES_128_GCM, "aes-128-gcm"},
- {EVP_AES_128_GCM, "id-aes128-GCM"},
- #endif
- #ifdef WOLFSSL_AES_192
- {EVP_AES_192_GCM, "aes-192-gcm"},
- {EVP_AES_192_GCM, "id-aes192-GCM"},
- #endif
- #ifdef WOLFSSL_AES_256
- {EVP_AES_256_GCM, "aes-256-gcm"},
- {EVP_AES_256_GCM, "id-aes256-GCM"},
- #endif
- #endif
- #endif
- #ifndef NO_RC4
- {EVP_ARC4, "RC4"},
- #endif
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- {EVP_CHACHA20_POLY1305, "chacha20-poly1305"},
- #endif
- { NULL, NULL}
- };
- const struct cipher *ent;
- const struct alias *al;
- WOLFSSL_ENTER("EVP_get_cipherbyname");
- for (al = cipher_alias_tbl; al->name != NULL; al++) {
- /* Accept any case alternative version of an alias. */
- if (XSTRCASECMP(name, al->alias) == 0) {
- name = al->name;
- break;
- }
- }
- for (ent = cipher_tbl; ent->name != NULL; ent++) {
- /* Accept any case alternative version of name. */
- if (XSTRCASECMP(name, ent->name) == 0) {
- return (WOLFSSL_EVP_CIPHER *)ent->name;
- }
- }
- return NULL;
- }
- /*
- * return an EVP_CIPHER structure when cipher NID is passed.
- *
- * id cipher NID
- *
- * return WOLFSSL_EVP_CIPHER
- */
- const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id)
- {
- WOLFSSL_ENTER("EVP_get_cipherbynid");
- switch(id) {
- #ifndef NO_AES
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- #ifdef WOLFSSL_AES_128
- case NID_aes_128_cbc:
- return wolfSSL_EVP_aes_128_cbc();
- #endif
- #ifdef WOLFSSL_AES_192
- case NID_aes_192_cbc:
- return wolfSSL_EVP_aes_192_cbc();
- #endif
- #ifdef WOLFSSL_AES_256
- case NID_aes_256_cbc:
- return wolfSSL_EVP_aes_256_cbc();
- #endif
- #endif
- #ifdef WOLFSSL_AES_COUNTER
- #ifdef WOLFSSL_AES_128
- case NID_aes_128_ctr:
- return wolfSSL_EVP_aes_128_ctr();
- #endif
- #ifdef WOLFSSL_AES_192
- case NID_aes_192_ctr:
- return wolfSSL_EVP_aes_192_ctr();
- #endif
- #ifdef WOLFSSL_AES_256
- case NID_aes_256_ctr:
- return wolfSSL_EVP_aes_256_ctr();
- #endif
- #endif /* WOLFSSL_AES_COUNTER */
- #ifdef HAVE_AES_ECB
- #ifdef WOLFSSL_AES_128
- case NID_aes_128_ecb:
- return wolfSSL_EVP_aes_128_ecb();
- #endif
- #ifdef WOLFSSL_AES_192
- case NID_aes_192_ecb:
- return wolfSSL_EVP_aes_192_ecb();
- #endif
- #ifdef WOLFSSL_AES_256
- case NID_aes_256_ecb:
- return wolfSSL_EVP_aes_256_ecb();
- #endif
- #endif /* HAVE_AES_ECB */
- #ifdef HAVE_AESGCM
- #ifdef WOLFSSL_AES_128
- case NID_aes_128_gcm:
- return wolfSSL_EVP_aes_128_gcm();
- #endif
- #ifdef WOLFSSL_AES_192
- case NID_aes_192_gcm:
- return wolfSSL_EVP_aes_192_gcm();
- #endif
- #ifdef WOLFSSL_AES_256
- case NID_aes_256_gcm:
- return wolfSSL_EVP_aes_256_gcm();
- #endif
- #endif
- #endif
- #ifndef NO_DES3
- case NID_des_cbc:
- return wolfSSL_EVP_des_cbc();
- #ifdef WOLFSSL_DES_ECB
- case NID_des_ecb:
- return wolfSSL_EVP_des_ecb();
- #endif
- case NID_des_ede3_cbc:
- return wolfSSL_EVP_des_ede3_cbc();
- #ifdef WOLFSSL_DES_ECB
- case NID_des_ede3_ecb:
- return wolfSSL_EVP_des_ede3_ecb();
- #endif
- #endif /*NO_DES3*/
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- case NID_chacha20_poly1305:
- return wolfSSL_EVP_chacha20_poly1305();
- #endif
- default:
- WOLFSSL_MSG("Bad cipher id value");
- }
- return NULL;
- }
- void wolfSSL_EVP_init(void)
- {
- /* Does nothing. */
- }
- /* this function makes the assumption that out buffer is big enough for digest*/
- int wolfSSL_EVP_Digest(const unsigned char* in, int inSz, unsigned char* out,
- unsigned int* outSz, const WOLFSSL_EVP_MD* evp,
- WOLFSSL_ENGINE* eng)
- {
- int err;
- int hashType = WC_HASH_TYPE_NONE;
- int hashSz;
- WOLFSSL_ENTER("wolfSSL_EVP_Digest");
- if (in == NULL || out == NULL || evp == NULL) {
- WOLFSSL_MSG("Null argument passed in");
- return WOLFSSL_FAILURE;
- }
- err = wolfSSL_EVP_get_hashinfo(evp, &hashType, &hashSz);
- if (err != WOLFSSL_SUCCESS)
- return err;
- if (wc_Hash((enum wc_HashType)hashType, in, inSz, out, hashSz) != 0) {
- return WOLFSSL_FAILURE;
- }
- if (outSz != NULL)
- *outSz = hashSz;
- (void)eng;
- return WOLFSSL_SUCCESS;
- }
- static const struct alias {
- const char *name;
- const char *alias;
- } digest_alias_tbl[] =
- {
- {"MD4", "ssl3-md4"},
- {"MD5", "ssl3-md5"},
- {"SHA1", "ssl3-sha1"},
- {"SHA1", "SHA"},
- { NULL, NULL}
- };
- const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name)
- {
- char nameUpper[15]; /* 15 bytes should be enough for any name */
- size_t i;
- const struct alias *al;
- const struct s_ent *ent;
- for (i = 0; i < sizeof(nameUpper) && name[i] != '\0'; i++) {
- nameUpper[i] = (char)XTOUPPER((unsigned char) name[i]);
- }
- if (i < sizeof(nameUpper))
- nameUpper[i] = '\0';
- else
- return NULL;
- name = nameUpper;
- for (al = digest_alias_tbl; al->name != NULL; al++)
- if(XSTRCMP(name, al->alias) == 0) {
- name = al->name;
- break;
- }
- for (ent = md_tbl; ent->name != NULL; ent++)
- if(XSTRCMP(name, ent->name) == 0) {
- return (EVP_MD *)ent->name;
- }
- return NULL;
- }
- /* Returns the NID of the WOLFSSL_EVP_MD passed in.
- *
- * type - pointer to WOLFSSL_EVP_MD for which to return NID value
- *
- * Returns NID on success, or NID_undef if none exists.
- */
- int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
- {
- const struct s_ent *ent ;
- WOLFSSL_ENTER("EVP_MD_type");
- if (type == NULL) {
- WOLFSSL_MSG("MD type arg is NULL");
- return NID_undef;
- }
- for( ent = md_tbl; ent->name != NULL; ent++){
- if(XSTRCMP((const char *)type, ent->name) == 0) {
- return ent->nid;
- }
- }
- return NID_undef;
- }
- #ifndef NO_MD4
- /* return a pointer to MD4 EVP type */
- const WOLFSSL_EVP_MD* wolfSSL_EVP_md4(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_md4");
- return EVP_get_digestbyname("MD4");
- }
- #endif /* !NO_MD4 */
- #ifndef NO_MD5
- const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void)
- {
- WOLFSSL_ENTER("EVP_md5");
- return EVP_get_digestbyname("MD5");
- }
- #endif /* !NO_MD5 */
- #ifdef HAVE_BLAKE2
- /* return EVP_MD
- * @param none
- * @return "blake2b512"
- */
- const WOLFSSL_EVP_MD* wolfSSL_EVP_blake2b512(void)
- {
- WOLFSSL_ENTER("EVP_blake2b512");
- return EVP_get_digestbyname("BLAKE2b512");
- }
- #endif
- #ifdef HAVE_BLAKE2S
- /* return EVP_MD
- * @param none
- * @return "blake2s256"
- */
- const WOLFSSL_EVP_MD* wolfSSL_EVP_blake2s256(void)
- {
- WOLFSSL_ENTER("EVP_blake2s256");
- return EVP_get_digestbyname("BLAKE2s256");
- }
- #endif
- #ifndef NO_WOLFSSL_STUB
- void wolfSSL_EVP_set_pw_prompt(const char *prompt)
- {
- (void)prompt;
- WOLFSSL_STUB("EVP_set_pw_prompt");
- }
- #endif
- #ifndef NO_WOLFSSL_STUB
- const WOLFSSL_EVP_MD* wolfSSL_EVP_mdc2(void)
- {
- WOLFSSL_STUB("EVP_mdc2");
- return NULL;
- }
- #endif
- #ifndef NO_SHA
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void)
- {
- WOLFSSL_ENTER("EVP_sha1");
- return EVP_get_digestbyname("SHA1");
- }
- #endif /* NO_SHA */
- #ifdef WOLFSSL_SHA224
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha224(void)
- {
- WOLFSSL_ENTER("EVP_sha224");
- return EVP_get_digestbyname("SHA224");
- }
- #endif /* WOLFSSL_SHA224 */
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void)
- {
- WOLFSSL_ENTER("EVP_sha256");
- return EVP_get_digestbyname("SHA256");
- }
- #ifdef WOLFSSL_SHA384
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void)
- {
- WOLFSSL_ENTER("EVP_sha384");
- return EVP_get_digestbyname("SHA384");
- }
- #endif /* WOLFSSL_SHA384 */
- #ifdef WOLFSSL_SHA512
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void)
- {
- WOLFSSL_ENTER("EVP_sha512");
- return EVP_get_digestbyname("SHA512");
- }
- #ifndef WOLFSSL_NOSHA512_224
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512_224(void)
- {
- WOLFSSL_ENTER("EVP_sha512_224");
- return EVP_get_digestbyname("SHA512_224");
- }
- #endif /* !WOLFSSL_NOSHA512_224 */
- #ifndef WOLFSSL_NOSHA512_224
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512_256(void)
- {
- WOLFSSL_ENTER("EVP_sha512_256");
- return EVP_get_digestbyname("SHA512_256");
- }
- #endif /* !WOLFSSL_NOSHA512_224 */
- #endif /* WOLFSSL_SHA512 */
- #ifdef WOLFSSL_SHA3
- #ifndef WOLFSSL_NOSHA3_224
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_224(void)
- {
- WOLFSSL_ENTER("EVP_sha3_224");
- return EVP_get_digestbyname("SHA3_224");
- }
- #endif /* WOLFSSL_NOSHA3_224 */
- #ifndef WOLFSSL_NOSHA3_256
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_256(void)
- {
- WOLFSSL_ENTER("EVP_sha3_256");
- return EVP_get_digestbyname("SHA3_256");
- }
- #endif /* WOLFSSL_NOSHA3_256 */
- #ifndef WOLFSSL_NOSHA3_384
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_384(void)
- {
- WOLFSSL_ENTER("EVP_sha3_384");
- return EVP_get_digestbyname("SHA3_384");
- }
- #endif /* WOLFSSL_NOSHA3_384 */
- #ifndef WOLFSSL_NOSHA3_512
- const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_512(void)
- {
- WOLFSSL_ENTER("EVP_sha3_512");
- return EVP_get_digestbyname("SHA3_512");
- }
- #endif /* WOLFSSL_NOSHA3_512 */
- #ifdef WOLFSSL_SHAKE128
- const WOLFSSL_EVP_MD* wolfSSL_EVP_shake128(void)
- {
- WOLFSSL_ENTER("EVP_shake128");
- return EVP_get_digestbyname("SHAKE128");
- }
- #endif /* WOLFSSL_SHAKE128 */
- #ifdef WOLFSSL_SHAKE256
- const WOLFSSL_EVP_MD* wolfSSL_EVP_shake256(void)
- {
- WOLFSSL_ENTER("EVP_shake256");
- return EVP_get_digestbyname("SHAKE256");
- }
- #endif /* WOLFSSL_SHAKE256 */
- #endif /* WOLFSSL_SHA3 */
- WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new(void)
- {
- WOLFSSL_EVP_MD_CTX* ctx;
- WOLFSSL_ENTER("EVP_MD_CTX_new");
- ctx = (WOLFSSL_EVP_MD_CTX*)XMALLOC(sizeof *ctx, NULL,
- DYNAMIC_TYPE_OPENSSL);
- if (ctx){
- wolfSSL_EVP_MD_CTX_init(ctx);
- }
- return ctx;
- }
- void wolfSSL_EVP_MD_CTX_free(WOLFSSL_EVP_MD_CTX *ctx)
- {
- if (ctx) {
- WOLFSSL_ENTER("EVP_MD_CTX_free");
- wolfSSL_EVP_MD_CTX_cleanup(ctx);
- XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
- }
- }
- /* returns the NID of message digest used by the ctx */
- int wolfSSL_EVP_MD_CTX_type(const WOLFSSL_EVP_MD_CTX *ctx)
- {
- const struct s_ent *ent;
- WOLFSSL_ENTER("EVP_MD_CTX_type");
- if (ctx) {
- if (ctx->isHMAC) {
- return NID_hmac;
- }
- for(ent = md_tbl; ent->name != NULL; ent++) {
- if (ctx->macType == ent->macType) {
- return ent->nid;
- }
- }
- /* Return whatever we got */
- return ctx->macType;
- }
- return 0;
- }
- /* returns WOLFSSL_SUCCESS on success */
- int wolfSSL_EVP_MD_CTX_copy(WOLFSSL_EVP_MD_CTX *out, const WOLFSSL_EVP_MD_CTX *in)
- {
- return wolfSSL_EVP_MD_CTX_copy_ex(out, in);
- }
- /* returns digest size */
- int wolfSSL_EVP_MD_CTX_size(const WOLFSSL_EVP_MD_CTX *ctx) {
- return(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(ctx)));
- }
- /* returns block size */
- int wolfSSL_EVP_MD_CTX_block_size(const WOLFSSL_EVP_MD_CTX *ctx) {
- return(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(ctx)));
- }
- /* Deep copy of EVP_MD hasher
- * return WOLFSSL_SUCCESS on success */
- static int wolfSSL_EVP_MD_Copy_Hasher(WOLFSSL_EVP_MD_CTX* des,
- const WOLFSSL_EVP_MD_CTX* src)
- {
- int ret;
- if (src->isHMAC) {
- return wolfSSL_HmacCopy(&des->hash.hmac, (Hmac*)&src->hash.hmac);
- }
- else {
- switch (src->macType) {
- case WC_HASH_TYPE_MD5:
- #ifndef NO_MD5
- ret = wc_Md5Copy((wc_Md5*)&src->hash.digest,
- (wc_Md5*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif /* !NO_MD5 */
- break;
- case WC_HASH_TYPE_SHA:
- #ifndef NO_SHA
- ret = wc_ShaCopy((wc_Sha*)&src->hash.digest,
- (wc_Sha*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif /* !NO_SHA */
- break;
- case WC_HASH_TYPE_SHA224:
- #ifdef WOLFSSL_SHA224
- ret = wc_Sha224Copy((wc_Sha224*)&src->hash.digest,
- (wc_Sha224*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif /* WOLFSSL_SHA224 */
- break;
- case WC_HASH_TYPE_SHA256:
- #ifndef NO_SHA256
- ret = wc_Sha256Copy((wc_Sha256*)&src->hash.digest,
- (wc_Sha256*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif /* !NO_SHA256 */
- break;
- case WC_HASH_TYPE_SHA384:
- #ifdef WOLFSSL_SHA384
- ret = wc_Sha384Copy((wc_Sha384*)&src->hash.digest,
- (wc_Sha384*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif /* WOLFSSL_SHA384 */
- break;
- case WC_HASH_TYPE_SHA512:
- #ifdef WOLFSSL_SHA512
- ret = wc_Sha512Copy((wc_Sha512*)&src->hash.digest,
- (wc_Sha512*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif /* WOLFSSL_SHA512 */
- break;
- #ifndef WOLFSSL_NOSHA512_224
- case WC_HASH_TYPE_SHA512_224:
- #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
- defined(WOLFSSL_SHA512)
- ret = wc_Sha512_224Copy((wc_Sha512*)&src->hash.digest,
- (wc_Sha512*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif
- break;
- #endif /* !WOLFSSL_NOSHA512_224 */
- #ifndef WOLFSSL_NOSHA512_256
- case WC_HASH_TYPE_SHA512_256:
- #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
- defined(WOLFSSL_SHA512)
- ret = wc_Sha512_256Copy((wc_Sha512*)&src->hash.digest,
- (wc_Sha512*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif
- break;
- #endif /* !WOLFSSL_NOSHA512_256 */
- case WC_HASH_TYPE_SHA3_224:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
- ret = wc_Sha3_224_Copy((wc_Sha3*)&src->hash.digest,
- (wc_Sha3*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif
- break;
- case WC_HASH_TYPE_SHA3_256:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
- ret = wc_Sha3_256_Copy((wc_Sha3*)&src->hash.digest,
- (wc_Sha3*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif
- break;
- case WC_HASH_TYPE_SHA3_384:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
- ret = wc_Sha3_384_Copy((wc_Sha3*)&src->hash.digest,
- (wc_Sha3*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif
- break;
- case WC_HASH_TYPE_SHA3_512:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
- ret = wc_Sha3_512_Copy((wc_Sha3*)&src->hash.digest,
- (wc_Sha3*)&des->hash.digest);
- #else
- ret = NOT_COMPILED_IN;
- #endif
- break;
- case WC_HASH_TYPE_NONE:
- case WC_HASH_TYPE_MD2:
- case WC_HASH_TYPE_MD4:
- case WC_HASH_TYPE_MD5_SHA:
- case WC_HASH_TYPE_BLAKE2B:
- case WC_HASH_TYPE_BLAKE2S:
- #ifndef WOLFSSL_NO_SHAKE256
- case WC_HASH_TYPE_SHAKE128:
- case WC_HASH_TYPE_SHAKE256:
- #endif
- default:
- ret = BAD_FUNC_ARG;
- break;
- }
- return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
- }
- }
- /* copies structure in to the structure out
- *
- * returns WOLFSSL_SUCCESS on success */
- int wolfSSL_EVP_MD_CTX_copy_ex(WOLFSSL_EVP_MD_CTX *out, const WOLFSSL_EVP_MD_CTX *in)
- {
- if ((out == NULL) || (in == NULL)) return WOLFSSL_FAILURE;
- WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_copy_ex");
- XMEMCPY(out, in, sizeof(WOLFSSL_EVP_MD_CTX));
- if (in->pctx != NULL) {
- out->pctx = wolfSSL_EVP_PKEY_CTX_new(in->pctx->pkey, NULL);
- if (out->pctx == NULL)
- return WOLFSSL_FAILURE;
- }
- return wolfSSL_EVP_MD_Copy_Hasher(out, (WOLFSSL_EVP_MD_CTX*)in);
- }
- void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx)
- {
- WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_init");
- XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_MD_CTX));
- }
- const WOLFSSL_EVP_MD *wolfSSL_EVP_MD_CTX_md(const WOLFSSL_EVP_MD_CTX *ctx)
- {
- const struct s_ent *ent;
- if (ctx == NULL)
- return NULL;
- WOLFSSL_ENTER("EVP_MD_CTX_md");
- if (ctx->isHMAC) {
- return "HMAC";
- }
- for(ent = md_tbl; ent->name != NULL; ent++) {
- if(ctx->macType == ent->macType) {
- return (const WOLFSSL_EVP_MD *)ent->name;
- }
- }
- return (WOLFSSL_EVP_MD *)NULL;
- }
- /* return alias name if has
- * @param n message digest type name
- * @return alias name, otherwise NULL
- */
- static const char* hasAliasName(const char* n)
- {
- const char* aliasnm = NULL;
- const struct alias *al;
- for (al = digest_alias_tbl; al->name != NULL; al++)
- if(XSTRCMP(n, al->name) == 0) {
- aliasnm = al->alias;
- break;
- }
- return aliasnm;
- }
- struct do_all_md {
- void *arg;
- void (*fn) (const WOLFSSL_EVP_MD *m,
- const char* from, const char* to, void *arg);
- };
- /* do all md algorithm
- * @param nm a pointer to WOLFSSL_OBJ_NAME
- * @param arg arguments to pass to the callback
- * @return none
- */
- static void md_do_all_func(const WOLFSSL_OBJ_NAME* nm, void* arg)
- {
- struct do_all_md *md = (struct do_all_md*)arg;
- const struct s_ent *ent;
- /* sanity check */
- if (md == NULL || nm == NULL || md->fn == NULL ||
- nm->type != WOLFSSL_OBJ_NAME_TYPE_MD_METH)
- return;
- /* loop all md */
- for (ent = md_tbl; ent->name != NULL; ent++){
- /* check if the md has alias */
- if(hasAliasName(ent->name) != NULL) {
- md->fn(NULL, ent->name, ent->name, md->arg);
- }
- else {
- md->fn(ent->name, ent->name, NULL, md->arg);
- }
- }
- }
- /* call md_do_all function to do all md algorithm via a callback function
- * @param fn a callback function to be called with all 'md'
- * @param args arguments to pass to the callback
- * @return none
- */
- void wolfSSL_EVP_MD_do_all(void (*fn) (const WOLFSSL_EVP_MD *m,
- const char* from, const char* to, void* xx), void* args)
- {
- struct do_all_md md;
- md.fn = fn;
- md.arg = args;
- wolfSSL_OBJ_NAME_do_all(WOLFSSL_OBJ_NAME_TYPE_MD_METH,
- md_do_all_func, &md);
- }
- /* call "fn" based on OBJ_NAME type
- * @param type OBJ_NAME type
- * @param fn a callback function
- * @param args arguments to pass to the callback
- * @return none
- */
- void wolfSSL_OBJ_NAME_do_all(int type,
- void (*fn)(const WOLFSSL_OBJ_NAME*, void* arg), void* arg)
- {
- WOLFSSL_OBJ_NAME objnm;
- /* sanity check */
- if (!fn)
- return;
- objnm.type = type;
- switch(type) {
- case WOLFSSL_OBJ_NAME_TYPE_MD_METH:
- fn(&objnm, arg);
- break;
- case WOLFSSL_OBJ_NAME_TYPE_CIPHER_METH:
- case WOLFSSL_OBJ_NAME_TYPE_PKEY_METH:
- case WOLFSSL_OBJ_NAME_TYPE_COMP_METH:
- case WOLFSSL_OBJ_NAME_TYPE_NUM:
- WOLFSSL_MSG("not implemented");
- FALL_THROUGH;
- case WOLFSSL_OBJ_NAME_TYPE_UNDEF:
- default:
- break;
- }
- }
- #ifndef NO_AES
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- #ifdef WOLFSSL_AES_128
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cbc");
- return EVP_AES_128_CBC;
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cbc");
- return EVP_AES_192_CBC;
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cbc");
- return EVP_AES_256_CBC;
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* HAVE_AES_CBC */
- #ifdef WOLFSSL_AES_CFB
- #if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
- #ifdef WOLFSSL_AES_128
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb1(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cfb1");
- return EVP_AES_128_CFB1;
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb1(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cfb1");
- return EVP_AES_192_CFB1;
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb1(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cfb1");
- return EVP_AES_256_CFB1;
- }
- #endif /* WOLFSSL_AES_256 */
- #ifdef WOLFSSL_AES_128
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb8(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cfb8");
- return EVP_AES_128_CFB8;
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb8(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cfb8");
- return EVP_AES_192_CFB8;
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb8(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cfb8");
- return EVP_AES_256_CFB8;
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* !HAVE_SELFTEST && !HAVE_FIPS */
- #ifdef WOLFSSL_AES_128
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb128(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cfb128");
- return EVP_AES_128_CFB128;
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb128(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cfb128");
- return EVP_AES_192_CFB128;
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb128(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cfb128");
- return EVP_AES_256_CFB128;
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* WOLFSSL_AES_CFB */
- #ifdef WOLFSSL_AES_OFB
- #ifdef WOLFSSL_AES_128
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ofb(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ofb");
- return EVP_AES_128_OFB;
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ofb(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ofb");
- return EVP_AES_192_OFB;
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ofb(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ofb");
- return EVP_AES_256_OFB;
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* WOLFSSL_AES_OFB */
- #ifdef WOLFSSL_AES_XTS
- #ifdef WOLFSSL_AES_128
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_xts(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_128_xts");
- return EVP_AES_128_XTS;
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_256
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_xts(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_256_xts");
- return EVP_AES_256_XTS;
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* WOLFSSL_AES_XTS */
- #ifdef HAVE_AESGCM
- #ifdef WOLFSSL_AES_128
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_gcm(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_128_gcm");
- return EVP_AES_128_GCM;
- }
- #endif /* WOLFSSL_GCM_128 */
- #ifdef WOLFSSL_AES_192
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_gcm(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_192_gcm");
- return EVP_AES_192_GCM;
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_gcm(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_256_gcm");
- return EVP_AES_256_GCM;
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* HAVE_AESGCM */
- #ifdef WOLFSSL_AES_COUNTER
- #ifdef WOLFSSL_AES_128
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ctr");
- return EVP_AES_128_CTR;
- }
- #endif /* WOLFSSL_AES_2128 */
- #ifdef WOLFSSL_AES_192
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ctr");
- return EVP_AES_192_CTR;
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ctr");
- return EVP_AES_256_CTR;
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* WOLFSSL_AES_COUNTER */
- #ifdef HAVE_AES_ECB
- #ifdef WOLFSSL_AES_128
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ecb(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ecb");
- return EVP_AES_128_ECB;
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ecb(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ecb");
- return EVP_AES_192_ECB;
- }
- #endif /* WOLFSSL_AES_192*/
- #ifdef WOLFSSL_AES_256
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ecb(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ecb");
- return EVP_AES_256_ECB;
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* HAVE_AES_ECB */
- #endif /* NO_AES */
- #ifndef NO_DES3
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_des_cbc");
- return EVP_DES_CBC;
- }
- #ifdef WOLFSSL_DES_ECB
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ecb(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_des_ecb");
- return EVP_DES_ECB;
- }
- #endif
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc");
- return EVP_DES_EDE3_CBC;
- }
- #ifdef WOLFSSL_DES_ECB
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_ecb(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_ecb");
- return EVP_DES_EDE3_ECB;
- }
- #endif
- #endif /* NO_DES3 */
- #ifndef NO_RC4
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_rc4");
- return EVP_ARC4;
- }
- #endif
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_chacha20_poly1305(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_chacha20_poly1305");
- return EVP_CHACHA20_POLY1305;
- }
- #endif
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_enc_null");
- return EVP_NULL;
- }
- int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx)
- {
- int ret = WOLFSSL_SUCCESS;
- WOLFSSL_ENTER("EVP_MD_CTX_cleanup");
- if (ctx->pctx != NULL)
- wolfSSL_EVP_PKEY_CTX_free(ctx->pctx);
- if (ctx->isHMAC) {
- wc_HmacFree(&ctx->hash.hmac);
- }
- else {
- switch (ctx->macType) {
- case WC_HASH_TYPE_MD5:
- #ifndef NO_MD5
- wc_Md5Free((wc_Md5*)&ctx->hash.digest);
- #endif /* !NO_MD5 */
- break;
- case WC_HASH_TYPE_SHA:
- #ifndef NO_SHA
- wc_ShaFree((wc_Sha*)&ctx->hash.digest);
- #endif /* !NO_SHA */
- break;
- case WC_HASH_TYPE_SHA224:
- #ifdef WOLFSSL_SHA224
- wc_Sha224Free((wc_Sha224*)&ctx->hash.digest);
- #endif /* WOLFSSL_SHA224 */
- break;
- case WC_HASH_TYPE_SHA256:
- #ifndef NO_SHA256
- wc_Sha256Free((wc_Sha256*)&ctx->hash.digest);
- #endif /* !NO_SHA256 */
- break;
- case WC_HASH_TYPE_SHA384:
- #ifdef WOLFSSL_SHA384
- wc_Sha384Free((wc_Sha384*)&ctx->hash.digest);
- #endif /* WOLFSSL_SHA384 */
- break;
- case WC_HASH_TYPE_SHA512:
- #ifdef WOLFSSL_SHA512
- wc_Sha512Free((wc_Sha512*)&ctx->hash.digest);
- #endif /* WOLFSSL_SHA512 */
- break;
- #ifndef WOLFSSL_NOSHA512_224
- case WC_HASH_TYPE_SHA512_224:
- #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
- defined(WOLFSSL_SHA512)
- wc_Sha512_224Free((wc_Sha512*)&ctx->hash.digest);
- #endif
- break;
- #endif /* !WOLFSSL_NOSHA512_224 */
- #ifndef WOLFSSL_NOSHA512_256
- case WC_HASH_TYPE_SHA512_256:
- #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
- defined(WOLFSSL_SHA512)
- wc_Sha512_256Free((wc_Sha512*)&ctx->hash.digest);
- #endif
- break;
- #endif /* !WOLFSSL_NOSHA512_256 */
- case WC_HASH_TYPE_SHA3_224:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
- wc_Sha3_224_Free((wc_Sha3*)&ctx->hash.digest);
- #endif
- break;
- case WC_HASH_TYPE_SHA3_256:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
- wc_Sha3_256_Free((wc_Sha3*)&ctx->hash.digest);
- #endif
- break;
- case WC_HASH_TYPE_SHA3_384:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
- wc_Sha3_384_Free((wc_Sha3*)&ctx->hash.digest);
- #endif
- break;
- case WC_HASH_TYPE_SHA3_512:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
- wc_Sha3_512_Free((wc_Sha3*)&ctx->hash.digest);
- #endif
- break;
- case WC_HASH_TYPE_NONE:
- /* Not an error since an unused struct could be free'd or
- * reset. */
- break;
- case WC_HASH_TYPE_MD2:
- case WC_HASH_TYPE_MD4:
- case WC_HASH_TYPE_MD5_SHA:
- case WC_HASH_TYPE_BLAKE2B:
- case WC_HASH_TYPE_BLAKE2S:
- #ifndef WOLFSSL_NO_SHAKE256
- case WC_HASH_TYPE_SHAKE128:
- case WC_HASH_TYPE_SHAKE256:
- #endif
- default:
- ret = WOLFSSL_FAILURE;
- break;
- }
- }
- ForceZero(ctx, sizeof(*ctx));
- ctx->macType = WC_HASH_TYPE_NONE;
- return ret;
- }
- void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx)
- {
- WOLFSSL_ENTER("EVP_CIPHER_CTX_init");
- if (ctx) {
- XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_CIPHER_CTX));
- ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT; /* not yet initialized */
- ctx->keyLen = 0;
- ctx->enc = 1; /* start in encrypt mode */
- }
- }
- /* This function allows cipher specific parameters to be
- determined and set. */
- int wolfSSL_EVP_CIPHER_CTX_ctrl(WOLFSSL_EVP_CIPHER_CTX *ctx, int type, \
- int arg, void *ptr)
- {
- int ret = WOLFSSL_FAILURE;
- #ifndef WC_NO_RNG
- WC_RNG rng;
- #endif
- if (ctx == NULL)
- return WOLFSSL_FAILURE;
- (void)arg;
- (void)ptr;
- WOLFSSL_ENTER("EVP_CIPHER_CTX_ctrl");
- switch(type) {
- case EVP_CTRL_INIT:
- wolfSSL_EVP_CIPHER_CTX_init(ctx);
- if(ctx)
- ret = WOLFSSL_SUCCESS;
- break;
- case EVP_CTRL_SET_KEY_LENGTH:
- ret = wolfSSL_EVP_CIPHER_CTX_set_key_length(ctx, arg);
- break;
- #if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
- case EVP_CTRL_AEAD_SET_IVLEN:
- if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
- break;
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- if (ctx->cipherType == CHACHA20_POLY1305_TYPE) {
- if (arg != CHACHA20_POLY1305_AEAD_IV_SIZE) {
- break;
- }
- }
- else
- #endif /* HAVE_CHACHA && HAVE_POLY1305 */
- {
- if (arg <= 0 || arg > AES_BLOCK_SIZE)
- break;
- }
- ret = wolfSSL_EVP_CIPHER_CTX_set_iv_length(ctx, arg);
- break;
- case EVP_CTRL_AEAD_SET_IV_FIXED:
- if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
- break;
- if (arg == -1) {
- /* arg == -1 copies ctx->ivSz from ptr */
- ret = wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, (byte*)ptr, ctx->ivSz);
- }
- #ifndef WC_NO_RNG
- else {
- /*
- * Fixed field must be at least 4 bytes and invocation
- * field at least 8.
- */
- if ((arg < 4) || (ctx->ivSz - arg) < 8) {
- WOLFSSL_MSG("Fixed field or invocation field too short");
- break;
- }
- /* arg is 4...(ctx->ivSz - 8) */
- XMEMCPY(ctx->iv, ptr, arg);
- if (wc_InitRng(&rng) != 0) {
- WOLFSSL_MSG("wc_InitRng failed");
- break;
- }
- if (wc_RNG_GenerateBlock(&rng, ctx->iv + arg,
- ctx->ivSz - arg) == 0) {
- ret = WOLFSSL_SUCCESS;
- } else {
- /* rng is freed immediately after if block so no need
- * to do it here
- */
- WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
- }
- if (wc_FreeRng(&rng) != 0) {
- WOLFSSL_MSG("wc_FreeRng failed");
- ret = WOLFSSL_FAILURE;
- break;
- }
- }
- #ifdef HAVE_AESGCM
- if (ret == WOLFSSL_SUCCESS) {
- /*
- * OpenSSL requires that a EVP_CTRL_AEAD_SET_IV_FIXED
- * command be issued before a EVP_CTRL_GCM_IV_GEN command.
- * This flag is used to enforce that.
- */
- ctx->gcmIvGenEnable = 1;
- }
- #endif
- #endif /* !WC_NO_RNG */
- break;
- #if defined(HAVE_AESGCM) && !defined(_WIN32) && !defined(HAVE_SELFTEST) && \
- (!defined(HAVE_FIPS) || FIPS_VERSION_GE(2,0))
- /*
- * Using EVP_CTRL_GCM_IV_GEN is a way to do AES-GCM encrypt/decrypt
- * multiple times with EVP_Cipher without having to call
- * EVP_CipherInit between each iteration. The IV is incremented for
- * each subsequent EVP_Cipher call to prevent IV reuse.
- */
- case EVP_CTRL_GCM_IV_GEN:
- if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
- break;
- if (!ctx->gcmIvGenEnable) {
- WOLFSSL_MSG("Must use EVP_CTRL_AEAD_SET_IV_FIXED before "
- "EVP_CTRL_GCM_IV_GEN");
- break;
- }
- if (ctx->cipher.aes.keylen == 0 || ctx->ivSz == 0) {
- WOLFSSL_MSG("Key or IV not set");
- break;
- }
- if (ptr == NULL) {
- WOLFSSL_MSG("Destination buffer for IV bytes NULL.");
- break;
- }
- if (arg <= 0 || arg > ctx->ivSz) {
- XMEMCPY(ptr, ctx->iv, ctx->ivSz);
- }
- else {
- /*
- * Copy the last "arg" bytes of ctx->iv into the buffer at
- * "ptr." Not sure why OpenSSL does this, but it does.
- */
- XMEMCPY(ptr, ctx->iv + ctx->ivSz - arg, arg);
- }
- /*
- * The gcmIncIV flag indicates that the IV should be incremented
- * after the next cipher operation.
- */
- ctx->gcmIncIv = 1;
- ret = WOLFSSL_SUCCESS;
- break;
- #endif /* HAVE_AESGCM && !_WIN32 && !HAVE_SELFTEST && (!HAVE_FIPS ||
- * FIPS_VERSION >= 2)*/
- case EVP_CTRL_AEAD_SET_TAG:
- if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
- break;
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- if (ctx->cipherType == CHACHA20_POLY1305_TYPE) {
- if (arg != CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE) {
- break;
- }
- ctx->authTagSz = arg;
- ret = WOLFSSL_SUCCESS;
- if (ptr != NULL) {
- XMEMCPY(ctx->authTag, ptr, arg);
- }
- break;
- }
- else
- #endif /* HAVE_CHACHA && HAVE_POLY1305 */
- {
- if(arg <= 0 || arg > 16 || (ptr == NULL))
- break;
- XMEMCPY(ctx->authTag, ptr, arg);
- ctx->authTagSz = arg;
- ret = WOLFSSL_SUCCESS;
- break;
- }
- case EVP_CTRL_AEAD_GET_TAG:
- if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
- break;
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- if (ctx->cipherType == CHACHA20_POLY1305_TYPE) {
- if (arg != CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE) {
- break;
- }
- }
- else
- #endif /* HAVE_CHACHA && HAVE_POLY1305 */
- {
- if (arg <= 0 || arg > AES_BLOCK_SIZE)
- break;
- }
- if (ptr != NULL) {
- XMEMCPY(ptr, ctx->authTag, arg);
- ret = WOLFSSL_SUCCESS;
- }
- break;
- #endif /* HAVE_AESGCM || (HAVE_CHACHA && HAVE_POLY1305) */
- default:
- WOLFSSL_MSG("EVP_CIPHER_CTX_ctrl operation not yet handled");
- break;
- }
- return ret;
- }
- /* WOLFSSL_SUCCESS on ok */
- int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx)
- {
- WOLFSSL_ENTER("EVP_CIPHER_CTX_cleanup");
- if (ctx) {
- #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
- (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
- #if defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM)
- if ((ctx->cipherType == AES_128_GCM_TYPE) ||
- (ctx->cipherType == AES_192_GCM_TYPE) ||
- (ctx->cipherType == AES_256_GCM_TYPE)) {
- wc_AesFree(&ctx->cipher.aes);
- }
- #endif /* HAVE_AESGCM && WOLFSSL_AESGCM_STREAM */
- #endif /* not FIPS or FIPS v2+ */
- ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT; /* not yet initialized */
- ctx->keyLen = 0;
- #ifdef HAVE_AESGCM
- if (ctx->gcmBuffer) {
- XFREE(ctx->gcmBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
- ctx->gcmBuffer = NULL;
- }
- ctx->gcmBufferLen = 0;
- if (ctx->gcmAuthIn) {
- XFREE(ctx->gcmAuthIn, NULL, DYNAMIC_TYPE_OPENSSL);
- ctx->gcmAuthIn = NULL;
- }
- ctx->gcmAuthInSz = 0;
- ctx->gcmIvGenEnable = 0;
- ctx->gcmIncIv = 0;
- #endif
- }
- return WOLFSSL_SUCCESS;
- }
- /* Permanent stub for Qt compilation. */
- #if defined(WOLFSSL_QT) && !defined(NO_WOLFSSL_STUB)
- const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc2_cbc(void)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_rc2_cbc");
- WOLFSSL_STUB("EVP_rc2_cbc");
- return NULL;
- }
- #endif
- #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
- int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type,
- const WOLFSSL_EVP_MD* md, const byte* salt,
- const byte* data, int sz, int count, byte* key, byte* iv)
- {
- int ret;
- int hashType = WC_HASH_TYPE_NONE;
- #ifdef WOLFSSL_SMALL_STACK
- EncryptedInfo* info;
- #else
- EncryptedInfo info[1];
- #endif
- #ifdef WOLFSSL_SMALL_STACK
- info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
- DYNAMIC_TYPE_ENCRYPTEDINFO);
- if (info == NULL) {
- WOLFSSL_MSG("malloc failed");
- return WOLFSSL_FAILURE;
- }
- #endif
- XMEMSET(info, 0, sizeof(EncryptedInfo));
- ret = wc_EncryptedInfoGet(info, type);
- if (ret < 0)
- goto end;
- if (data == NULL) {
- ret = info->keySz;
- goto end;
- }
- ret = wolfSSL_EVP_get_hashinfo(md, &hashType, NULL);
- if (ret == WOLFSSL_FAILURE)
- goto end;
- ret = wc_PBKDF1_ex(key, info->keySz, iv, info->ivSz, data, sz, salt,
- EVP_SALT_SIZE, count, hashType, NULL);
- if (ret == 0)
- ret = info->keySz;
- end:
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
- #endif
- if (ret < 0)
- return 0; /* failure - for compatibility */
- return ret;
- }
- #endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */
- #ifndef NO_AES
- #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
- defined(WOLFSSL_AES_256)
- #define AES_SIZE_ANY
- #endif
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) || \
- defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_CFB) || \
- defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_DIRECT)
- #define AES_SET_KEY
- #endif
- #if defined(AES_SIZE_ANY) && defined(AES_SET_KEY)
- static int AesSetKey_ex(Aes* aes, const byte* key, word32 len,
- const byte* iv, int dir, int direct)
- {
- int ret;
- /* wc_AesSetKey clear aes.reg if iv == NULL.
- Keep IV for openSSL compatibility */
- if (iv == NULL)
- XMEMCPY((byte *)aes->tmp, (byte *)aes->reg, AES_BLOCK_SIZE);
- if (direct) {
- #if defined(WOLFSSL_AES_DIRECT)
- ret = wc_AesSetKeyDirect(aes, key, len, iv, dir);
- #else
- ret = NOT_COMPILED_IN;
- #endif
- }
- else {
- ret = wc_AesSetKey(aes, key, len, iv, dir);
- }
- if (iv == NULL)
- XMEMCPY((byte *)aes->reg, (byte *)aes->tmp, AES_BLOCK_SIZE);
- return ret;
- }
- #endif /* AES_ANY_SIZE && AES_SET_KEY */
- #endif /* NO_AES */
- #if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
- || FIPS_VERSION_GE(2,0))
- static int EvpCipherInitAesGCM(WOLFSSL_EVP_CIPHER_CTX* ctx,
- const WOLFSSL_EVP_CIPHER* type,
- const byte* key, const byte* iv, int enc)
- {
- int ret = WOLFSSL_SUCCESS;
- if (ctx->gcmAuthIn) {
- XFREE(ctx->gcmAuthIn, NULL, DYNAMIC_TYPE_OPENSSL);
- ctx->gcmAuthIn = NULL;
- }
- ctx->gcmAuthInSz = 0;
- ctx->block_size = AES_BLOCK_SIZE;
- ctx->authTagSz = AES_BLOCK_SIZE;
- if (ctx->ivSz == 0) {
- ctx->ivSz = GCM_NONCE_MID_SZ;
- }
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE |
- WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
- if (enc == 0 || enc == 1) {
- ctx->enc = enc ? 1 : 0;
- }
- #ifdef WOLFSSL_AES_128
- if (ctx->cipherType == AES_128_GCM_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_GCM))) {
- WOLFSSL_MSG("EVP_AES_128_GCM");
- ctx->cipherType = AES_128_GCM_TYPE;
- ctx->keyLen = AES_128_KEY_SIZE;
- }
- #endif
- #ifdef WOLFSSL_AES_192
- if (ctx->cipherType == AES_192_GCM_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_GCM))) {
- WOLFSSL_MSG("EVP_AES_192_GCM");
- ctx->cipherType = AES_192_GCM_TYPE;
- ctx->keyLen = AES_192_KEY_SIZE;
- }
- #endif
- #ifdef WOLFSSL_AES_256
- if (ctx->cipherType == AES_256_GCM_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_GCM))) {
- WOLFSSL_MSG("EVP_AES_256_GCM");
- ctx->cipherType = AES_256_GCM_TYPE;
- ctx->keyLen = AES_256_KEY_SIZE;
- }
- #endif
- #ifndef WOLFSSL_AESGCM_STREAM
- if (ret == WOLFSSL_SUCCESS && key &&
- wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
- WOLFSSL_MSG("wc_AesGcmSetKey() failed");
- ret = WOLFSSL_FAILURE;
- }
- #endif /* !WOLFSSL_AESGCM_STREAM */
- if (ret == WOLFSSL_SUCCESS && iv &&
- wc_AesGcmSetExtIV(&ctx->cipher.aes, iv, ctx->ivSz)) {
- WOLFSSL_MSG("wc_AesGcmSetExtIV() failed");
- ret = WOLFSSL_FAILURE;
- }
- #ifdef WOLFSSL_AESGCM_STREAM
- /*
- * Initialize with key and IV if available. wc_AesGcmInit will fail
- * if called with IV only and no key has been set.
- */
- if (ret == WOLFSSL_SUCCESS &&
- (key || (iv && ctx->cipher.aes.gcmKeySet)) &&
- wc_AesGcmInit(&ctx->cipher.aes, key,
- (key == NULL) ? 0 : ctx->keyLen, iv,
- (iv == NULL) ? 0 : ctx->ivSz) != 0) {
- WOLFSSL_MSG("wc_AesGcmInit() failed");
- ret = WOLFSSL_FAILURE;
- }
- #endif /* WOLFSSL_AESGCM_STREAM */
- /*
- * OpenSSL clears this flag, which permits subsequent use of
- * EVP_CTRL_GCM_IV_GEN, when EVP_CipherInit is called with no key.
- * If a key is provided, the flag retains its value.
- */
- if (ret == WOLFSSL_SUCCESS && key == NULL) {
- ctx->gcmIvGenEnable = 0;
- }
- return ret;
- }
- static int EvpCipherAesGCM(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst,
- byte* src, word32 len)
- {
- int ret = WOLFSSL_FAILURE;
- #ifndef WOLFSSL_AESGCM_STREAM
- /* No destination means only AAD. */
- if (src != NULL && dst == NULL) {
- ret = wolfSSL_EVP_CipherUpdate_GCM_AAD(ctx, src, len);
- }
- else if (src != NULL && dst != NULL) {
- if (ctx->enc) {
- ret = wc_AesGcmEncrypt(&ctx->cipher.aes, dst, src,
- len, ctx->iv, ctx->ivSz, ctx->authTag,
- ctx->authTagSz, ctx->gcmAuthIn,
- ctx->gcmAuthInSz);
- }
- else {
- ret = wc_AesGcmDecrypt(&ctx->cipher.aes, dst, src,
- len, ctx->iv, ctx->ivSz, ctx->authTag,
- ctx->authTagSz, ctx->gcmAuthIn,
- ctx->gcmAuthInSz);
- }
- if (ctx->gcmIncIv) {
- IncCtr((byte*)ctx->cipher.aes.reg,
- ctx->cipher.aes.nonceSz);
- ctx->gcmIncIv = 0;
- }
- }
- #else
- /*
- * No need to call wc_AesGcmInit. Should have been called by
- * wolfSSL_EVP_CipherInit.
- */
- /* NULL dst and non-NULL src means only AAD. */
- if (src != NULL && dst == NULL) {
- if (ctx->enc) {
- ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, NULL,
- NULL, 0, src, len);
- }
- else {
- ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, NULL,
- NULL, 0, src, len);
- }
- }
- /* Only plain/cipher text. */
- else if (src != NULL && dst != NULL) {
- if (ctx->enc) {
- ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, dst, src,
- len, NULL, 0);
- }
- else {
- ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, dst, src,
- len, NULL, 0);
- }
- }
- /*
- * src == NULL is analogous to other "final"-type functions
- * (e.g. EVP_CipherFinal). Calculates tag on encrypt
- * and checks tag on decrypt.
- */
- else {
- if (ctx->enc) {
- /* Calculate authentication tag. */
- ret = wc_AesGcmEncryptFinal(&ctx->cipher.aes,
- ctx->authTag, ctx->authTagSz);
- /*
- * wc_AesGcmEncryptFinal increments the IV in
- * ctx->cipher.aes.reg, so we don't call IncCtr here.
- */
- }
- else {
- /* Calculate authentication tag and compare. */
- ret = wc_AesGcmDecryptFinal(&ctx->cipher.aes,
- ctx->authTag, ctx->authTagSz);
- if (ctx->gcmIncIv) {
- IncCtr((byte*)ctx->cipher.aes.reg,
- ctx->cipher.aes.nonceSz);
- }
- }
- /* Reinitialize for subsequent wolfSSL_EVP_Cipher calls. */
- if (wc_AesGcmInit(&ctx->cipher.aes, NULL, 0,
- (byte*)ctx->cipher.aes.reg,
- ctx->ivSz) != 0) {
- WOLFSSL_MSG("wc_AesGcmInit failed");
- return WOLFSSL_FATAL_ERROR;
- }
- ctx->gcmIncIv = 0;
- }
- #endif /* WOLFSSL_AESGCM_STREAM */
- if (src == NULL) {
- /*
- * Clear any leftover AAD on final (final is when src is
- * NULL).
- */
- if (ctx->gcmAuthIn != NULL) {
- XMEMSET(ctx->gcmAuthIn, 0, ctx->gcmAuthInSz);
- }
- ctx->gcmAuthInSz = 0;
- }
- if (ret == 0) {
- ret = len;
- }
- return ret;
- }
- #endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
- * HAVE_FIPS_VERSION >= 2 */
- /* return WOLFSSL_SUCCESS on ok, 0 on failure to match API compatibility */
- int wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
- const WOLFSSL_EVP_CIPHER* type, const byte* key,
- const byte* iv, int enc)
- {
- int ret = 0;
- (void)key;
- (void)iv;
- (void)enc;
- WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
- if (ctx == NULL) {
- WOLFSSL_MSG("no ctx");
- return WOLFSSL_FAILURE;
- }
- if (type == NULL && ctx->cipherType == WOLFSSL_EVP_CIPH_TYPE_INIT) {
- WOLFSSL_MSG("no type set");
- return WOLFSSL_FAILURE;
- }
- if (ctx->cipherType == WOLFSSL_EVP_CIPH_TYPE_INIT){
- /* only first EVP_CipherInit invoke. ctx->cipherType is set below */
- XMEMSET(&ctx->cipher, 0, sizeof(ctx->cipher));
- ctx->flags = 0;
- }
- /* always clear buffer state */
- ctx->bufUsed = 0;
- ctx->lastUsed = 0;
- #ifdef HAVE_WOLFSSL_EVP_CIPHER_CTX_IV
- if (!iv && ctx->ivSz) {
- iv = ctx->iv;
- }
- #endif
- #ifndef NO_AES
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- #ifdef WOLFSSL_AES_128
- if (ctx->cipherType == AES_128_CBC_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_CBC))) {
- WOLFSSL_MSG("EVP_AES_128_CBC");
- ctx->cipherType = AES_128_CBC_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE;
- ctx->keyLen = 16;
- ctx->block_size = AES_BLOCK_SIZE;
- ctx->ivSz = AES_BLOCK_SIZE;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- if (ctx->cipherType == AES_192_CBC_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_CBC))) {
- WOLFSSL_MSG("EVP_AES_192_CBC");
- ctx->cipherType = AES_192_CBC_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE;
- ctx->keyLen = 24;
- ctx->block_size = AES_BLOCK_SIZE;
- ctx->ivSz = AES_BLOCK_SIZE;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- if (ctx->cipherType == AES_256_CBC_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_CBC))) {
- WOLFSSL_MSG("EVP_AES_256_CBC");
- ctx->cipherType = AES_256_CBC_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE;
- ctx->keyLen = 32;
- ctx->block_size = AES_BLOCK_SIZE;
- ctx->ivSz = AES_BLOCK_SIZE;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0);
- if (ret != 0){
- WOLFSSL_MSG("AesSetKey() failed");
- return WOLFSSL_FAILURE;
- }
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0){
- WOLFSSL_MSG("wc_AesSetIV() failed");
- return WOLFSSL_FAILURE;
- }
- }
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
- #if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
- || FIPS_VERSION_GE(2,0))
- if (
- #ifdef WOLFSSL_AES_128
- ctx->cipherType == AES_128_GCM_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_GCM))
- #endif
- #ifdef WOLFSSL_AES_192
- || ctx->cipherType == AES_192_GCM_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_GCM))
- #endif
- #ifdef WOLFSSL_AES_256
- || ctx->cipherType == AES_256_GCM_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_GCM))
- #endif
- ) {
- if (EvpCipherInitAesGCM(ctx, type, key, iv, enc)
- != WOLFSSL_SUCCESS) {
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
- * HAVE_FIPS_VERSION >= 2 */
- #ifdef WOLFSSL_AES_COUNTER
- #ifdef WOLFSSL_AES_128
- if (ctx->cipherType == AES_128_CTR_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_CTR))) {
- WOLFSSL_MSG("EVP_AES_128_CTR");
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->cipherType = AES_128_CTR_TYPE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CTR_MODE;
- ctx->keyLen = 16;
- ctx->block_size = NO_PADDING_BLOCK_SIZE;
- ctx->ivSz = AES_BLOCK_SIZE;
- #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB)
- ctx->cipher.aes.left = 0;
- #endif
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 1);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- if (ctx->cipherType == AES_192_CTR_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_CTR))) {
- WOLFSSL_MSG("EVP_AES_192_CTR");
- ctx->cipherType = AES_192_CTR_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CTR_MODE;
- ctx->keyLen = 24;
- ctx->block_size = NO_PADDING_BLOCK_SIZE;
- ctx->ivSz = AES_BLOCK_SIZE;
- #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB)
- ctx->cipher.aes.left = 0;
- #endif
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 1);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- if (ctx->cipherType == AES_256_CTR_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_CTR))) {
- WOLFSSL_MSG("EVP_AES_256_CTR");
- ctx->cipherType = AES_256_CTR_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CTR_MODE;
- ctx->keyLen = 32;
- ctx->block_size = NO_PADDING_BLOCK_SIZE;
- ctx->ivSz = AES_BLOCK_SIZE;
- #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB)
- ctx->cipher.aes.left = 0;
- #endif
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 1);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* WOLFSSL_AES_COUNTER */
- #ifdef HAVE_AES_ECB
- #ifdef WOLFSSL_AES_128
- if (ctx->cipherType == AES_128_ECB_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_ECB))) {
- WOLFSSL_MSG("EVP_AES_128_ECB");
- ctx->cipherType = AES_128_ECB_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_ECB_MODE;
- ctx->keyLen = 16;
- ctx->block_size = AES_BLOCK_SIZE;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL,
- ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1);
- }
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- if (ctx->cipherType == AES_192_ECB_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_ECB))) {
- WOLFSSL_MSG("EVP_AES_192_ECB");
- ctx->cipherType = AES_192_ECB_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_ECB_MODE;
- ctx->keyLen = 24;
- ctx->block_size = AES_BLOCK_SIZE;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL,
- ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1);
- }
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- if (ctx->cipherType == AES_256_ECB_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_ECB))) {
- WOLFSSL_MSG("EVP_AES_256_ECB");
- ctx->cipherType = AES_256_ECB_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_ECB_MODE;
- ctx->keyLen = 32;
- ctx->block_size = AES_BLOCK_SIZE;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL,
- ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1);
- }
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* HAVE_AES_ECB */
- #ifdef WOLFSSL_AES_CFB
- #ifdef WOLFSSL_AES_128
- if (ctx->cipherType == AES_128_CFB1_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_CFB1))) {
- WOLFSSL_MSG("EVP_AES_128_CFB1");
- ctx->cipherType = AES_128_CFB1_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE;
- ctx->keyLen = 16;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- if (ctx->cipherType == AES_192_CFB1_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_CFB1))) {
- WOLFSSL_MSG("EVP_AES_192_CFB1");
- ctx->cipherType = AES_192_CFB1_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE;
- ctx->keyLen = 24;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- if (ctx->cipherType == AES_256_CFB1_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_CFB1))) {
- WOLFSSL_MSG("EVP_AES_256_CFB1");
- ctx->cipherType = AES_256_CFB1_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE;
- ctx->keyLen = 32;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0){
- WOLFSSL_MSG("AesSetKey() failed");
- return WOLFSSL_FAILURE;
- }
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0){
- WOLFSSL_MSG("wc_AesSetIV() failed");
- return WOLFSSL_FAILURE;
- }
- }
- }
- #endif /* WOLFSSL_AES_256 */
- #ifdef WOLFSSL_AES_128
- if (ctx->cipherType == AES_128_CFB8_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_CFB8))) {
- WOLFSSL_MSG("EVP_AES_128_CFB8");
- ctx->cipherType = AES_128_CFB8_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE;
- ctx->keyLen = 16;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- if (ctx->cipherType == AES_192_CFB8_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_CFB8))) {
- WOLFSSL_MSG("EVP_AES_192_CFB8");
- ctx->cipherType = AES_192_CFB8_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE;
- ctx->keyLen = 24;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- if (ctx->cipherType == AES_256_CFB8_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_CFB8))) {
- WOLFSSL_MSG("EVP_AES_256_CFB8");
- ctx->cipherType = AES_256_CFB8_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE;
- ctx->keyLen = 32;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0){
- WOLFSSL_MSG("AesSetKey() failed");
- return WOLFSSL_FAILURE;
- }
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0){
- WOLFSSL_MSG("wc_AesSetIV() failed");
- return WOLFSSL_FAILURE;
- }
- }
- }
- #endif /* WOLFSSL_AES_256 */
- #ifdef WOLFSSL_AES_128
- if (ctx->cipherType == AES_128_CFB128_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_CFB128))) {
- WOLFSSL_MSG("EVP_AES_128_CFB128");
- ctx->cipherType = AES_128_CFB128_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE;
- ctx->keyLen = 16;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- if (ctx->cipherType == AES_192_CFB128_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_CFB128))) {
- WOLFSSL_MSG("EVP_AES_192_CFB128");
- ctx->cipherType = AES_192_CFB128_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE;
- ctx->keyLen = 24;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- if (ctx->cipherType == AES_256_CFB128_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_CFB128))) {
- WOLFSSL_MSG("EVP_AES_256_CFB128");
- ctx->cipherType = AES_256_CFB128_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE;
- ctx->keyLen = 32;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0){
- WOLFSSL_MSG("AesSetKey() failed");
- return WOLFSSL_FAILURE;
- }
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0){
- WOLFSSL_MSG("wc_AesSetIV() failed");
- return WOLFSSL_FAILURE;
- }
- }
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* WOLFSSL_AES_CFB */
- #ifdef WOLFSSL_AES_OFB
- #ifdef WOLFSSL_AES_128
- if (ctx->cipherType == AES_128_OFB_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_OFB))) {
- WOLFSSL_MSG("EVP_AES_128_OFB");
- ctx->cipherType = AES_128_OFB_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_OFB_MODE;
- ctx->keyLen = 16;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_192
- if (ctx->cipherType == AES_192_OFB_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_OFB))) {
- WOLFSSL_MSG("EVP_AES_192_OFB");
- ctx->cipherType = AES_192_OFB_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_OFB_MODE;
- ctx->keyLen = 24;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* WOLFSSL_AES_192 */
- #ifdef WOLFSSL_AES_256
- if (ctx->cipherType == AES_256_OFB_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_OFB))) {
- WOLFSSL_MSG("EVP_AES_256_OFB");
- ctx->cipherType = AES_256_OFB_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_OFB_MODE;
- ctx->keyLen = 32;
- ctx->block_size = 1;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
- AES_ENCRYPTION, 0);
- if (ret != 0){
- WOLFSSL_MSG("AesSetKey() failed");
- return WOLFSSL_FAILURE;
- }
- }
- if (iv && key == NULL) {
- ret = wc_AesSetIV(&ctx->cipher.aes, iv);
- if (ret != 0){
- WOLFSSL_MSG("wc_AesSetIV() failed");
- return WOLFSSL_FAILURE;
- }
- }
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* HAVE_AES_OFB */
- #ifdef WOLFSSL_AES_XTS
- #ifdef WOLFSSL_AES_128
- if (ctx->cipherType == AES_128_XTS_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_XTS))) {
- WOLFSSL_MSG("EVP_AES_128_XTS");
- ctx->cipherType = AES_128_XTS_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_XTS_MODE;
- ctx->keyLen = 32;
- ctx->block_size = 1;
- ctx->ivSz = AES_BLOCK_SIZE;
- if (iv != NULL) {
- if (iv != ctx->iv) /* Valgrind error when src == dst */
- XMEMCPY(ctx->iv, iv, ctx->ivSz);
- }
- else
- XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen,
- ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, NULL, 0);
- if (ret != 0) {
- WOLFSSL_MSG("wc_AesXtsSetKey() failed");
- return WOLFSSL_FAILURE;
- }
- }
- }
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_256
- if (ctx->cipherType == AES_256_XTS_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_XTS))) {
- WOLFSSL_MSG("EVP_AES_256_XTS");
- ctx->cipherType = AES_256_XTS_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_XTS_MODE;
- ctx->keyLen = 64;
- ctx->block_size = 1;
- ctx->ivSz = AES_BLOCK_SIZE;
- if (iv != NULL) {
- if (iv != ctx->iv) /* Valgrind error when src == dst */
- XMEMCPY(ctx->iv, iv, ctx->ivSz);
- }
- else
- XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen,
- ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, NULL, 0);
- if (ret != 0) {
- WOLFSSL_MSG("wc_AesXtsSetKey() failed");
- return WOLFSSL_FAILURE;
- }
- }
- }
- #endif /* WOLFSSL_AES_256 */
- #endif /* HAVE_AES_XTS */
- #endif /* NO_AES */
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- if (ctx->cipherType == CHACHA20_POLY1305_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_CHACHA20_POLY1305))) {
- WOLFSSL_MSG("EVP_CHACHA20_POLY1305");
- ctx->cipherType = CHACHA20_POLY1305_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
- ctx->keyLen = CHACHA20_POLY1305_AEAD_KEYSIZE;
- ctx->block_size = CHACHA_CHUNK_BYTES;
- ctx->authTagSz = CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE;
- ctx->ivSz = CHACHA20_POLY1305_AEAD_IV_SIZE;
- if (enc == 0 || enc == 1) {
- ctx->enc = (byte) enc;
- }
- if (key != NULL && iv != NULL && wc_ChaCha20Poly1305_Init(
- &ctx->cipher.chachaPoly, key, iv, enc) != 0) {
- WOLFSSL_MSG("wc_ChaCha20Poly1305_Init() failed");
- return WOLFSSL_FAILURE;
- }
- }
- #endif
- #ifndef NO_DES3
- if (ctx->cipherType == DES_CBC_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_DES_CBC))) {
- WOLFSSL_MSG("EVP_DES_CBC");
- ctx->cipherType = DES_CBC_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE;
- ctx->keyLen = 8;
- ctx->block_size = DES_BLOCK_SIZE;
- ctx->ivSz = DES_BLOCK_SIZE;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = wc_Des_SetKey(&ctx->cipher.des, key, iv,
- ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL)
- wc_Des_SetIV(&ctx->cipher.des, iv);
- }
- #ifdef WOLFSSL_DES_ECB
- else if (ctx->cipherType == DES_ECB_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_DES_ECB))) {
- WOLFSSL_MSG("EVP_DES_ECB");
- ctx->cipherType = DES_ECB_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_ECB_MODE;
- ctx->keyLen = 8;
- ctx->block_size = DES_BLOCK_SIZE;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- WOLFSSL_MSG("Des_SetKey");
- ret = wc_Des_SetKey(&ctx->cipher.des, key, NULL,
- ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif
- else if (ctx->cipherType == DES_EDE3_CBC_TYPE ||
- (type &&
- EVP_CIPHER_TYPE_MATCHES(type, EVP_DES_EDE3_CBC))) {
- WOLFSSL_MSG("EVP_DES_EDE3_CBC");
- ctx->cipherType = DES_EDE3_CBC_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE;
- ctx->keyLen = 24;
- ctx->block_size = DES_BLOCK_SIZE;
- ctx->ivSz = DES_BLOCK_SIZE;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = wc_Des3_SetKey(&ctx->cipher.des3, key, iv,
- ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- if (iv && key == NULL) {
- ret = wc_Des3_SetIV(&ctx->cipher.des3, iv);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- else if (ctx->cipherType == DES_EDE3_ECB_TYPE ||
- (type &&
- EVP_CIPHER_TYPE_MATCHES(type, EVP_DES_EDE3_ECB))) {
- WOLFSSL_MSG("EVP_DES_EDE3_ECB");
- ctx->cipherType = DES_EDE3_ECB_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_ECB_MODE;
- ctx->keyLen = 24;
- ctx->block_size = DES_BLOCK_SIZE;
- if (enc == 0 || enc == 1)
- ctx->enc = enc ? 1 : 0;
- if (key) {
- ret = wc_Des3_SetKey(&ctx->cipher.des3, key, NULL,
- ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
- if (ret != 0)
- return WOLFSSL_FAILURE;
- }
- }
- #endif /* NO_DES3 */
- #ifndef NO_RC4
- if (ctx->cipherType == ARC4_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_ARC4))) {
- WOLFSSL_MSG("ARC4");
- ctx->cipherType = ARC4_TYPE;
- ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
- ctx->flags |= WOLFSSL_EVP_CIPH_STREAM_CIPHER;
- ctx->block_size = 1;
- if (ctx->keyLen == 0) /* user may have already set */
- ctx->keyLen = 16; /* default to 128 */
- if (key)
- wc_Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen);
- }
- #endif /* NO_RC4 */
- if (ctx->cipherType == NULL_CIPHER_TYPE ||
- (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_NULL))) {
- WOLFSSL_MSG("NULL cipher");
- ctx->cipherType = NULL_CIPHER_TYPE;
- ctx->keyLen = 0;
- ctx->block_size = 16;
- }
- #ifdef HAVE_WOLFSSL_EVP_CIPHER_CTX_IV
- if (iv && iv != ctx->iv) {
- if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) {
- return WOLFSSL_FAILURE;
- }
- }
- #endif
- (void)ret; /* remove warning. If execution reaches this point, ret=0 */
- return WOLFSSL_SUCCESS;
- }
- /* WOLFSSL_SUCCESS on ok */
- int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_key_length");
- if (ctx)
- return ctx->keyLen;
- else
- return WOLFSSL_FAILURE;
- }
- /* WOLFSSL_SUCCESS on ok */
- int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx,
- int keylen)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_key_length");
- if (ctx)
- ctx->keyLen = keylen;
- else
- return WOLFSSL_FAILURE;
- return WOLFSSL_SUCCESS;
- }
- #ifdef HAVE_WOLFSSL_EVP_CIPHER_CTX_IV
- /* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE */
- int wolfSSL_EVP_CIPHER_CTX_set_iv_length(WOLFSSL_EVP_CIPHER_CTX* ctx,
- int ivLen)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_iv_length");
- if (ctx)
- ctx->ivSz= ivLen;
- else
- return WOLFSSL_FAILURE;
- return WOLFSSL_SUCCESS;
- }
- #endif
- #if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
- /* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE */
- int wolfSSL_EVP_CIPHER_CTX_set_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* iv,
- int ivLen)
- {
- int expectedIvLen;
- WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_iv");
- if (!ctx || !iv || !ivLen) {
- return WOLFSSL_FAILURE;
- }
- expectedIvLen = wolfSSL_EVP_CIPHER_CTX_iv_length(ctx);
- if (expectedIvLen == 0 || expectedIvLen != ivLen) {
- WOLFSSL_MSG("Wrong ivLen value");
- return WOLFSSL_FAILURE;
- }
- return wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, -1);
- }
- #endif
- #if !defined(NO_AES) || !defined(NO_DES3)
- /* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE */
- int wolfSSL_EVP_CIPHER_CTX_get_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* iv,
- int ivLen)
- {
- int expectedIvLen;
- WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_get_iv");
- if (ctx == NULL || iv == NULL || ivLen == 0) {
- WOLFSSL_MSG("Bad parameter");
- return WOLFSSL_FAILURE;
- }
- expectedIvLen = wolfSSL_EVP_CIPHER_CTX_iv_length(ctx);
- if (expectedIvLen == 0 || expectedIvLen != ivLen) {
- WOLFSSL_MSG("Wrong ivLen value");
- return WOLFSSL_FAILURE;
- }
- XMEMCPY(iv, ctx->iv, ivLen);
- return WOLFSSL_SUCCESS;
- }
- #endif /* !NO_AES || !NO_DES3 */
- /* Return length on ok */
- int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src,
- word32 len)
- {
- int ret = WOLFSSL_FAILURE;
- WOLFSSL_ENTER("wolfSSL_EVP_Cipher");
- if (ctx == NULL || ((src == NULL || dst == NULL) &&
- (ctx->cipherType != AES_128_GCM_TYPE &&
- ctx->cipherType != AES_192_GCM_TYPE &&
- ctx->cipherType != AES_256_GCM_TYPE))) {
- WOLFSSL_MSG("Bad argument.");
- return WOLFSSL_FATAL_ERROR;
- }
- if (ctx->cipherType == WOLFSSL_EVP_CIPH_TYPE_INIT) {
- WOLFSSL_MSG("Cipher operation not initialized. Call "
- "wolfSSL_EVP_CipherInit.");
- return WOLFSSL_FATAL_ERROR;
- }
- switch (ctx->cipherType) {
- #ifndef NO_AES
- #ifdef HAVE_AES_CBC
- case AES_128_CBC_TYPE :
- case AES_192_CBC_TYPE :
- case AES_256_CBC_TYPE :
- WOLFSSL_MSG("AES CBC");
- if (ctx->enc)
- ret = wc_AesCbcEncrypt(&ctx->cipher.aes, dst, src, len);
- else
- ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len);
- if (ret == 0)
- ret = (len / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
- break;
- #endif /* HAVE_AES_CBC */
- #ifdef WOLFSSL_AES_CFB
- #if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
- case AES_128_CFB1_TYPE:
- case AES_192_CFB1_TYPE:
- case AES_256_CFB1_TYPE:
- WOLFSSL_MSG("AES CFB1");
- if (ctx->enc)
- ret = wc_AesCfb1Encrypt(&ctx->cipher.aes, dst, src, len);
- else
- ret = wc_AesCfb1Decrypt(&ctx->cipher.aes, dst, src, len);
- if (ret == 0)
- ret = len;
- break;
- case AES_128_CFB8_TYPE:
- case AES_192_CFB8_TYPE:
- case AES_256_CFB8_TYPE:
- WOLFSSL_MSG("AES CFB8");
- if (ctx->enc)
- ret = wc_AesCfb8Encrypt(&ctx->cipher.aes, dst, src, len);
- else
- ret = wc_AesCfb8Decrypt(&ctx->cipher.aes, dst, src, len);
- if (ret == 0)
- ret = len;
- break;
- #endif /* !HAVE_SELFTEST && !HAVE_FIPS */
- case AES_128_CFB128_TYPE:
- case AES_192_CFB128_TYPE:
- case AES_256_CFB128_TYPE:
- WOLFSSL_MSG("AES CFB128");
- if (ctx->enc)
- ret = wc_AesCfbEncrypt(&ctx->cipher.aes, dst, src, len);
- else
- ret = wc_AesCfbDecrypt(&ctx->cipher.aes, dst, src, len);
- if (ret == 0)
- ret = len;
- break;
- #endif /* WOLFSSL_AES_CFB */
- #if defined(WOLFSSL_AES_OFB)
- case AES_128_OFB_TYPE:
- case AES_192_OFB_TYPE:
- case AES_256_OFB_TYPE:
- WOLFSSL_MSG("AES OFB");
- if (ctx->enc)
- ret = wc_AesOfbEncrypt(&ctx->cipher.aes, dst, src, len);
- else
- ret = wc_AesOfbDecrypt(&ctx->cipher.aes, dst, src, len);
- if (ret == 0)
- ret = len;
- break;
- #endif /* WOLFSSL_AES_OFB */
- #if defined(WOLFSSL_AES_XTS)
- case AES_128_XTS_TYPE:
- case AES_256_XTS_TYPE:
- WOLFSSL_MSG("AES XTS");
- if (ctx->enc)
- ret = wc_AesXtsEncrypt(&ctx->cipher.xts, dst, src, len,
- ctx->iv, ctx->ivSz);
- else
- ret = wc_AesXtsDecrypt(&ctx->cipher.xts, dst, src, len,
- ctx->iv, ctx->ivSz);
- if (ret == 0)
- ret = len;
- break;
- #endif /* WOLFSSL_AES_XTS */
- #if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
- || FIPS_VERSION_GE(2,0))
- case AES_128_GCM_TYPE :
- case AES_192_GCM_TYPE :
- case AES_256_GCM_TYPE :
- WOLFSSL_MSG("AES GCM");
- ret = EvpCipherAesGCM(ctx, dst, src, len);
- break;
- #endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
- * HAVE_FIPS_VERSION >= 2 */
- #ifdef HAVE_AES_ECB
- case AES_128_ECB_TYPE :
- case AES_192_ECB_TYPE :
- case AES_256_ECB_TYPE :
- WOLFSSL_MSG("AES ECB");
- if (ctx->enc)
- ret = wc_AesEcbEncrypt(&ctx->cipher.aes, dst, src, len);
- else
- ret = wc_AesEcbDecrypt(&ctx->cipher.aes, dst, src, len);
- if (ret == 0)
- ret = (len / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
- break;
- #endif
- #ifdef WOLFSSL_AES_COUNTER
- case AES_128_CTR_TYPE :
- case AES_192_CTR_TYPE :
- case AES_256_CTR_TYPE :
- WOLFSSL_MSG("AES CTR");
- ret = wc_AesCtrEncrypt(&ctx->cipher.aes, dst, src, len);
- if (ret == 0)
- ret = len;
- break;
- #endif /* WOLFSSL_AES_COUNTER */
- #endif /* NO_AES */
- #ifndef NO_DES3
- case DES_CBC_TYPE :
- WOLFSSL_MSG("DES CBC");
- if (ctx->enc)
- wc_Des_CbcEncrypt(&ctx->cipher.des, dst, src, len);
- else
- wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len);
- if (ret == 0)
- ret = (len / DES_BLOCK_SIZE) * DES_BLOCK_SIZE;
- break;
- case DES_EDE3_CBC_TYPE :
- WOLFSSL_MSG("DES3 CBC");
- if (ctx->enc)
- ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len);
- else
- ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len);
- if (ret == 0)
- ret = (len / DES_BLOCK_SIZE) * DES_BLOCK_SIZE;
- break;
- #ifdef WOLFSSL_DES_ECB
- case DES_ECB_TYPE :
- WOLFSSL_MSG("DES ECB");
- ret = wc_Des_EcbEncrypt(&ctx->cipher.des, dst, src, len);
- if (ret == 0)
- ret = (len / DES_BLOCK_SIZE) * DES_BLOCK_SIZE;
- break;
- case DES_EDE3_ECB_TYPE :
- WOLFSSL_MSG("DES3 ECB");
- ret = wc_Des3_EcbEncrypt(&ctx->cipher.des3, dst, src, len);
- if (ret == 0)
- ret = (len / DES_BLOCK_SIZE) * DES_BLOCK_SIZE;
- break;
- #endif
- #endif /* !NO_DES3 */
- #ifndef NO_RC4
- case ARC4_TYPE :
- WOLFSSL_MSG("ARC4");
- wc_Arc4Process(&ctx->cipher.arc4, dst, src, len);
- if (ret == 0)
- ret = len;
- break;
- #endif
- case NULL_CIPHER_TYPE :
- WOLFSSL_MSG("NULL CIPHER");
- XMEMCPY(dst, src, len);
- ret = len;
- break;
- default: {
- WOLFSSL_MSG("bad type");
- return WOLFSSL_FATAL_ERROR;
- }
- }
- if (ret < 0) {
- if (ret == AES_GCM_AUTH_E) {
- WOLFSSL_MSG("wolfSSL_EVP_Cipher failure: bad AES-GCM tag.");
- }
- WOLFSSL_MSG("wolfSSL_EVP_Cipher failure");
- return WOLFSSL_FATAL_ERROR;
- }
- if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) {
- return WOLFSSL_FATAL_ERROR;
- }
- WOLFSSL_MSG("wolfSSL_EVP_Cipher success");
- return ret;
- }
- /* WOLFSSL_SUCCESS on ok */
- int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx,
- const WOLFSSL_EVP_MD* md)
- {
- int ret = WOLFSSL_SUCCESS;
- WOLFSSL_ENTER("EVP_DigestInit");
- if (ctx == NULL) {
- return BAD_FUNC_ARG;
- }
- #ifdef WOLFSSL_ASYNC_CRYPT
- /* compile-time validation of ASYNC_CTX_SIZE */
- typedef char async_test[WC_ASYNC_DEV_SIZE >= sizeof(WC_ASYNC_DEV) ?
- 1 : -1];
- (void)sizeof(async_test);
- #endif
- /* Set to 0 if no match */
- ctx->macType = EvpMd2MacType(md);
- if (md == NULL) {
- XMEMSET(&ctx->hash.digest, 0, sizeof(WOLFSSL_Hasher));
- } else
- #ifndef NO_SHA
- if ((XSTRCMP(md, "SHA") == 0) || (XSTRCMP(md, "SHA1") == 0)) {
- ret = wolfSSL_SHA_Init(&(ctx->hash.digest.sha));
- } else
- #endif
- #ifndef NO_SHA256
- if (XSTRCMP(md, "SHA256") == 0) {
- ret = wolfSSL_SHA256_Init(&(ctx->hash.digest.sha256));
- } else
- #endif
- #ifdef WOLFSSL_SHA224
- if (XSTRCMP(md, "SHA224") == 0) {
- ret = wolfSSL_SHA224_Init(&(ctx->hash.digest.sha224));
- } else
- #endif
- #ifdef WOLFSSL_SHA384
- if (XSTRCMP(md, "SHA384") == 0) {
- ret = wolfSSL_SHA384_Init(&(ctx->hash.digest.sha384));
- } else
- #endif
- #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
- defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224)
- if (XSTRCMP(md, "SHA512_224") == 0) {
- ret = wolfSSL_SHA512_224_Init(&(ctx->hash.digest.sha512));
- } else
- #endif
- #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
- defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256)
- if (XSTRCMP(md, "SHA512_256") == 0) {
- ret = wolfSSL_SHA512_256_Init(&(ctx->hash.digest.sha512));
- } else
- #endif
- #ifdef WOLFSSL_SHA512
- if (XSTRCMP(md, "SHA512") == 0) {
- ret = wolfSSL_SHA512_Init(&(ctx->hash.digest.sha512));
- } else
- #endif
- #ifndef NO_MD4
- if (XSTRCMP(md, "MD4") == 0) {
- wolfSSL_MD4_Init(&(ctx->hash.digest.md4));
- } else
- #endif
- #ifndef NO_MD5
- if (XSTRCMP(md, "MD5") == 0) {
- ret = wolfSSL_MD5_Init(&(ctx->hash.digest.md5));
- } else
- #endif
- #ifdef WOLFSSL_SHA3
- #ifndef WOLFSSL_NOSHA3_224
- if (XSTRCMP(md, "SHA3_224") == 0) {
- ret = wolfSSL_SHA3_224_Init(&(ctx->hash.digest.sha3_224));
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_256
- if (XSTRCMP(md, "SHA3_256") == 0) {
- ret = wolfSSL_SHA3_256_Init(&(ctx->hash.digest.sha3_256));
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_384
- if (XSTRCMP(md, "SHA3_384") == 0) {
- ret = wolfSSL_SHA3_384_Init(&(ctx->hash.digest.sha3_384));
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_512
- if (XSTRCMP(md, "SHA3_512") == 0) {
- ret = wolfSSL_SHA3_512_Init(&(ctx->hash.digest.sha3_512));
- } else
- #endif
- #endif
- {
- ctx->macType = WC_HASH_TYPE_NONE;
- return BAD_FUNC_ARG;
- }
- return ret;
- }
- /* WOLFSSL_SUCCESS on ok, WOLFSSL_FAILURE on failure */
- int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data,
- size_t sz)
- {
- int ret = WOLFSSL_FAILURE;
- enum wc_HashType macType;
- WOLFSSL_ENTER("EVP_DigestUpdate");
- macType = EvpMd2MacType(EVP_MD_CTX_md(ctx));
- switch (macType) {
- case WC_HASH_TYPE_MD4:
- #ifndef NO_MD4
- wolfSSL_MD4_Update((MD4_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- ret = WOLFSSL_SUCCESS;
- #endif
- break;
- case WC_HASH_TYPE_MD5:
- #ifndef NO_MD5
- ret = wolfSSL_MD5_Update((MD5_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif
- break;
- case WC_HASH_TYPE_SHA:
- #ifndef NO_SHA
- ret = wolfSSL_SHA_Update((SHA_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif
- break;
- case WC_HASH_TYPE_SHA224:
- #ifdef WOLFSSL_SHA224
- ret = wolfSSL_SHA224_Update((SHA224_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif
- break;
- case WC_HASH_TYPE_SHA256:
- #ifndef NO_SHA256
- ret = wolfSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif /* !NO_SHA256 */
- break;
- case WC_HASH_TYPE_SHA384:
- #ifdef WOLFSSL_SHA384
- ret = wolfSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif
- break;
- case WC_HASH_TYPE_SHA512:
- #ifdef WOLFSSL_SHA512
- ret = wolfSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif /* WOLFSSL_SHA512 */
- break;
- #ifndef WOLFSSL_NOSHA512_224
- case WC_HASH_TYPE_SHA512_224:
- #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
- defined(WOLFSSL_SHA512)
- ret = wolfSSL_SHA512_224_Update((SHA512_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif
- break;
- #endif /* !WOLFSSL_NOSHA512_224 */
- #ifndef WOLFSSL_NOSHA512_256
- case WC_HASH_TYPE_SHA512_256:
- #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
- defined(WOLFSSL_SHA512)
- ret = wolfSSL_SHA512_256_Update((SHA512_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif /* WOLFSSL_SHA512 */
- break;
- #endif /* !WOLFSSL_NOSHA512_256 */
- case WC_HASH_TYPE_SHA3_224:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
- ret = wolfSSL_SHA3_224_Update((SHA3_224_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif
- break;
- case WC_HASH_TYPE_SHA3_256:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
- ret = wolfSSL_SHA3_256_Update((SHA3_256_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif
- break;
- case WC_HASH_TYPE_SHA3_384:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
- ret = wolfSSL_SHA3_384_Update((SHA3_384_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif
- break;
- case WC_HASH_TYPE_SHA3_512:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
- ret = wolfSSL_SHA3_512_Update((SHA3_512_CTX*)&ctx->hash, data,
- (unsigned long)sz);
- #endif
- break;
- case WC_HASH_TYPE_NONE:
- case WC_HASH_TYPE_MD2:
- case WC_HASH_TYPE_MD5_SHA:
- case WC_HASH_TYPE_BLAKE2B:
- case WC_HASH_TYPE_BLAKE2S:
- #ifndef WOLFSSL_NO_SHAKE256
- case WC_HASH_TYPE_SHAKE128:
- case WC_HASH_TYPE_SHAKE256:
- #endif
- default:
- return WOLFSSL_FAILURE;
- }
- return ret;
- }
- /* WOLFSSL_SUCCESS on ok */
- int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
- unsigned int* s)
- {
- int ret = WOLFSSL_FAILURE;
- enum wc_HashType macType;
- WOLFSSL_ENTER("EVP_DigestFinal");
- macType = EvpMd2MacType(EVP_MD_CTX_md(ctx));
- switch (macType) {
- case WC_HASH_TYPE_MD4:
- #ifndef NO_MD4
- wolfSSL_MD4_Final(md, (MD4_CTX*)&ctx->hash);
- if (s) *s = MD4_DIGEST_SIZE;
- ret = WOLFSSL_SUCCESS;
- #endif
- break;
- case WC_HASH_TYPE_MD5:
- #ifndef NO_MD5
- ret = wolfSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash);
- if (s) *s = WC_MD5_DIGEST_SIZE;
- #endif
- break;
- case WC_HASH_TYPE_SHA:
- #ifndef NO_SHA
- ret = wolfSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash);
- if (s) *s = WC_SHA_DIGEST_SIZE;
- #endif
- break;
- case WC_HASH_TYPE_SHA224:
- #ifdef WOLFSSL_SHA224
- ret = wolfSSL_SHA224_Final(md, (SHA224_CTX*)&ctx->hash);
- if (s) *s = WC_SHA224_DIGEST_SIZE;
- #endif
- break;
- case WC_HASH_TYPE_SHA256:
- #ifndef NO_SHA256
- ret = wolfSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash);
- if (s) *s = WC_SHA256_DIGEST_SIZE;
- #endif /* !NO_SHA256 */
- break;
- case WC_HASH_TYPE_SHA384:
- #ifdef WOLFSSL_SHA384
- ret = wolfSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash);
- if (s) *s = WC_SHA384_DIGEST_SIZE;
- #endif
- break;
- case WC_HASH_TYPE_SHA512:
- #ifdef WOLFSSL_SHA512
- ret = wolfSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash);
- if (s) *s = WC_SHA512_DIGEST_SIZE;
- #endif /* WOLFSSL_SHA512 */
- break;
- #ifndef WOLFSSL_NOSHA512_224
- case WC_HASH_TYPE_SHA512_224:
- #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
- defined(WOLFSSL_SHA512)
- ret = wolfSSL_SHA512_224_Final(md, (SHA512_CTX*)&ctx->hash);
- if (s) *s = WC_SHA512_224_DIGEST_SIZE;
- #endif
- break;
- #endif /* !WOLFSSL_NOSHA512_224 */
- #ifndef WOLFSSL_NOSHA512_256
- case WC_HASH_TYPE_SHA512_256:
- #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
- defined(WOLFSSL_SHA512)
- ret = wolfSSL_SHA512_256_Final(md, (SHA512_CTX*)&ctx->hash);
- if (s) *s = WC_SHA512_256_DIGEST_SIZE;
- #endif
- break;
- #endif /* !WOLFSSL_NOSHA512_256 */
- case WC_HASH_TYPE_SHA3_224:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
- ret = wolfSSL_SHA3_224_Final(md, (SHA3_224_CTX*)&ctx->hash);
- if (s) *s = WC_SHA3_224_DIGEST_SIZE;
- #endif
- break;
- case WC_HASH_TYPE_SHA3_256:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
- ret = wolfSSL_SHA3_256_Final(md, (SHA3_256_CTX*)&ctx->hash);
- if (s) *s = WC_SHA3_256_DIGEST_SIZE;
- #endif
- break;
- case WC_HASH_TYPE_SHA3_384:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
- ret = wolfSSL_SHA3_384_Final(md, (SHA3_384_CTX*)&ctx->hash);
- if (s) *s = WC_SHA3_384_DIGEST_SIZE;
- #endif
- break;
- case WC_HASH_TYPE_SHA3_512:
- #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
- ret = wolfSSL_SHA3_512_Final(md, (SHA3_512_CTX*)&ctx->hash);
- if (s) *s = WC_SHA3_512_DIGEST_SIZE;
- #endif
- break;
- case WC_HASH_TYPE_NONE:
- case WC_HASH_TYPE_MD2:
- case WC_HASH_TYPE_MD5_SHA:
- case WC_HASH_TYPE_BLAKE2B:
- case WC_HASH_TYPE_BLAKE2S:
- #ifndef WOLFSSL_NO_SHAKE256
- case WC_HASH_TYPE_SHAKE128:
- case WC_HASH_TYPE_SHAKE256:
- #endif
- default:
- return WOLFSSL_FAILURE;
- }
- return ret;
- }
- /* WOLFSSL_SUCCESS on ok */
- int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
- unsigned int* s)
- {
- WOLFSSL_ENTER("EVP_DigestFinal_ex");
- return EVP_DigestFinal(ctx, md, s);
- }
- void wolfSSL_EVP_cleanup(void)
- {
- /* nothing to do here */
- }
- const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id)
- {
- WOLFSSL_MSG("wolfSSL_get_digestbynid");
- switch(id) {
- #ifndef NO_MD5
- case NID_md5:
- return wolfSSL_EVP_md5();
- #endif
- #ifndef NO_SHA
- case NID_sha1:
- return wolfSSL_EVP_sha1();
- #endif
- #ifdef WOLFSSL_SHA224
- case NID_sha224:
- return wolfSSL_EVP_sha224();
- #endif
- #ifndef NO_SHA256
- case NID_sha256:
- return wolfSSL_EVP_sha256();
- #endif
- #ifdef WOLFSSL_SHA384
- case NID_sha384:
- return wolfSSL_EVP_sha384();
- #endif
- #ifdef WOLFSSL_SHA512
- case NID_sha512:
- return wolfSSL_EVP_sha512();
- #endif
- default:
- WOLFSSL_MSG("Bad digest id value");
- }
- return NULL;
- }
- static void clearEVPPkeyKeys(WOLFSSL_EVP_PKEY *pkey)
- {
- if(pkey == NULL)
- return;
- WOLFSSL_ENTER("clearEVPPkeyKeys");
- #ifndef NO_RSA
- if (pkey->rsa != NULL && pkey->ownRsa == 1) {
- wolfSSL_RSA_free(pkey->rsa);
- pkey->rsa = NULL;
- }
- pkey->ownRsa = 0;
- #endif
- #ifndef NO_DSA
- if (pkey->dsa != NULL && pkey->ownDsa == 1) {
- wolfSSL_DSA_free(pkey->dsa);
- pkey->dsa = NULL;
- }
- pkey->ownDsa = 0;
- #endif
- #ifndef NO_DH
- if (pkey->dh != NULL && pkey->ownDh == 1) {
- wolfSSL_DH_free(pkey->dh);
- pkey->dh = NULL;
- }
- pkey->ownDh = 0;
- #endif
- #ifdef HAVE_ECC
- if (pkey->ecc != NULL && pkey->ownEcc == 1) {
- wolfSSL_EC_KEY_free(pkey->ecc);
- pkey->ecc = NULL;
- }
- pkey->ownEcc = 0;
- #endif
- }
- #ifndef NO_RSA
- #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)
- static int PopulateRSAEvpPkeyDer(WOLFSSL_EVP_PKEY *pkey)
- {
- int ret = 0;
- int derSz = 0;
- word32 pkcs8Sz = 0;
- byte* derBuf = NULL;
- RsaKey* rsa = NULL;
- WOLFSSL_RSA *key = NULL;
- if (pkey == NULL || pkey->rsa == NULL || pkey->rsa->internal == NULL) {
- WOLFSSL_MSG("bad parameter");
- return WOLFSSL_FAILURE;
- }
- key = pkey->rsa;
- rsa = (RsaKey*)pkey->rsa->internal;
- /* Get DER size */
- if (rsa->type == RSA_PRIVATE) {
- ret = wc_RsaKeyToDer(rsa, NULL, 0);
- if (ret > 0) {
- derSz = ret;
- #ifdef HAVE_PKCS8
- if (key->pkcs8HeaderSz) {
- ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, NULL, derSz,
- RSAk, NULL, 0);
- if (ret == LENGTH_ONLY_E)
- ret = 0;
- }
- #endif
- }
- }
- else {
- ret = wc_RsaKeyToPublicDer(rsa, NULL, 0);
- if (ret > 0)
- derSz = ret;
- }
- if (derSz == 0 || ret < 0) {
- WOLFSSL_MSG("Error getting RSA DER size");
- return WOLFSSL_FAILURE;
- }
- derBuf = (byte*)XREALLOC(pkey->pkey.ptr, derSz,
- pkey->heap, DYNAMIC_TYPE_DER);
- if (derBuf == NULL) {
- WOLFSSL_MSG("PopulateRSAEvpPkeyDer malloc failed");
- return WOLFSSL_FAILURE;
- }
- /* Old pointer is invalid from this point on */
- pkey->pkey.ptr = (char*)derBuf;
- if (rsa->type == RSA_PRIVATE) {
- ret = wc_RsaKeyToDer(rsa, derBuf, derSz);
- if (ret > 0) {
- derSz = ret;
- #ifdef HAVE_PKCS8
- if (key->pkcs8HeaderSz) {
- byte* keyBuf = derBuf;
- int keySz = derSz;
- derSz = pkcs8Sz;
- /* Need new buffer for PKCS8 since we can't
- * do this in-place */
- derBuf = (byte*)XMALLOC(pkcs8Sz, pkey->heap,
- DYNAMIC_TYPE_DER);
- if (derBuf != NULL) {
- ret = wc_CreatePKCS8Key(derBuf, (word32*)&derSz, keyBuf,
- keySz, RSAk, NULL, 0);
- XFREE(keyBuf, pkey->heap, DYNAMIC_TYPE_DER);
- pkey->pkey.ptr = (char*)derBuf;
- }
- else
- ret = MEMORY_E;
- }
- #endif
- }
- }
- else {
- /* Public key to DER */
- ret = wc_RsaKeyToPublicDer(rsa, derBuf, derSz);
- if (ret > 0)
- derSz = ret;
- }
- if (ret < 0) {
- WOLFSSL_MSG("PopulateRSAEvpPkeyDer failed");
- return WOLFSSL_FAILURE;
- }
- else {
- pkey->pkey_sz = derSz;
- return WOLFSSL_SUCCESS;
- }
- }
- #endif
- WOLFSSL_RSA* wolfSSL_EVP_PKEY_get0_RSA(WOLFSSL_EVP_PKEY *pkey)
- {
- WOLFSSL_MSG("wolfSSL_EVP_PKEY_get0_RSA");
- if (pkey == NULL)
- return NULL;
- return pkey->rsa;
- }
- WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* pkey)
- {
- WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_RSA");
- if (pkey == NULL || pkey->rsa == NULL)
- return NULL;
- if (wolfSSL_RSA_up_ref(pkey->rsa) != WOLFSSL_SUCCESS)
- return NULL;
- return pkey->rsa;
- }
- /* with set1 functions the pkey struct does not own the RSA structure
- *
- * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
- */
- int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_RSA");
- if (pkey == NULL || key == NULL)
- return WOLFSSL_FAILURE;
- if (wolfSSL_RSA_up_ref(key) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("wolfSSL_RSA_up_ref failed");
- return WOLFSSL_FAILURE;
- }
- clearEVPPkeyKeys(pkey);
- pkey->rsa = key;
- pkey->ownRsa = 1; /* pkey does not own RSA but needs to call free on it */
- pkey->type = EVP_PKEY_RSA;
- pkey->pkcs8HeaderSz = key->pkcs8HeaderSz;
- if (key->inSet == 0) {
- if (SetRsaInternal(key) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("SetRsaInternal failed");
- return WOLFSSL_FAILURE;
- }
- }
- #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)
- if (PopulateRSAEvpPkeyDer(pkey) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("PopulateRSAEvpPkeyDer failed");
- return WOLFSSL_FAILURE;
- }
- #endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */
- #ifdef WC_RSA_BLINDING
- if (key->ownRng == 0) {
- if (wc_RsaSetRNG((RsaKey*)pkey->rsa->internal, &pkey->rng) != 0) {
- WOLFSSL_MSG("Error setting RSA rng");
- return WOLFSSL_FAILURE;
- }
- }
- #endif
- return WOLFSSL_SUCCESS;
- }
- #endif /* !NO_RSA */
- #if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
- /* with set1 functions the pkey struct does not own the DSA structure
- *
- * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
- */
- int wolfSSL_EVP_PKEY_set1_DSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DSA *key)
- {
- int derMax = 0;
- int derSz = 0;
- DsaKey* dsa = NULL;
- byte* derBuf = NULL;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_DSA");
- if((pkey == NULL) || (key == NULL))return WOLFSSL_FAILURE;
- clearEVPPkeyKeys(pkey);
- pkey->dsa = key;
- pkey->ownDsa = 0; /* pkey does not own DSA */
- pkey->type = EVP_PKEY_DSA;
- if (key->inSet == 0) {
- if (SetDsaInternal(key) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("SetDsaInternal failed");
- return WOLFSSL_FAILURE;
- }
- }
- dsa = (DsaKey*)key->internal;
- /* 4 > size of pub, priv, p, q, g + ASN.1 additional information */
- derMax = 4 * wolfSSL_BN_num_bytes(key->g) + AES_BLOCK_SIZE;
- derBuf = (byte*)XMALLOC(derMax, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
- if (derBuf == NULL) {
- WOLFSSL_MSG("malloc failed");
- return WOLFSSL_FAILURE;
- }
- if (dsa->type == DSA_PRIVATE) {
- /* Private key to DER */
- derSz = wc_DsaKeyToDer(dsa, derBuf, derMax);
- }
- else {
- /* Public key to DER */
- derSz = wc_DsaKeyToPublicDer(dsa, derBuf, derMax);
- }
- if (derSz < 0) {
- if (dsa->type == DSA_PRIVATE) {
- WOLFSSL_MSG("wc_DsaKeyToDer failed");
- }
- else {
- WOLFSSL_MSG("wc_DsaKeyToPublicDer failed");
- }
- XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
- return WOLFSSL_FAILURE;
- }
- pkey->pkey.ptr = (char*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_DER);
- if (pkey->pkey.ptr == NULL) {
- WOLFSSL_MSG("key malloc failed");
- XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
- return WOLFSSL_FAILURE;
- }
- pkey->pkey_sz = derSz;
- XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
- XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
- return WOLFSSL_SUCCESS;
- }
- WOLFSSL_DSA* wolfSSL_EVP_PKEY_get0_DSA(struct WOLFSSL_EVP_PKEY *pkey)
- {
- if (!pkey) {
- return NULL;
- }
- return pkey->dsa;
- }
- WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key)
- {
- WOLFSSL_DSA* local;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_get1_DSA");
- if (key == NULL) {
- WOLFSSL_MSG("Bad function argument");
- return NULL;
- }
- local = wolfSSL_DSA_new();
- if (local == NULL) {
- WOLFSSL_MSG("Error creating a new WOLFSSL_DSA structure");
- return NULL;
- }
- if (key->type == EVP_PKEY_DSA) {
- if (wolfSSL_DSA_LoadDer(local, (const unsigned char*)key->pkey.ptr,
- key->pkey_sz) != SSL_SUCCESS) {
- /* now try public key */
- if (wolfSSL_DSA_LoadDer_ex(local,
- (const unsigned char*)key->pkey.ptr, key->pkey_sz,
- WOLFSSL_DSA_LOAD_PUBLIC) != SSL_SUCCESS) {
- wolfSSL_DSA_free(local);
- local = NULL;
- }
- }
- }
- else {
- WOLFSSL_MSG("WOLFSSL_EVP_PKEY does not hold a DSA key");
- wolfSSL_DSA_free(local);
- local = NULL;
- }
- return local;
- }
- #endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */
- #ifdef HAVE_ECC
- WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get0_EC_KEY(WOLFSSL_EVP_PKEY *pkey)
- {
- WOLFSSL_EC_KEY *eckey = NULL;
- if (pkey && pkey->type == EVP_PKEY_EC) {
- #ifdef HAVE_ECC
- eckey = pkey->ecc;
- #endif
- }
- return eckey;
- }
- WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key)
- {
- WOLFSSL_EC_KEY* local = NULL;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_get1_EC_KEY");
- if (key == NULL || key->type != EVP_PKEY_EC) {
- return NULL;
- }
- if (key->type == EVP_PKEY_EC) {
- if (key->ecc != NULL) {
- if (wolfSSL_EC_KEY_up_ref(key->ecc) != WOLFSSL_SUCCESS) {
- return NULL;
- }
- local = key->ecc;
- }
- else {
- key->ecc = local = wolfSSL_EC_KEY_new();
- if (local == NULL) {
- WOLFSSL_MSG("Error creating a new WOLFSSL_EC_KEY structure");
- return NULL;
- }
- if (wolfSSL_EC_KEY_LoadDer(local,
- (const unsigned char*)key->pkey.ptr,
- key->pkey_sz) != WOLFSSL_SUCCESS) {
- /* now try public key */
- if (wolfSSL_EC_KEY_LoadDer_ex(local,
- (const unsigned char*)key->pkey.ptr, key->pkey_sz,
- WOLFSSL_EC_KEY_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
- wolfSSL_EC_KEY_free(local);
- local = NULL;
- }
- }
- }
- }
- else {
- WOLFSSL_MSG("WOLFSSL_EVP_PKEY does not hold an EC key");
- }
- return local;
- }
- #endif /* HAVE_ECC */
- #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_OPENSSH)
- #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
- /* with set1 functions the pkey struct does not own the DH structure
- * Build the following DH Key format from the passed in WOLFSSL_DH
- * then store in WOLFSSL_EVP_PKEY in DER format.
- *
- * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
- */
- int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key)
- {
- byte havePublic = 0, havePrivate = 0;
- int ret;
- word32 derSz = 0;
- byte* derBuf = NULL;
- DhKey* dhkey = NULL;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_DH");
- if (pkey == NULL || key == NULL)
- return WOLFSSL_FAILURE;
- clearEVPPkeyKeys(pkey);
- if (wolfSSL_DH_up_ref(key) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("Failed to increase dh key ref count");
- return WOLFSSL_FAILURE;
- }
- pkey->dh = key;
- pkey->ownDh = 1; /* pkey does not own DH but needs to call free on it */
- pkey->type = EVP_PKEY_DH;
- if (key->inSet == 0) {
- if (SetDhInternal(key) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("SetDhInternal failed");
- return WOLFSSL_FAILURE;
- }
- }
- dhkey = (DhKey*)key->internal;
- havePublic = mp_unsigned_bin_size(&dhkey->pub) > 0;
- havePrivate = mp_unsigned_bin_size(&dhkey->priv) > 0;
- /* Get size of DER buffer only */
- if (havePublic && !havePrivate) {
- ret = wc_DhPubKeyToDer(dhkey, NULL, &derSz);
- } else if (havePrivate && !havePublic) {
- ret = wc_DhPrivKeyToDer(dhkey, NULL, &derSz);
- } else {
- ret = wc_DhParamsToDer(dhkey,NULL,&derSz);
- }
- if (derSz == 0 || ret != LENGTH_ONLY_E) {
- WOLFSSL_MSG("Failed to get size of DH Key");
- return WOLFSSL_FAILURE;
- }
- derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
- if (derBuf == NULL) {
- WOLFSSL_MSG("malloc failed");
- return WOLFSSL_FAILURE;
- }
- /* Fill DER buffer */
- if (havePublic && !havePrivate) {
- ret = wc_DhPubKeyToDer(dhkey, derBuf, &derSz);
- } else if (havePrivate && !havePublic) {
- ret = wc_DhPrivKeyToDer(dhkey, derBuf, &derSz);
- } else {
- ret = wc_DhParamsToDer(dhkey,derBuf,&derSz);
- }
- if (ret <= 0) {
- WOLFSSL_MSG("Failed to export DH Key");
- XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
- return WOLFSSL_FAILURE;
- }
- /* Store DH key into pkey (DER format) */
- pkey->pkey.ptr = (char*)derBuf;
- pkey->pkey_sz = derSz;
- return WOLFSSL_SUCCESS;
- }
- WOLFSSL_DH* wolfSSL_EVP_PKEY_get0_DH(WOLFSSL_EVP_PKEY* key)
- {
- if (!key) {
- return NULL;
- }
- return key->dh;
- }
- WOLFSSL_DH* wolfSSL_EVP_PKEY_get1_DH(WOLFSSL_EVP_PKEY* key)
- {
- WOLFSSL_DH* local = NULL;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_get1_DH");
- if (key == NULL || key->dh == NULL) {
- WOLFSSL_MSG("Bad function argument");
- return NULL;
- }
- if (key->type == EVP_PKEY_DH) {
- /* if key->dh already exists copy instead of re-importing from DER */
- if (key->dh != NULL) {
- if (wolfSSL_DH_up_ref(key->dh) != WOLFSSL_SUCCESS) {
- return NULL;
- }
- local = key->dh;
- }
- else {
- #if !defined(NO_DH) && (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
- (HAVE_FIPS_VERSION>2)))
- local = wolfSSL_DH_new();
- if (local == NULL) {
- WOLFSSL_MSG("Error creating a new WOLFSSL_DH structure");
- return NULL;
- }
- if (wolfSSL_DH_LoadDer(local, (const unsigned char*)key->pkey.ptr,
- key->pkey_sz) != SSL_SUCCESS) {
- wolfSSL_DH_free(local);
- WOLFSSL_MSG("Error wolfSSL_DH_LoadDer");
- local = NULL;
- }
- #else
- WOLFSSL_MSG("EVP_PKEY does not hold DH struct");
- return NULL;
- #endif
- }
- }
- else {
- WOLFSSL_MSG("WOLFSSL_EVP_PKEY does not hold a DH key");
- wolfSSL_DH_free(local);
- return NULL;
- }
- return local;
- }
- #endif /* NO_DH && WOLFSSL_DH_EXTRA && NO_FILESYSTEM */
- int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key)
- {
- int ret;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_assign");
- /* pkey and key checked if NULL in subsequent assign functions */
- switch(type) {
- #ifndef NO_RSA
- case EVP_PKEY_RSA:
- ret = wolfSSL_EVP_PKEY_assign_RSA(pkey, (WOLFSSL_RSA*)key);
- break;
- #endif
- #ifndef NO_DSA
- case EVP_PKEY_DSA:
- ret = wolfSSL_EVP_PKEY_assign_DSA(pkey, (WOLFSSL_DSA*)key);
- break;
- #endif
- #ifdef HAVE_ECC
- case EVP_PKEY_EC:
- ret = wolfSSL_EVP_PKEY_assign_EC_KEY(pkey, (WOLFSSL_EC_KEY*)key);
- break;
- #endif
- #ifndef NO_DH
- case EVP_PKEY_DH:
- ret = wolfSSL_EVP_PKEY_assign_DH(pkey, (WOLFSSL_DH*)key);
- break;
- #endif
- default:
- WOLFSSL_MSG("Unknown EVP_PKEY type in wolfSSL_EVP_PKEY_assign.");
- ret = WOLFSSL_FAILURE;
- }
- return ret;
- }
- #endif /* WOLFSSL_QT || OPENSSL_ALL */
- #if defined(HAVE_ECC)
- /* try and populate public pkey_sz and pkey.ptr */
- static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key)
- {
- int derSz = 0;
- byte* derBuf = NULL;
- ecc_key* ecc;
- if (pkey == NULL || key == NULL || key->internal == NULL)
- return WOLFSSL_FAILURE;
- ecc = (ecc_key*)key->internal;
- if (ecc->type == ECC_PRIVATEKEY || ecc->type == ECC_PRIVATEKEY_ONLY) {
- #ifdef HAVE_PKCS8
- if (key->pkcs8HeaderSz) {
- /* when key has pkcs8 header the pkey should too */
- if (wc_EccKeyToPKCS8(ecc, NULL, (word32*)&derSz) == LENGTH_ONLY_E) {
- derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_OPENSSL);
- if (derBuf) {
- if (wc_EccKeyToPKCS8(ecc, derBuf, (word32*)&derSz) >= 0) {
- if (pkey->pkey.ptr) {
- XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_OPENSSL);
- }
- pkey->pkey_sz = (int)derSz;
- pkey->pkey.ptr = (char*)derBuf;
- pkey->pkcs8HeaderSz = key->pkcs8HeaderSz;
- return WOLFSSL_SUCCESS;
- }
- else {
- XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL);
- derBuf = NULL;
- }
- }
- }
- }
- else
- #endif /* HAVE_PKCS8 */
- {
- if (ecc->type == ECC_PRIVATEKEY_ONLY) {
- if (wc_ecc_make_pub(ecc, NULL) != MP_OKAY) {
- return WOLFSSL_FAILURE;
- }
- }
- /* if not, the pkey will be traditional ecc key */
- if ((derSz = wc_EccKeyDerSize(ecc, 1)) > 0) {
- derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_OPENSSL);
- if (derBuf) {
- if (wc_EccKeyToDer(ecc, derBuf, derSz) >= 0) {
- if (pkey->pkey.ptr) {
- XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_OPENSSL);
- }
- pkey->pkey_sz = (int)derSz;
- pkey->pkey.ptr = (char*)derBuf;
- return WOLFSSL_SUCCESS;
- }
- else {
- XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL);
- derBuf = NULL;
- }
- }
- }
- }
- }
- else if (ecc->type == ECC_PUBLICKEY) {
- if ((derSz = (word32)wc_EccPublicKeyDerSize(ecc, 1)) > 0) {
- derBuf = (byte*)XREALLOC(pkey->pkey.ptr, derSz, NULL,
- DYNAMIC_TYPE_OPENSSL);
- if (derBuf != NULL) {
- pkey->pkey.ptr = (char*)derBuf;
- if ((derSz = wc_EccPublicKeyToDer(ecc, derBuf, derSz, 1)) < 0) {
- XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL);
- derBuf = NULL;
- }
- }
- }
- }
- if (derBuf != NULL) {
- pkey->pkey_sz = (int)derSz;
- return WOLFSSL_SUCCESS;
- }
- else {
- return WOLFSSL_FAILURE;
- }
- }
- int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key)
- {
- #ifdef HAVE_ECC
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_EC_KEY");
- if (pkey == NULL || key == NULL)
- return WOLFSSL_FAILURE;
- clearEVPPkeyKeys(pkey);
- if (wolfSSL_EC_KEY_up_ref(key) != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("wolfSSL_EC_KEY_up_ref failed");
- return WOLFSSL_FAILURE;
- }
- pkey->ecc = key;
- pkey->ownEcc = 1; /* pkey needs to call free on key */
- pkey->type = EVP_PKEY_EC;
- return ECC_populate_EVP_PKEY(pkey, key);
- #else
- (void)pkey;
- (void)key;
- return WOLFSSL_FAILURE;
- #endif /* HAVE_ECC */
- }
- void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx)
- {
- WOLFSSL_MSG("wolfSSL_EVP_X_STATE");
- if (ctx) {
- switch (ctx->cipherType) {
- case ARC4_TYPE:
- WOLFSSL_MSG("returning arc4 state");
- return (void*)&ctx->cipher.arc4.x;
- default:
- WOLFSSL_MSG("bad x state type");
- return 0;
- }
- }
- return NULL;
- }
- int wolfSSL_EVP_PKEY_assign_EC_KEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY* key)
- {
- int ret;
- if (pkey == NULL || key == NULL)
- return WOLFSSL_FAILURE;
- /* try and populate public pkey_sz and pkey.ptr */
- ret = ECC_populate_EVP_PKEY(pkey, key);
- if (ret == WOLFSSL_SUCCESS) { /* take ownership of key if can be used */
- clearEVPPkeyKeys(pkey); /* clear out any previous keys */
- pkey->type = EVP_PKEY_EC;
- pkey->ecc = key;
- pkey->ownEcc = 1;
- }
- return ret;
- }
- #endif /* HAVE_ECC */
- #ifndef NO_WOLFSSL_STUB
- const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void)
- {
- WOLFSSL_MSG("wolfSSL_ripemd160");
- WOLFSSL_STUB("EVP_ripemd160");
- return NULL;
- }
- #endif
- int wolfSSL_EVP_MD_block_size(const WOLFSSL_EVP_MD* type)
- {
- WOLFSSL_MSG("wolfSSL_EVP_MD_block_size");
- if (type == NULL) {
- WOLFSSL_MSG("No md type arg");
- return BAD_FUNC_ARG;
- }
- #ifndef NO_SHA
- if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) {
- return WC_SHA_BLOCK_SIZE;
- } else
- #endif
- #ifndef NO_SHA256
- if (XSTRCMP(type, "SHA256") == 0) {
- return WC_SHA256_BLOCK_SIZE;
- } else
- #endif
- #ifndef NO_MD4
- if (XSTRCMP(type, "MD4") == 0) {
- return MD4_BLOCK_SIZE;
- } else
- #endif
- #ifndef NO_MD5
- if (XSTRCMP(type, "MD5") == 0) {
- return WC_MD5_BLOCK_SIZE;
- } else
- #endif
- #ifdef WOLFSSL_SHA224
- if (XSTRCMP(type, "SHA224") == 0) {
- return WC_SHA224_BLOCK_SIZE;
- } else
- #endif
- #ifdef WOLFSSL_SHA384
- if (XSTRCMP(type, "SHA384") == 0) {
- return WC_SHA384_BLOCK_SIZE;
- } else
- #endif
- #ifdef WOLFSSL_SHA512
- if (XSTRCMP(type, "SHA512") == 0) {
- return WC_SHA512_BLOCK_SIZE;
- } else
- #endif
- #ifdef WOLFSSL_SHA3
- #ifndef WOLFSSL_NOSHA3_224
- if (XSTRCMP(type, "SHA3_224") == 0) {
- return WC_SHA3_224_BLOCK_SIZE;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_256
- if (XSTRCMP(type, "SHA3_256") == 0) {
- return WC_SHA3_256_BLOCK_SIZE;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_384
- if (XSTRCMP(type, "SHA3_384") == 0) {
- return WC_SHA3_384_BLOCK_SIZE;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_512
- if (XSTRCMP(type, "SHA3_512") == 0) {
- return WC_SHA3_512_BLOCK_SIZE;
- }
- #endif
- #endif /* WOLFSSL_SHA3 */
- return BAD_FUNC_ARG;
- }
- int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type)
- {
- WOLFSSL_MSG("wolfSSL_EVP_MD_size");
- if (type == NULL) {
- WOLFSSL_MSG("No md type arg");
- return BAD_FUNC_ARG;
- }
- #ifndef NO_SHA
- if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) {
- return WC_SHA_DIGEST_SIZE;
- } else
- #endif
- #ifndef NO_SHA256
- if (XSTRCMP(type, "SHA256") == 0) {
- return WC_SHA256_DIGEST_SIZE;
- } else
- #endif
- #ifndef NO_MD4
- if (XSTRCMP(type, "MD4") == 0) {
- return MD4_DIGEST_SIZE;
- } else
- #endif
- #ifndef NO_MD5
- if (XSTRCMP(type, "MD5") == 0) {
- return WC_MD5_DIGEST_SIZE;
- } else
- #endif
- #ifdef WOLFSSL_SHA224
- if (XSTRCMP(type, "SHA224") == 0) {
- return WC_SHA224_DIGEST_SIZE;
- } else
- #endif
- #ifdef WOLFSSL_SHA384
- if (XSTRCMP(type, "SHA384") == 0) {
- return WC_SHA384_DIGEST_SIZE;
- } else
- #endif
- #ifdef WOLFSSL_SHA512
- if (XSTRCMP(type, "SHA512") == 0) {
- return WC_SHA512_DIGEST_SIZE;
- } else
- #ifndef WOLFSSL_NOSHA512_224
- if (XSTRCMP(type, "SHA512_224") == 0) {
- return WC_SHA512_224_DIGEST_SIZE;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA512_256
- if (XSTRCMP(type, "SHA512_256") == 0) {
- return WC_SHA512_256_DIGEST_SIZE;
- } else
- #endif
- #endif
- #ifdef WOLFSSL_SHA3
- #ifndef WOLFSSL_NOSHA3_224
- if (XSTRCMP(type, "SHA3_224") == 0) {
- return WC_SHA3_224_DIGEST_SIZE;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_256
- if (XSTRCMP(type, "SHA3_256") == 0) {
- return WC_SHA3_256_DIGEST_SIZE;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_384
- if (XSTRCMP(type, "SHA3_384") == 0) {
- return WC_SHA3_384_DIGEST_SIZE;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_512
- if (XSTRCMP(type, "SHA3_512") == 0) {
- return WC_SHA3_512_DIGEST_SIZE;
- }
- #endif
- #endif /* WOLFSSL_SHA3 */
- return BAD_FUNC_ARG;
- }
- int wolfSSL_EVP_MD_pkey_type(const WOLFSSL_EVP_MD* type)
- {
- int ret = BAD_FUNC_ARG;
- WOLFSSL_ENTER("wolfSSL_EVP_MD_pkey_type");
- if (type != NULL) {
- if (XSTRCMP(type, "MD5") == 0) {
- ret = NID_md5WithRSAEncryption;
- }
- else if (XSTRCMP(type, "SHA1") == 0) {
- ret = NID_sha1WithRSAEncryption;
- }
- else if (XSTRCMP(type, "SHA224") == 0) {
- ret = NID_sha224WithRSAEncryption;
- }
- else if (XSTRCMP(type, "SHA256") == 0) {
- ret = NID_sha256WithRSAEncryption;
- }
- else if (XSTRCMP(type, "SHA384") == 0) {
- ret = NID_sha384WithRSAEncryption;
- }
- else if (XSTRCMP(type, "SHA512") == 0) {
- ret = NID_sha512WithRSAEncryption;
- }
- }
- WOLFSSL_LEAVE("wolfSSL_EVP_MD_pkey_type", ret);
- return ret;
- }
- int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
- {
- WOLFSSL_MSG("wolfSSL_EVP_CIPHER_CTX_iv_length");
- switch (ctx->cipherType) {
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- case AES_128_CBC_TYPE :
- case AES_192_CBC_TYPE :
- case AES_256_CBC_TYPE :
- WOLFSSL_MSG("AES CBC");
- return AES_BLOCK_SIZE;
- #endif
- #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
- (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
- #ifdef HAVE_AESGCM
- case AES_128_GCM_TYPE :
- case AES_192_GCM_TYPE :
- case AES_256_GCM_TYPE :
- WOLFSSL_MSG("AES GCM");
- if (ctx->ivSz != 0) {
- return ctx->ivSz;
- }
- return GCM_NONCE_MID_SZ;
- #endif
- #endif /* (HAVE_FIPS && !HAVE_SELFTEST) || HAVE_FIPS_VERSION >= 2 */
- #ifdef WOLFSSL_AES_COUNTER
- case AES_128_CTR_TYPE :
- case AES_192_CTR_TYPE :
- case AES_256_CTR_TYPE :
- WOLFSSL_MSG("AES CTR");
- return AES_BLOCK_SIZE;
- #endif
- #ifndef NO_DES3
- case DES_CBC_TYPE :
- WOLFSSL_MSG("DES CBC");
- return DES_BLOCK_SIZE;
- case DES_EDE3_CBC_TYPE :
- WOLFSSL_MSG("DES EDE3 CBC");
- return DES_BLOCK_SIZE;
- #endif
- #ifndef NO_RC4
- case ARC4_TYPE :
- WOLFSSL_MSG("ARC4");
- return 0;
- #endif
- #ifdef WOLFSSL_AES_CFB
- #if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
- case AES_128_CFB1_TYPE:
- case AES_192_CFB1_TYPE:
- case AES_256_CFB1_TYPE:
- WOLFSSL_MSG("AES CFB1");
- return AES_BLOCK_SIZE;
- case AES_128_CFB8_TYPE:
- case AES_192_CFB8_TYPE:
- case AES_256_CFB8_TYPE:
- WOLFSSL_MSG("AES CFB8");
- return AES_BLOCK_SIZE;
- #endif /* !HAVE_SELFTEST && !HAVE_FIPS */
- case AES_128_CFB128_TYPE:
- case AES_192_CFB128_TYPE:
- case AES_256_CFB128_TYPE:
- WOLFSSL_MSG("AES CFB128");
- return AES_BLOCK_SIZE;
- #endif /* WOLFSSL_AES_CFB */
- #if defined(WOLFSSL_AES_OFB)
- case AES_128_OFB_TYPE:
- case AES_192_OFB_TYPE:
- case AES_256_OFB_TYPE:
- WOLFSSL_MSG("AES OFB");
- return AES_BLOCK_SIZE;
- #endif /* WOLFSSL_AES_OFB */
- #ifdef WOLFSSL_AES_XTS
- case AES_128_XTS_TYPE:
- case AES_256_XTS_TYPE:
- WOLFSSL_MSG("AES XTS");
- return AES_BLOCK_SIZE;
- #endif /* WOLFSSL_AES_XTS */
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- case CHACHA20_POLY1305_TYPE:
- WOLFSSL_MSG("CHACHA20 POLY1305");
- return CHACHA20_POLY1305_AEAD_IV_SIZE;
- #endif /* HAVE_CHACHA HAVE_POLY1305 */
- case NULL_CIPHER_TYPE :
- WOLFSSL_MSG("NULL");
- return 0;
- default: {
- WOLFSSL_MSG("bad type");
- }
- }
- return 0;
- }
- int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher)
- {
- const char *name = (const char *)cipher;
- WOLFSSL_MSG("wolfSSL_EVP_CIPHER_iv_length");
- #ifndef NO_AES
- #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
- #ifdef WOLFSSL_AES_128
- if (XSTRCMP(name, EVP_AES_128_CBC) == 0)
- return AES_BLOCK_SIZE;
- #endif
- #ifdef WOLFSSL_AES_192
- if (XSTRCMP(name, EVP_AES_192_CBC) == 0)
- return AES_BLOCK_SIZE;
- #endif
- #ifdef WOLFSSL_AES_256
- if (XSTRCMP(name, EVP_AES_256_CBC) == 0)
- return AES_BLOCK_SIZE;
- #endif
- #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
- #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
- (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
- #ifdef HAVE_AESGCM
- #ifdef WOLFSSL_AES_128
- if (XSTRCMP(name, EVP_AES_128_GCM) == 0)
- return GCM_NONCE_MID_SZ;
- #endif
- #ifdef WOLFSSL_AES_192
- if (XSTRCMP(name, EVP_AES_192_GCM) == 0)
- return GCM_NONCE_MID_SZ;
- #endif
- #ifdef WOLFSSL_AES_256
- if (XSTRCMP(name, EVP_AES_256_GCM) == 0)
- return GCM_NONCE_MID_SZ;
- #endif
- #endif /* HAVE_AESGCM */
- #endif /* (HAVE_FIPS && !HAVE_SELFTEST) || HAVE_FIPS_VERSION >= 2 */
- #ifdef WOLFSSL_AES_COUNTER
- #ifdef WOLFSSL_AES_128
- if (XSTRCMP(name, EVP_AES_128_CTR) == 0)
- return AES_BLOCK_SIZE;
- #endif
- #ifdef WOLFSSL_AES_192
- if (XSTRCMP(name, EVP_AES_192_CTR) == 0)
- return AES_BLOCK_SIZE;
- #endif
- #ifdef WOLFSSL_AES_256
- if (XSTRCMP(name, EVP_AES_256_CTR) == 0)
- return AES_BLOCK_SIZE;
- #endif
- #endif
- #ifdef WOLFSSL_AES_XTS
- #ifdef WOLFSSL_AES_128
- if (XSTRCMP(name, EVP_AES_128_XTS) == 0)
- return AES_BLOCK_SIZE;
- #endif /* WOLFSSL_AES_128 */
- #ifdef WOLFSSL_AES_256
- if (XSTRCMP(name, EVP_AES_256_XTS) == 0)
- return AES_BLOCK_SIZE;
- #endif /* WOLFSSL_AES_256 */
- #endif /* WOLFSSL_AES_XTS */
- #endif
- #ifndef NO_DES3
- if ((XSTRCMP(name, EVP_DES_CBC) == 0) ||
- (XSTRCMP(name, EVP_DES_EDE3_CBC) == 0)) {
- return DES_BLOCK_SIZE;
- }
- #endif
- #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- if (XSTRCMP(name, EVP_CHACHA20_POLY1305) == 0)
- return CHACHA20_POLY1305_AEAD_IV_SIZE;
- #endif
- (void)name;
- return 0;
- }
- int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx)
- {
- WOLFSSL_MSG("wolfSSL_EVP_X_STATE_LEN");
- if (ctx) {
- switch (ctx->cipherType) {
- case ARC4_TYPE:
- WOLFSSL_MSG("returning arc4 state size");
- return sizeof(Arc4);
- default:
- WOLFSSL_MSG("bad x state type");
- return 0;
- }
- }
- return 0;
- }
- /* return of pkey->type which will be EVP_PKEY_RSA for example.
- *
- * type type of EVP_PKEY
- *
- * returns type or if type is not found then NID_undef
- */
- int wolfSSL_EVP_PKEY_type(int type)
- {
- WOLFSSL_MSG("wolfSSL_EVP_PKEY_type");
- switch (type) {
- case EVP_PKEY_RSA:
- return EVP_PKEY_RSA;
- case EVP_PKEY_DSA:
- return EVP_PKEY_DSA;
- case EVP_PKEY_EC:
- return EVP_PKEY_EC;
- case EVP_PKEY_DH:
- return EVP_PKEY_DH;
- default:
- return NID_undef;
- }
- }
- int wolfSSL_EVP_PKEY_id(const WOLFSSL_EVP_PKEY *pkey)
- {
- if (pkey != NULL)
- return pkey->type;
- return 0;
- }
- int wolfSSL_EVP_PKEY_base_id(const WOLFSSL_EVP_PKEY *pkey)
- {
- if (pkey == NULL)
- return NID_undef;
- return wolfSSL_EVP_PKEY_type(pkey->type);
- }
- int wolfSSL_EVP_PKEY_get_default_digest_nid(WOLFSSL_EVP_PKEY *pkey, int *pnid)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_get_default_digest_nid");
- if (!pkey || !pnid) {
- WOLFSSL_MSG("Bad parameter");
- return WOLFSSL_FAILURE;
- }
- switch (pkey->type) {
- case EVP_PKEY_HMAC:
- #ifndef NO_DSA
- case EVP_PKEY_DSA:
- #endif
- #ifndef NO_RSA
- case EVP_PKEY_RSA:
- #endif
- #ifdef HAVE_ECC
- case EVP_PKEY_EC:
- #endif
- *pnid = NID_sha256;
- return WOLFSSL_SUCCESS;
- default:
- return WOLFSSL_FAILURE;
- }
- }
- #if defined(OPENSSL_ALL) || defined(WOLFSSL_WPAS_SMALL)
- WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKCS82PKEY(const WOLFSSL_PKCS8_PRIV_KEY_INFO* p8)
- {
- if (p8 == NULL || p8->pkey.ptr == NULL) {
- return NULL;
- }
- return wolfSSL_d2i_PrivateKey_EVP(NULL, (unsigned char**)&p8->pkey.ptr,
- p8->pkey_sz);
- }
- /* in wolf PKCS8_PRIV_KEY_INFO and WOLFSSL_EVP_PKEY are same type */
- /* this function just casts and returns pointer */
- WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_EVP_PKEY2PKCS8(const WOLFSSL_EVP_PKEY* pkey)
- {
- return (WOLFSSL_PKCS8_PRIV_KEY_INFO*)pkey;
- }
- #endif
- /* increments ref count of WOLFSSL_EVP_PKEY. Return 1 on success, 0 on error */
- int wolfSSL_EVP_PKEY_up_ref(WOLFSSL_EVP_PKEY* pkey)
- {
- if (pkey) {
- #ifndef SINGLE_THREADED
- if (wc_LockMutex(&pkey->refMutex) != 0) {
- WOLFSSL_MSG("Failed to lock pkey mutex");
- }
- #endif
- pkey->references++;
- #ifndef SINGLE_THREADED
- wc_UnLockMutex(&pkey->refMutex);
- #endif
- return WOLFSSL_SUCCESS;
- }
- return WOLFSSL_FAILURE;
- }
- #ifndef NO_RSA
- int wolfSSL_EVP_PKEY_assign_RSA(EVP_PKEY* pkey, WOLFSSL_RSA* key)
- {
- if (pkey == NULL || key == NULL)
- return WOLFSSL_FAILURE;
- clearEVPPkeyKeys(pkey);
- pkey->type = EVP_PKEY_RSA;
- pkey->rsa = key;
- pkey->ownRsa = 1;
- /* try and populate pkey_sz and pkey.ptr */
- if (key->internal) {
- RsaKey* rsa = (RsaKey*)key->internal;
- int ret = wc_RsaKeyToDer(rsa, NULL, 0);
- if (ret > 0) {
- int derSz = ret;
- byte* derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if (derBuf) {
- ret = wc_RsaKeyToDer(rsa, derBuf, derSz);
- if (ret >= 0) {
- pkey->pkey_sz = ret;
- pkey->pkey.ptr = (char*)derBuf;
- }
- else { /* failure - okay to ignore */
- XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- derBuf = NULL;
- }
- }
- }
- }
- return WOLFSSL_SUCCESS;
- }
- #endif /* !NO_RSA */
- #ifndef NO_DSA
- int wolfSSL_EVP_PKEY_assign_DSA(EVP_PKEY* pkey, WOLFSSL_DSA* key)
- {
- if (pkey == NULL || key == NULL)
- return WOLFSSL_FAILURE;
- clearEVPPkeyKeys(pkey);
- pkey->type = EVP_PKEY_DSA;
- pkey->dsa = key;
- pkey->ownDsa = 1;
- return WOLFSSL_SUCCESS;
- }
- #endif /* !NO_DSA */
- #ifndef NO_DH
- int wolfSSL_EVP_PKEY_assign_DH(EVP_PKEY* pkey, WOLFSSL_DH* key)
- {
- if (pkey == NULL || key == NULL)
- return WOLFSSL_FAILURE;
- clearEVPPkeyKeys(pkey);
- pkey->type = EVP_PKEY_DH;
- pkey->dh = key;
- pkey->ownDh = 1;
- return WOLFSSL_SUCCESS;
- }
- #endif /* !NO_DH */
- #endif /* OPENSSL_EXTRA */
- #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
- /* Subset of OPENSSL_EXTRA for PKEY operations PKEY free is needed by the
- * subset of X509 API */
- WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new(void){
- return wolfSSL_EVP_PKEY_new_ex(NULL);
- }
- WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_ex(void* heap)
- {
- WOLFSSL_EVP_PKEY* pkey;
- int ret;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_new_ex");
- pkey = (WOLFSSL_EVP_PKEY*)XMALLOC(sizeof(WOLFSSL_EVP_PKEY), heap,
- DYNAMIC_TYPE_PUBLIC_KEY);
- if (pkey != NULL) {
- XMEMSET(pkey, 0, sizeof(WOLFSSL_EVP_PKEY));
- pkey->heap = heap;
- pkey->type = WOLFSSL_EVP_PKEY_DEFAULT;
- #ifndef SINGLE_THREADED
- /* init of mutex needs to come before wolfSSL_EVP_PKEY_free */
- ret = wc_InitMutex(&pkey->refMutex);
- if (ret != 0){
- XFREE(pkey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
- WOLFSSL_MSG("Issue initializing mutex");
- return NULL;
- }
- #endif
- #ifndef HAVE_FIPS
- ret = wc_InitRng_ex(&pkey->rng, heap, INVALID_DEVID);
- #else
- ret = wc_InitRng(&pkey->rng);
- #endif
- pkey->references = 1;
- if (ret != 0){
- wolfSSL_EVP_PKEY_free(pkey);
- WOLFSSL_MSG("Issue initializing RNG");
- return NULL;
- }
- }
- else {
- WOLFSSL_MSG("memory failure");
- }
- return pkey;
- }
- void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key)
- {
- int doFree = 0;
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_free");
- if (key != NULL) {
- #ifndef SINGLE_THREADED
- if (wc_LockMutex(&key->refMutex) != 0) {
- WOLFSSL_MSG("Couldn't lock pkey mutex");
- }
- #endif
- /* only free if all references to it are done */
- key->references--;
- if (key->references == 0) {
- doFree = 1;
- }
- #ifndef SINGLE_THREADED
- wc_UnLockMutex(&key->refMutex);
- #endif
- if (doFree) {
- wc_FreeRng(&key->rng);
- if (key->pkey.ptr != NULL) {
- XFREE(key->pkey.ptr, key->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- key->pkey.ptr = NULL;
- }
- switch(key->type)
- {
- #ifndef NO_RSA
- case EVP_PKEY_RSA:
- if (key->rsa != NULL && key->ownRsa == 1) {
- wolfSSL_RSA_free(key->rsa);
- key->rsa = NULL;
- }
- break;
- #endif /* NO_RSA */
- #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
- case EVP_PKEY_EC:
- if (key->ecc != NULL && key->ownEcc == 1) {
- wolfSSL_EC_KEY_free(key->ecc);
- key->ecc = NULL;
- }
- break;
- #endif /* HAVE_ECC && OPENSSL_EXTRA */
- #ifndef NO_DSA
- case EVP_PKEY_DSA:
- if (key->dsa != NULL && key->ownDsa == 1) {
- wolfSSL_DSA_free(key->dsa);
- key->dsa = NULL;
- }
- break;
- #endif /* NO_DSA */
- #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
- case EVP_PKEY_DH:
- if (key->dh != NULL && key->ownDh == 1) {
- wolfSSL_DH_free(key->dh);
- key->dh = NULL;
- }
- break;
- #endif /* ! NO_DH ... */
- #ifdef HAVE_HKDF
- case EVP_PKEY_HKDF:
- if (key->hkdfSalt != NULL) {
- XFREE(key->hkdfSalt, NULL, DYNAMIC_TYPE_SALT);
- key->hkdfSalt = NULL;
- }
- if (key->hkdfKey != NULL) {
- XFREE(key->hkdfKey, NULL, DYNAMIC_TYPE_KEY);
- key->hkdfKey = NULL;
- }
- if (key->hkdfInfo != NULL) {
- XFREE(key->hkdfInfo, NULL, DYNAMIC_TYPE_INFO);
- key->hkdfInfo = NULL;
- }
- key->hkdfSaltSz = 0;
- key->hkdfKeySz = 0;
- key->hkdfInfoSz = 0;
- break;
- #endif /* HAVE_HKDF */
- default:
- break;
- }
- #ifndef SINGLE_THREADED
- if (wc_FreeMutex(&key->refMutex) != 0) {
- WOLFSSL_MSG("Couldn't free pkey mutex");
- }
- #endif
- XFREE(key, key->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- }
- }
- }
- #if defined(OPENSSL_EXTRA) && !defined(NO_BIO)
- /* Indent writes white spaces of the number specified by "indents"
- * to the BIO. The number of white spaces is limited from 0 to
- * EVP_PKEY_PRINT_INDENT_MAX.
- * returns the amount written to BIO.
- */
- static int Indent(WOLFSSL_BIO* out, int indents)
- {
- int i;
- char space = ' ';
- if (out == NULL) {
- return 0;
- }
- if (indents > EVP_PKEY_PRINT_INDENT_MAX) {
- indents = EVP_PKEY_PRINT_INDENT_MAX;
- }
- for (i = 0; i < indents; i++) {
- if (wolfSSL_BIO_write(out, &space, 1) < 0) {
- break;
- }
- }
- return indents -i;
- }
- /* PrintHexWithColon dump byte-data specified by "input" to the "out".
- * Each line has leading white spaces( "indent" gives the number ) plus
- * four spaces, then hex coded 15 byte data with separator ":" follow.
- * Each line looks like:
- * " 00:e6:ab: --- 9f:ef:"
- * Parameters:
- * out bio to output dump data
- * input buffer holding data to dump
- * inlen input data size
- * indent the number of spaces for indent
- * Returns 1 on success, 0 on failure.
- */
- static int PrintHexWithColon(WOLFSSL_BIO* out, const byte* input,
- int inlen, int indent)
- {
- #ifdef WOLFSSL_SMALL_STACK
- byte* buff = NULL;
- #else
- byte buff[EVP_PKEY_PRINT_LINE_WIDTH_MAX] = { 0 };
- #endif /* WOLFSSL_SMALL_STACK */
- int ret = WOLFSSL_SUCCESS;
- word32 in = 0;
- word32 i;
- int idx;
- const byte* data;
- word32 outSz;
- byte outHex[3];
- if (!out || !input || inlen <= 0) {
- return WOLFSSL_FAILURE;
- }
- if (indent < 0) {
- indent = 0;
- }
- if (indent > EVP_PKEY_PRINT_INDENT_MAX) {
- indent = EVP_PKEY_PRINT_INDENT_MAX;
- }
- data = input;
- #ifdef WOLFSSL_SMALL_STACK
- buff = (byte*)XMALLOC(EVP_PKEY_PRINT_LINE_WIDTH_MAX, NULL,
- DYNAMIC_TYPE_TMP_BUFFER);
- if (!buff) {
- return WOLFSSL_FAILURE;
- }
- #endif
- /* print pub element */
- idx = 0;
- for (in = 0; in < (word32)inlen && ret == WOLFSSL_SUCCESS; in +=
- EVP_PKEY_PRINT_DIGITS_PER_LINE ) {
- Indent(out, indent);
- for (i = 0; (i < EVP_PKEY_PRINT_DIGITS_PER_LINE) &&
- (in + i < (word32)inlen); i++) {
- if (ret == WOLFSSL_SUCCESS) {
- outSz = sizeof(outHex);
- ret = Base16_Encode((const byte*)&data[in + i], 1,
- outHex, &outSz) == 0;
- }
- if (ret == WOLFSSL_SUCCESS) {
- XMEMCPY(buff + idx, outHex, 2);
- idx += 2;
- if (in + i != (word32)inlen -1) {
- XMEMSET(buff + idx, ':', 1);
- idx += 1;
- }
- }
- }
- if (ret == WOLFSSL_SUCCESS) {
- ret = wolfSSL_BIO_write(out, buff, idx) > 0;
- }
- if (ret == WOLFSSL_SUCCESS) {
- ret = wolfSSL_BIO_write(out, "\n", 1) > 0;
- }
- if (ret == WOLFSSL_SUCCESS) {
- XMEMSET(buff, 0, EVP_PKEY_PRINT_LINE_WIDTH_MAX);
- idx = 0;
- }
- }
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- #endif
- return ret;
- }
- #if !defined(NO_RSA)
- /* PrintPubKeyRSA is a helper function for wolfSSL_EVP_PKEY_print_public
- * to parse a DER format RSA public key specified in the second parameter.
- * Parameters:
- * out bio to output dump data
- * pkey buffer holding public key data
- * pkeySz public key data size
- * indent the number of spaces for indent
- * bitlen bit size of the given key
- * pctx context(not used)
- * Returns 1 on success, 0 on failure.
- */
- static int PrintPubKeyRSA(WOLFSSL_BIO* out, const byte* pkey, int pkeySz,
- int indent, int bitlen, ASN1_PCTX* pctx)
- {
- byte buff[8] = { 0 };
- int res = WOLFSSL_FAILURE;
- word32 inOutIdx = 0;
- word32 nSz; /* size of modulus */
- word32 eSz; /* size of public exponent */
- const byte* n = NULL;
- const byte* e = NULL; /* pointer to modulus/exponent */
- int idx;
- int wsz;
- word32 i;
- unsigned long exponent = 0;
- #ifdef WOLFSSL_SMALL_STACK
- mp_int* a = NULL;
- #else
- mp_int a[1];
- #endif
- char line[32] = { 0 };
- (void)pctx;
- #ifdef WOLFSSL_SMALL_STACK
- a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
- if (a == NULL) {
- return WOLFSSL_FAILURE;
- }
- #endif
- if( mp_init(a) != 0) {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
- #endif
- return WOLFSSL_FAILURE;
- }
- if (indent < 0) {
- indent = 0;
- }
- if (indent > EVP_PKEY_PRINT_INDENT_MAX) {
- indent = EVP_PKEY_PRINT_INDENT_MAX;
- }
- do {
- /* parse key to get modulus and exponent */
- if (wc_RsaPublicKeyDecode_ex(pkey, &inOutIdx, pkeySz,
- &n, &nSz, &e, &eSz) != 0) {
- break;
- }
- /* print out public key elements */
- idx = 0;
- XMEMSET(buff, 0, sizeof(buff));
- Indent(out, indent);
- XSTRNCPY(line, "RSA Public-Key: (", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- if (mp_set_int(a, bitlen) != 0) {
- break;
- }
- if (mp_todecimal(a, (char*)buff) != 0) {
- break;
- }
- wsz = (int)XSTRLEN((const char*)buff);
- if (wolfSSL_BIO_write(out, buff + idx, wsz) <= 0) {
- break;
- }
- XSTRNCPY(line, " bit)\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- /* print Modulus */
- Indent(out, indent);
- XSTRNCPY(line, "Modulus:\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- /* print modulus with leading zero if exists */
- if (*n & 0x80 && *(n-1) == 0) {
- n--;
- nSz++;
- }
- if (PrintHexWithColon(out, n, nSz, indent + 4) != WOLFSSL_SUCCESS) {
- break;
- }
- /* print public Exponent */
- idx = 0;
- Indent(out, indent);
- XSTRNCPY(line, "Exponent: ", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- for (i = 0; i < eSz; i++) {
- exponent <<= 8;
- exponent += e[i];
- }
- XMEMSET(buff, 0, sizeof(buff));
- if (mp_set_int(a, exponent) != 0) {
- break;
- }
- if (mp_todecimal(a, (char*)buff) != 0) {
- break;
- }
- wsz = (int)XSTRLEN((const char*)buff);
- if (wolfSSL_BIO_write(out, buff + idx, wsz) <= 0) {
- break;
- }
- XSTRNCPY(line, " (0x", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- XMEMSET(buff, 0, sizeof(buff));
- if (mp_tohex(a, (char*)buff) != 0) {
- break;
- }
- if (wolfSSL_BIO_write(out, buff, (int)XSTRLEN((char*)buff)) <= 0) {
- break;
- }
- XSTRNCPY(line, ")\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- res = WOLFSSL_SUCCESS;
- } while (0);
- mp_free(a);
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
- #endif
- return res;
- }
- #endif /* !NO_RSA */
- #if defined(HAVE_ECC)
- /* PrintPubKeyEC is a helper function for wolfSSL_EVP_PKEY_print_public
- * to parse a DER format ECC public key specified in the second parameter.
- * Parameters:
- * out bio to output dump data
- * pkey buffer holding public key data
- * pkeySz public key data size
- * indent the number of spaces for indent
- * bitlen bit size of the given key
- * pctx context(not used)
- * Returns 1 on success, 0 on failure.
- */
- static int PrintPubKeyEC(WOLFSSL_BIO* out, const byte* pkey, int pkeySz,
- int indent, int bitlen, ASN1_PCTX* pctx)
- {
- byte* pub = NULL;
- word32 pubSz = 0;
- byte buff[8] = { 0 };
- int res = WOLFSSL_SUCCESS;
- word32 inOutIdx = 0;
- int curveId = 0;
- const byte* curveOID = NULL;
- word32 oidSz = 0;
- const char* OIDName = NULL;
- const char* nistCurveName = NULL;
- int nid;
- int idx = 0;
- int wsz = 0;
- #ifdef WOLFSSL_SMALL_STACK
- mp_int* a = NULL;
- ecc_key* key = NULL;
- #else
- mp_int a[1];
- ecc_key key[1];
- #endif
- char line[32] = { 0 };
- (void)pctx;
- #ifdef WOLFSSL_SMALL_STACK
- a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
- if (a == NULL) {
- WOLFSSL_MSG("Failed to allocate memory for mp_int");
- return WOLFSSL_FAILURE;
- }
- XMEMSET(a, 0, sizeof(mp_int));
- key = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
- if (key == NULL) {
- WOLFSSL_MSG("Failed to allocate memory for ecc_key");
- XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
- return WOLFSSL_FAILURE;
- }
- #endif
- if (mp_init(a) != 0) {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(key, NULL, DYNAMIC_TYPE_ECC);
- XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
- #endif
- return WOLFSSL_FAILURE;
- }
- if (wc_ecc_init(key) != 0) {
- /* Return early so we don't have to remember if init succeeded
- * or not. */
- mp_free(a);
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(key, NULL, DYNAMIC_TYPE_ECC);
- XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
- #endif
- return WOLFSSL_FAILURE;
- }
- if (indent < 0) {
- indent = 0;
- }
- else if (indent > EVP_PKEY_PRINT_INDENT_MAX) {
- indent = EVP_PKEY_PRINT_INDENT_MAX;
- }
- if (res == WOLFSSL_SUCCESS) {
- res = wc_EccPublicKeyDecode(pkey, &inOutIdx, key, pkeySz) == 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- curveId = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
- res = curveId > 0 && oidSz > 0;
- }
- /* get NIST curve name */
- if (res == WOLFSSL_SUCCESS) {
- nid = EccEnumToNID(curveId);
- if (nid != -1) {
- /* look up object name and nist curve name*/
- OIDName = wolfSSL_OBJ_nid2sn(nid);
- nistCurveName = wolfSSL_EC_curve_nid2nist(nid);
- res = (nistCurveName != NULL) && (OIDName != NULL);
- }
- else {
- res = WOLFSSL_FAILURE;
- }
- }
- if (res == WOLFSSL_SUCCESS) {
- pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
- if (pub != NULL) {
- pubSz = ECC_BUFSIZE;
- XMEMSET(pub, 0, ECC_BUFSIZE);
- PRIVATE_KEY_UNLOCK();
- res = wc_ecc_export_x963(key, pub, &pubSz) == 0;
- PRIVATE_KEY_LOCK();
- }
- else {
- res = WOLFSSL_FAILURE;
- }
- }
- if (res == WOLFSSL_SUCCESS) {
- idx = 0;
- res = Indent(out, indent) >= 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- XSTRNCPY(line, "Public-Key: (", sizeof(line));
- res = wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) > 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- res = mp_set_int(a, bitlen) == 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- res = mp_todecimal(a, (char*)buff) == 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- wsz = (int)XSTRLEN((const char*)buff);
- }
- if (res == WOLFSSL_SUCCESS) {
- res = wolfSSL_BIO_write(out, buff + idx, wsz) >= 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- XSTRNCPY(line, " bit)\n", sizeof(line));
- res = wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) > 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- res = Indent(out, indent) >= 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- /* print pub element */
- XSTRNCPY(line, "pub:\n", sizeof(line));
- res = wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) > 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- res = PrintHexWithColon(out, pub, pubSz, indent + 4);
- }
- if (res == WOLFSSL_SUCCESS) {
- res = Indent(out, indent) >= 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- /* print OID in name */
- XSTRNCPY(line, "ASN1 OID: ", sizeof(line));
- res = wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) > 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- res = wolfSSL_BIO_write(out, OIDName, (int)XSTRLEN(OIDName)) > 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- res = wolfSSL_BIO_write(out, "\n", 1) > 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- res = Indent(out, indent) >= 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- /* print NIST curve name */
- XSTRNCPY(line, "NIST CURVE: ", sizeof(line));
- res = wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) > 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- res = wolfSSL_BIO_write(out, nistCurveName,
- (int)XSTRLEN(nistCurveName)) > 0;
- }
- if (res == WOLFSSL_SUCCESS) {
- res = wolfSSL_BIO_write(out, "\n", 1) > 0;
- }
- if (pub != NULL) {
- XFREE(pub, NULL, DYNAMIC_TYPE_ECC_BUFFER);
- pub = NULL;
- }
- wc_ecc_free(key);
- mp_free(a);
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(key, NULL, DYNAMIC_TYPE_ECC);
- XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
- #endif
- return res;
- }
- #endif /* HAVE_ECC */
- #if !defined(NO_DSA)
- /* PrintPubKeyDSA is a helper function for wolfSSL_EVP_PKEY_print_public
- * to parse a DER format DSA public key specified in the second parameter.
- * Parameters:
- * out bio to output dump data
- * pkey buffer holding public key data
- * pkeySz public key data size
- * indent the number of spaces for indent
- * bitlen bit size of the given key
- * pctx context(not used)
- * Returns 1 on success, 0 on failure.
- */
- static int PrintPubKeyDSA(WOLFSSL_BIO* out, const byte* pkey, int pkeySz,
- int indent, int bitlen, ASN1_PCTX* pctx)
- {
- byte buff[8] = { 0 };
- int length;
- int res = WOLFSSL_FAILURE;
- word32 inOutIdx = 0;
- word32 oid;
- byte tagFound;
- byte *p = NULL, * q = NULL, * g = NULL, * y = NULL;
- int pSz, qSz, gSz, ySz;
- int idx;
- int wsz;
- #ifdef WOLFSSL_SMALL_STACK
- mp_int* a = NULL;
- #else
- mp_int a[1];
- #endif
- char line[32] = { 0 };
- #ifdef WOLFSSL_SMALL_STACK
- a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
- if (a == NULL) {
- return WOLFSSL_FAILURE;
- }
- #endif
- if( mp_init(a) != 0) {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
- #endif
- return WOLFSSL_FAILURE;
- }
- inOutIdx = 0;
- (void)pctx;
- if (indent < 0) {
- indent = 0;
- }
- if (indent > EVP_PKEY_PRINT_INDENT_MAX) {
- indent = EVP_PKEY_PRINT_INDENT_MAX;
- }
- do {
- if (GetSequence(pkey, &inOutIdx, &length, pkeySz) < 0) {
- break;
- }
- if (GetSequence(pkey, &inOutIdx, &length, pkeySz) < 0) {
- break;
- }
- if (GetObjectId(pkey, &inOutIdx, &oid, oidIgnoreType, pkeySz) != 0) {
- break;
- }
- if (GetSequence(pkey, &inOutIdx, &length, pkeySz) < 0) {
- break;
- }
- /* find P */
- if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) {
- break;
- }
- if (tagFound != ASN_INTEGER) {
- break;
- }
- if (GetLength(pkey, &inOutIdx, &length, pkeySz) <= 0) {
- break;
- }
- p = (byte*)(pkey + inOutIdx);
- pSz = length;
- if (bitlen == 0) {
- if (*p == 0) {
- bitlen = (pSz - 1) * 8; /* remove leading zero */
- }
- else {
- bitlen = pSz * 8;
- }
- }
- inOutIdx += length;
- /* find Q */
- if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) {
- break;
- }
- if (tagFound != ASN_INTEGER) {
- break;
- }
- if (GetLength(pkey, &inOutIdx, &length, pkeySz) <= 0) {
- break;
- }
- q = (byte*)(pkey + inOutIdx);
- qSz = length;
- inOutIdx += length;
- /* find G */
- if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) {
- break;
- }
- if (tagFound != ASN_INTEGER) {
- break;
- }
- if (GetLength(pkey, &inOutIdx, &length, pkeySz) <= 0) {
- break;
- }
- g = (byte*)(pkey + inOutIdx);
- gSz = length;
- inOutIdx += length;
- /* find Y */
- if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) {
- break;
- }
- if (tagFound != ASN_BIT_STRING) {
- break;
- }
- if (GetLength(pkey, &inOutIdx, &length, pkeySz) <= 0) {
- break;
- }
- inOutIdx++; /* skip the first byte( unused byte number)*/
- if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) {
- break;
- }
- if (tagFound != ASN_INTEGER) {
- break;
- }
- if (GetLength(pkey, &inOutIdx, &length, pkeySz) <= 0) {
- break;
- }
- y = (byte*)(pkey + inOutIdx);
- ySz = length;
- idx = 0;
- XMEMSET(buff, 0, sizeof(buff));
- Indent(out, indent);
- XSTRNCPY(line, "DSA Public-Key: (", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- if (mp_set_int(a, bitlen) != 0) {
- break;
- }
- if (mp_todecimal(a, (char*)buff) != 0) {
- break;
- }
- wsz = (int)XSTRLEN((const char*)buff);
- if (wolfSSL_BIO_write(out, buff + idx, wsz) <= 0) {
- break;
- }
- XSTRNCPY(line, " bit)\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- /* print pub element */
- Indent(out, indent);
- XSTRNCPY(line, "pub:\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- if (PrintHexWithColon(out, y, ySz, indent + 4) != WOLFSSL_SUCCESS) {
- break;
- }
- /* print P element */
- Indent(out, indent);
- XSTRNCPY(line, "P:\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- if (PrintHexWithColon(out, p, pSz, indent + 4) != WOLFSSL_SUCCESS) {
- break;
- }
- /* print Q element */
- Indent(out, indent);
- XSTRNCPY(line, "Q:\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- if (PrintHexWithColon(out, q, qSz, indent + 4) != WOLFSSL_SUCCESS) {
- break;
- }
- /* print G element */
- Indent(out, indent);
- XSTRNCPY(line, "G:\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- if (PrintHexWithColon(out, g, gSz, indent + 4) != WOLFSSL_SUCCESS) {
- break;
- }
- res = WOLFSSL_SUCCESS;
- } while (0);
- mp_free(a);
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
- #endif
- return res;
- }
- #endif /* !NO_DSA */
- #if defined(WOLFSSL_DH_EXTRA)
- /* PrintPubKeyDH is a helper function for wolfSSL_EVP_PKEY_print_public
- * to parse a DER format DH public key specified in the second parameter.
- * Parameters:
- * out bio to output dump data
- * pkey buffer holding public key data
- * pkeySz public key data size
- * indent the number of spaces for indent
- * bitlen bit size of the given key
- * pctx context(not used)
- * Returns 1 on success, 0 on failure.
- */
- static int PrintPubKeyDH(WOLFSSL_BIO* out, const byte* pkey, int pkeySz,
- int indent, int bitlen, ASN1_PCTX* pctx)
- {
- byte buff[8] = { 0 };
- int res = WOLFSSL_FAILURE;
- word32 length;
- word32 inOutIdx;
- word32 oid;
- byte tagFound;
- byte* prime = NULL;
- int primeSz;
- byte generator;
- byte* publicKey = NULL;
- int publicKeySz;
- int idx;
- int wsz;
- word32 outSz;
- byte outHex[3];
- #ifdef WOLFSSL_SMALL_STACK
- mp_int* a = NULL;
- #else
- mp_int a[1];
- #endif
- char line[32] = { 0 };
- #ifdef WOLFSSL_SMALL_STACK
- a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
- if (a == NULL) {
- return WOLFSSL_FAILURE;
- }
- #endif
- if( mp_init(a) != 0) {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
- #endif
- return WOLFSSL_FAILURE;
- }
- inOutIdx = 0;
- (void)pctx;
- if (indent < 0) {
- indent = 0;
- }
- if (indent > EVP_PKEY_PRINT_INDENT_MAX) {
- indent = EVP_PKEY_PRINT_INDENT_MAX;
- }
- do {
- if (GetSequence(pkey, &inOutIdx, (int*)&length, pkeySz) < 0) {
- break;
- }
- if (GetSequence(pkey, &inOutIdx, (int*)&length, pkeySz) < 0) {
- break;
- }
- if (GetObjectId(pkey, &inOutIdx, &oid, oidIgnoreType, pkeySz) < 0) {
- break;
- }
- if (GetSequence(pkey, &inOutIdx, (int*)&length, pkeySz) < 0) {
- break;
- }
- /* get prime element */
- if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) {
- break;
- }
- if (tagFound != ASN_INTEGER) {
- break;
- }
- if (GetLength(pkey, &inOutIdx, (int*)&length, pkeySz) <= 0) {
- break;
- }
- prime = (byte*)(pkey + inOutIdx);
- primeSz = length;
- inOutIdx += length;
- /* get generator element */
- if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) {
- break;
- }
- if (tagFound != ASN_INTEGER) {
- break;
- }
- if (GetLength(pkey, &inOutIdx, (int*)&length, pkeySz) <= 0) {
- break;
- }
- if (length != 1) {
- break;
- }
- generator = *(pkey + inOutIdx);
- inOutIdx += length;
- /* get public-key element */
- if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) {
- break;
- }
- if (tagFound != ASN_BIT_STRING) {
- break;
- }
- if (GetLength(pkey, &inOutIdx, (int*)&length, pkeySz) <= 0) {
- break;
- }
- inOutIdx ++;
- if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) {
- break;
- }
- if (tagFound != ASN_INTEGER) {
- break;
- }
- if (GetLength(pkey, &inOutIdx, (int*)&length, pkeySz) <= 0) {
- break;
- }
- publicKeySz = length;
- publicKey = (byte*)(pkey + inOutIdx);
- if (bitlen == 0) {
- if (*publicKey == 0) {
- bitlen = (publicKeySz - 1) * 8;
- }
- else {
- bitlen = publicKeySz * 8;
- }
- }
- /* print elements */
- idx = 0;
- Indent(out, indent);
- XSTRNCPY(line, "DH Public-Key: (", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- if (mp_set_int(a, bitlen) != 0) {
- break;
- }
- if (mp_todecimal(a, (char*)buff) != 0) {
- break;
- }
- wsz = (int)XSTRLEN((const char*)buff);
- if (wolfSSL_BIO_write(out, buff + idx, wsz) <= 0) {
- break;
- }
- XSTRNCPY(line, " bit)\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- Indent(out, indent);
- XSTRNCPY(line, "public-key:\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- if (PrintHexWithColon(out, publicKey, publicKeySz, indent + 4)
- != WOLFSSL_SUCCESS) {
- break;
- }
- Indent(out, indent);
- XSTRNCPY(line, "prime:\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- if (PrintHexWithColon(out, prime, primeSz, indent + 4)
- != WOLFSSL_SUCCESS) {
- break;
- }
- idx = 0;
- XMEMSET(buff, 0, sizeof(buff));
- Indent(out, indent);
- XSTRNCPY(line, "generator: ", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- if (mp_set_int(a, generator) != 0) {
- break;
- }
- if (mp_todecimal(a, (char*)buff) != 0) {
- break;
- }
- wsz = (int)XSTRLEN((const char*)buff);
- if (wolfSSL_BIO_write(out, buff + idx, wsz) <= 0) {
- break;
- }
- XSTRNCPY(line, " (0x", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- idx = 0;
- XMEMSET(buff, 0, sizeof(buff));
- outSz = sizeof(outHex);
- if (Base16_Encode((const byte*)&generator, 1, outHex, &outSz ) != 0) {
- break;
- }
- if (idx + 2 < (int)sizeof(buff) ) {
- XMEMCPY(buff + idx, outHex, 2);
- idx += 2;
- }
- if (wolfSSL_BIO_write(out, buff, idx) <= 0 ) {
- break;
- }
- XSTRNCPY(line, ")\n", sizeof(line));
- if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) {
- break;
- }
- res = WOLFSSL_SUCCESS;
- } while (0);
- mp_free(a);
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
- #endif
- return res;
- }
- #endif /* WOLFSSL_DH_EXTRA */
- /* wolfSSL_EVP_PKEY_print_public parses the specified key then
- * outputs public key info in human readable format to the specified BIO.
- * White spaces of the same number which 'indent" gives, will be added to
- * each line to output and ignores pctx parameter.
- * Parameters:
- * out bio to output dump data
- * pkey buffer holding public key data
- * indent the number of spaces for indent
- * pctx context(not used)
- * Returns 1 on success, 0 or negative on error, -2 means specified key
- * algo is not supported.
- * Can handle RSA, ECC, DSA and DH public keys.
- */
- int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out,
- const WOLFSSL_EVP_PKEY* pkey, int indent, ASN1_PCTX* pctx)
- {
- int res;
- #if !defined(NO_RSA) || defined(HAVE_ECC) || !defined(NO_DSA) || \
- defined(WOLFSSL_DH_EXTRA)
- int keybits; /* bit length of the key */
- #endif
- WOLFSSL_ENTER("wolfSSL_EVP_PKEY_print_public");
- if (pkey == NULL || out == NULL) {
- return 0;
- }
- #if !defined(NO_RSA) || defined(HAVE_ECC) || !defined(NO_DSA) || \
- defined(WOLFSSL_DH_EXTRA)
- if (indent < 0) {
- indent = 0;
- }
- if (indent > EVP_PKEY_PRINT_INDENT_MAX) {
- indent = EVP_PKEY_PRINT_INDENT_MAX;
- }
- #endif
- switch (pkey->type) {
- case EVP_PKEY_RSA:
- #if !defined(NO_RSA)
- keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8;
- res = PrintPubKeyRSA(
- out,
- (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */
- pkey->pkey_sz, /* raw pkey size */
- indent, /* indent size */
- keybits, /* bit length of the key */
- pctx); /* not used */
- #else
- res = WOLFSSL_UNKNOWN; /* not supported algo */
- #endif
- break;
- case EVP_PKEY_EC:
- #if defined(HAVE_ECC)
- keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8;
- res = PrintPubKeyEC(
- out,
- (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */
- pkey->pkey_sz, /* raw pkey size */
- indent, /* indent size */
- keybits, /* bit length of the key */
- pctx); /* not used */
- #else
- res = WOLFSSL_UNKNOWN; /* not supported algo */
- #endif
- break;
- case EVP_PKEY_DSA:
- #if !defined(NO_DSA)
- keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8;
- res = PrintPubKeyDSA(
- out,
- (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */
- pkey->pkey_sz, /* raw pkey size */
- indent, /* indent size */
- keybits, /* bit length of the key */
- pctx); /* not used */
- #else
- res = WOLFSSL_UNKNOWN; /* not supported algo */
- #endif
- break;
- case EVP_PKEY_DH:
- #if defined(WOLFSSL_DH_EXTRA)
- keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8;
- res = PrintPubKeyDH(
- out,
- (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */
- pkey->pkey_sz, /* raw pkey size */
- indent, /* indent size */
- keybits, /* bit length of the key */
- pctx); /* not used */
- #else
- res = WOLFSSL_UNKNOWN; /* not supported algo */
- #endif
- break;
- default:
- res = WOLFSSL_UNKNOWN; /* not supported algo */
- break;
- }
- return res;
- }
- #endif /* OPENSSL_EXTRA && !NO_BIO */
- int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp,
- int* pHash, int* pHashSz)
- {
- enum wc_HashType hash = WC_HASH_TYPE_NONE;
- int hashSz;
- if (XSTRLEN(evp) < 3) {
- /* do not try comparing strings if size is too small */
- return WOLFSSL_FAILURE;
- }
- #ifndef NO_SHA
- if ((XSTRCMP("SHA", evp) == 0) || (XSTRCMP("SHA1", evp) == 0)) {
- hash = WC_HASH_TYPE_SHA;
- } else
- #endif
- #ifdef WOLFSSL_SHA224
- if (XSTRCMP("SHA224", evp) == 0) {
- hash = WC_HASH_TYPE_SHA224;
- } else
- #endif
- #ifndef NO_SHA256
- if (XSTRCMP("SHA256", evp) == 0) {
- hash = WC_HASH_TYPE_SHA256;
- } else
- #endif
- #ifdef WOLFSSL_SHA384
- if (XSTRCMP("SHA384", evp) == 0) {
- hash = WC_HASH_TYPE_SHA384;
- } else
- #endif
- #ifdef WOLFSSL_SHA512
- if (XSTRCMP("SHA512", evp) == 0) {
- hash = WC_HASH_TYPE_SHA512;
- } else
- #ifndef WOLFSSL_NOSHA512_224
- if (XSTRCMP("SHA512_224", evp) == 0) {
- hash = WC_HASH_TYPE_SHA512_224;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA512_256
- if (XSTRCMP("SHA512_256", evp) == 0) {
- hash = WC_HASH_TYPE_SHA512_256;
- } else
- #endif
- #endif
- #ifdef WOLFSSL_SHA3
- #ifndef WOLFSSL_NOSHA3_224
- if (XSTRCMP("SHA3_224", evp) == 0) {
- hash = WC_HASH_TYPE_SHA3_224;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_256
- if (XSTRCMP("SHA3_256", evp) == 0) {
- hash = WC_HASH_TYPE_SHA3_256;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_384
- if (XSTRCMP("SHA3_384", evp) == 0) {
- hash = WC_HASH_TYPE_SHA3_384;
- } else
- #endif
- #ifndef WOLFSSL_NOSHA3_512
- if (XSTRCMP("SHA3_512", evp) == 0) {
- hash = WC_HASH_TYPE_SHA3_512;
- } else
- #endif
- #endif /* WOLFSSL_SHA3 */
- #ifdef WOLFSSL_MD2
- if (XSTRCMP("MD2", evp) == 0) {
- hash = WC_HASH_TYPE_MD2;
- } else
- #endif
- #ifndef NO_MD4
- if (XSTRCMP("MD4", evp) == 0) {
- hash = WC_HASH_TYPE_MD4;
- } else
- #endif
- #ifndef NO_MD5
- if (XSTRCMP("MD5", evp) == 0) {
- hash = WC_HASH_TYPE_MD5;
- } else
- #endif
- {
- if (XSTRNCMP("SHA", evp, 3) == 0) {
- WOLFSSL_MSG("Unknown SHA hash");
- }
- return WOLFSSL_FAILURE;
- }
- if (pHash)
- *pHash = hash;
- hashSz = wc_HashGetDigestSize(hash);
- if (pHashSz)
- *pHashSz = hashSz;
- if (hashSz < 0) {
- return WOLFSSL_FAILURE;
- }
- return WOLFSSL_SUCCESS;
- }
- /* Base64 encoding APIs */
- #if defined(WOLFSSL_BASE64_ENCODE) || defined(WOLFSSL_BASE64_DECODE)
- /* wolfSSL_EVP_ENCODE_CTX_new allocates WOLFSSL_EVP_ENCODE_CTX
- * Returns WOLFSSL_EVP_ENCODE_CTX structure on success, NULL on failure.
- */
- struct WOLFSSL_EVP_ENCODE_CTX* wolfSSL_EVP_ENCODE_CTX_new(void)
- {
- WOLFSSL_EVP_ENCODE_CTX* ctx = NULL;
- WOLFSSL_ENTER("wolfSSL_EVP_ENCODE_CTX_new");
- ctx = (WOLFSSL_EVP_ENCODE_CTX*)XMALLOC( sizeof(WOLFSSL_EVP_ENCODE_CTX),
- NULL, DYNAMIC_TYPE_OPENSSL );
- if (ctx != NULL) {
- XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_ENCODE_CTX) );
- ctx->heap = NULL;
- return ctx;
- }
- return NULL;
- }
- /* wolfSSL_EVP_ENCODE_CTX_free frees specified WOLFSSL_EVP_ENCODE_CTX struct.
- */
- void wolfSSL_EVP_ENCODE_CTX_free(WOLFSSL_EVP_ENCODE_CTX* ctx)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_ENCODE_CTX_free");
- if (ctx != NULL) {
- XFREE(ctx, ctx->heap, DYNAMIC_TYPE_OPENSSL);
- }
- }
- #endif /* WOLFSSL_BASE64_ENCODE || WOLFSSL_BASE64_DECODE */
- #if defined(WOLFSSL_BASE64_ENCODE)
- /* Assume that out has enough space */
- int wolfSSL_EVP_EncodeBlock(unsigned char *out, const unsigned char *in,
- int inLen)
- {
- word32 ret = (word32)-1;
- WOLFSSL_ENTER("wolfSSL_EVP_EncodeBlock");
- if (out == NULL || in == NULL)
- return WOLFSSL_FATAL_ERROR;
- if (Base64_Encode(in, inLen, out, &ret) == 0)
- return (int)ret;
- else
- return WOLFSSL_FATAL_ERROR;
- }
- /* Assume that out has enough space */
- int wolfSSL_EVP_DecodeBlock(unsigned char *out, const unsigned char *in,
- int inLen)
- {
- word32 ret = (word32)-1;
- WOLFSSL_ENTER("wolfSSL_EVP_DecodeBlock");
- if (out == NULL || in == NULL)
- return WOLFSSL_FATAL_ERROR;
- if (Base64_Decode(in, inLen, out, &ret) == 0)
- return (int)ret;
- else
- return WOLFSSL_FATAL_ERROR;
- }
- /* wolfSSL_EVP_EncodeInit initializes specified WOLFSSL_EVP_ENCODE_CTX object
- * for the subsequent wolfSSL_EVP_EncodeUpdate.
- */
- void wolfSSL_EVP_EncodeInit(WOLFSSL_EVP_ENCODE_CTX* ctx)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_EncodeInit");
- /* clean up ctx */
- if (ctx != NULL) {
- ctx->remaining = 0;
- XMEMSET(ctx->data, 0, sizeof(ctx->data));
- }
- }
- /* wolfSSL_EVP_EncodeUpdate encodes the input data in 48-byte units
- * and outputs it to out. If less than 48 bytes of data remain, save it in
- * ctx. The data given in the subsequent wolfSSL_EVP_EncodeUpdate
- * is combined with the data stored in CTX and used for encoding.
- * Returns 1 on success, 0 on error.
- */
- int wolfSSL_EVP_EncodeUpdate(WOLFSSL_EVP_ENCODE_CTX* ctx,
- unsigned char* out, int* outl, const unsigned char* in, int inl)
- {
- int cpysz;
- int res;
- word32 outsz = 0;
- WOLFSSL_ENTER("wolfSSL_EVP_EncodeUpdate");
- if (ctx == NULL || out == NULL || in == NULL || outl == NULL)
- return 0;
- *outl = 0;
- /* if the remaining data exists in the ctx, add input data to them
- * to create a block(48bytes) for encoding
- */
- if (ctx->remaining > 0 && inl > 0) {
- cpysz = min((BASE64_ENCODE_BLOCK_SIZE - ctx->remaining), inl);
- XMEMCPY(ctx->data + ctx->remaining, in, cpysz);
- ctx->remaining += cpysz;
- in += cpysz;
- inl -= cpysz;
- /* check if a block for encoding exists in ctx.data, if so encode it */
- if (ctx->remaining >= BASE64_ENCODE_BLOCK_SIZE) {
- /* Base64_Encode asks the out buff size via the 4th param*/
- outsz = BASE64_ENCODE_RESULT_BLOCK_SIZE + 1;
- res = Base64_Encode(ctx->data, BASE64_ENCODE_BLOCK_SIZE, out,
- &outsz);
- if (res == 0) {
- ctx->remaining = 0;
- *outl = outsz;
- }
- else
- return 0; /* return with error */
- }
- else {
- /* could not create a block */
- *outl = 0;
- return 1;
- }
- }
- /* Here, there is no data left in ctx, so try processing the data of
- * the specified input data.
- */
- while (inl >= BASE64_ENCODE_BLOCK_SIZE) {
- outsz = BASE64_ENCODE_RESULT_BLOCK_SIZE + 1;/* 64 byte and one for LF*/
- res = Base64_Encode(in, BASE64_ENCODE_BLOCK_SIZE,out,&outsz);
- if (res == 0) {
- in += BASE64_ENCODE_BLOCK_SIZE;
- inl -= BASE64_ENCODE_BLOCK_SIZE;
- out += outsz;
- *outl += outsz;
- }
- else {
- *outl = 0;
- return 0;
- }
- }
- /* if remaining data exists, copy them into ctx for the next call*/
- if (inl > 0) {
- XMEMSET(ctx->data, 0, sizeof(ctx->data));
- XMEMCPY(ctx->data, in, inl);
- ctx->remaining = inl;
- }
- return 1; /* returns 1 on success, 0 on error */
- }
- /* wolfSSL_EVP_EncodeFinal encodes data in ctx and outputs to out.
- */
- void wolfSSL_EVP_EncodeFinal(WOLFSSL_EVP_ENCODE_CTX* ctx,
- unsigned char* out, int* outl)
- {
- word32 outsz = 0;
- int res;
- WOLFSSL_ENTER("wolfSSL_EVP_EncodeFinal");
- if (outl == NULL)
- return;
- if (ctx == NULL || out == NULL) {
- *outl = 0;
- return;
- }
- if (ctx->remaining >= BASE64_ENCODE_RESULT_BLOCK_SIZE) {
- *outl = 0;
- return;
- }
- /* process remaining data in ctx */
- outsz = BASE64_ENCODE_RESULT_BLOCK_SIZE + 1; /* 64 byte and one for LF*/
- res = Base64_Encode(ctx->data, ctx->remaining ,out, &outsz);
- if (res == 0)
- *outl = outsz;
- else
- *outl = 0;
- ctx->remaining = 0;
- XMEMSET(ctx->data, 0, sizeof(ctx->data));
- return;
- }
- #endif /* WOLFSSL_BASE64_ENCODE */
- #if defined(WOLFSSL_BASE64_DECODE)
- /* wolfSSL_EVP_DecodeInit initializes specified WOLFSSL_EVP_ENCODE_CTX struct
- * for subsequent wolfSSL_EVP_DecodeUpdate.
- */
- void wolfSSL_EVP_DecodeInit(WOLFSSL_EVP_ENCODE_CTX* ctx)
- {
- WOLFSSL_ENTER("wolfSSL_EVP_DecodeInit");
- /* clean up ctx */
- if (ctx != NULL) {
- ctx->remaining = 0;
- XMEMSET(ctx->data, 0, sizeof(ctx->data));
- }
- }
- /* wolfSSL_EVP_DecodeUpdate encodes the input data in 4-byte units
- * and outputs it to out. If less than 4 bytes of data remain, save it in
- * ctx. The data given in the subsequent wolfSSL_EVP_DecodeUpdate
- * is combined with the data stored in CTX and used for decoding.
- * Returns 1 or 0 on success, -1 on error. Return value 0 indicates that
- * clients should call wolfSSL_EVP_DecodeFinal as next call.
- */
- int wolfSSL_EVP_DecodeUpdate(WOLFSSL_EVP_ENCODE_CTX* ctx,
- unsigned char* out, int* outl, const unsigned char* in, int inl)
- {
- word32 outsz = 0;
- word32 j = 0;
- word32 inLen;
- int res;
- int pad = 0;
- int i;
- int cpySz;
- unsigned char c;
- int pad3 = 0;
- int pad4 = 0;
- byte e[4];
- WOLFSSL_ENTER("wolfSSL_EVP_DecodeUpdate");
- if (outl == NULL)
- return -1;
- if (ctx == NULL || out == NULL || in == NULL) {
- *outl = 0;
- return -1;
- }
- if (inl == 0) {
- *outl = 0;
- return 1;
- }
- inLen = inl;
- *outl = 0;
- /* if the remaining data exist in the ctx, add input data to them to create
- a block(4bytes) for decoding*/
- if ( ctx->remaining > 0 && inl > 0) {
- cpySz = min((BASE64_DECODE_BLOCK_SIZE - ctx->remaining), inl);
- for ( i = 0; cpySz > 0 && inLen > 0; i++) {
- if (Base64_SkipNewline(in, &inLen, &j) == ASN_INPUT_E) {
- return -1; /* detected an illegal char in input */
- }
- c = in[j++];
- if (c == '=')
- pad = 1;
- *(ctx->data + ctx->remaining + i) = c;
- inLen--;
- cpySz--;
- }
- outsz = sizeof(ctx->data);
- res = Base64_Decode( ctx->data, BASE64_DECODE_BLOCK_SIZE, out, &outsz);
- if (res == 0) {
- *outl += outsz;
- out += outsz;
- ctx->remaining = 0;
- XMEMSET(ctx->data, 0, sizeof(ctx->data));
- }
- else {
- *outl = 0;
- return -1; /* return with error */
- }
- }
- /* Base64_Decode is not a streaming process, so it processes
- * the input data and exits. If a line break or whitespace
- * character is found in the input data, it will be skipped,
- * but if the end point of the input data is reached as a result,
- * Base64_Decode will stop processing there. The data cleansing is
- * required before Base64_Decode so that the processing does not
- * stop within 4 bytes, which is the unit of Base64 decoding processing.
- * The logic that exists before calling Base64_Decode in a While Loop is
- * a data cleansing process that removes line breaks and whitespace.
- */
- while (inLen > 3) {
- if ((res = Base64_SkipNewline(in, &inLen, &j)) != 0) {
- if (res == BUFFER_E) {
- break;
- }
- else {
- *outl = 0;
- return -1;
- }
- }
- e[0] = in[j++];
- if (e[0] == '\0') {
- break;
- }
- inLen--;
- if ((res = Base64_SkipNewline(in, &inLen, &j)) != 0) {
- if (res == BUFFER_E) {
- break;
- }
- else {
- *outl = 0;
- return -1;
- }
- }
- e[1] = in[j++];
- inLen--;
- if ((res = Base64_SkipNewline(in, &inLen, &j)) != 0) {
- if (res == BUFFER_E) {
- break;
- }
- else {
- *outl = 0;
- return -1;
- }
- }
- e[2] = in[j++];
- inLen--;
- if ((res = Base64_SkipNewline(in, &inLen, &j)) != 0) {
- if (res == BUFFER_E) {
- break;
- }
- else {
- *outl = 0;
- return -1;
- }
- }
- e[3] = in[j++];
- inLen--;
- if (e[0] == '=')
- pad = 1;
- if (e[1] == '=')
- pad = 1;
- if (e[2] == '=') {
- pad = 1;
- pad3 = 1;
- }
- if (e[3] == '=') {
- pad = 1;
- pad4 = 1;
- }
- if (pad3 && !pad4) {
- *outl = 0;
- return -1;
- }
- /* decode four bytes */
- outsz = sizeof(ctx->data);
- res = Base64_Decode( e, BASE64_DECODE_BLOCK_SIZE, out, &outsz);
- if (res < 0) {
- *outl = 0;
- return -1;
- }
- *outl += outsz;
- out += outsz;
- }
- /* copy left data to ctx */
- if (inLen > 0) {
- XMEMSET(ctx->data, 0, sizeof(ctx->data));
- i = 0;
- while (inLen > 0) {
- c = in[j++];
- if (c== '\n' || c == '\r' || c == ' ') {
- inLen--;
- continue;
- }
- if (c == '=') {
- pad = 1;
- }
- ctx->data[i++] = c;
- ctx->remaining++;
- inLen--;
- }
- if (pad)
- return 0; /* indicates that clients should call DecodeFinal */
- else
- return 1;
- }
- /* if the last data is '\n', remove it */
- c = in[j - 1];
- if (c == '\n') {
- c = (in[j - 2]);
- if (c == '=')
- return 0;
- else
- return 1;
- }
- if (c == '=')
- return 0;
- else
- return 1;
- }
- /* wolfSSL_EVP_DecodeFinal decode remaining data in ctx
- * to outputs to out.
- * Returns 1 on success, -1 on failure.
- */
- int wolfSSL_EVP_DecodeFinal(WOLFSSL_EVP_ENCODE_CTX* ctx,
- unsigned char* out, int* outl)
- {
- word32 outsz = 0;
- word32 inLen;
- word32 j = 0;
- int res;
- WOLFSSL_ENTER("wolfSSL_EVP_DecodeFinal");
- if (outl == NULL)
- return -1;
- if (ctx == NULL || out == NULL ) {
- *outl = 0;
- return -1;
- }
- if (ctx->remaining > 0) {
- inLen = ctx->remaining;
- if ((res = Base64_SkipNewline(ctx->data, &inLen, &j)) != 0) {
- *outl = 0;
- if (res == BUFFER_E) /* means no valid data to decode in buffer */
- return 1; /* returns as success with no output */
- else
- return -1;
- }
- outsz = ctx->remaining;
- res = Base64_Decode(ctx->data, ctx->remaining, out, &outsz);
- if (res == 0) {
- *outl = outsz;
- return 1;
- }
- else {
- *outl = 0;
- return -1;
- }
- }
- else {
- *outl = 0;
- return 1;
- }
- }
- #endif /* WOLFSSL_BASE64_DECODE */
- #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
- #endif /* WOLFSSL_EVP_INCLUDED */
|