12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852 |
- /* tls.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>
- #ifndef WOLFCRYPT_ONLY
- #include <wolfssl/ssl.h>
- #include <wolfssl/internal.h>
- #include <wolfssl/error-ssl.h>
- #include <wolfssl/wolfcrypt/hash.h>
- #include <wolfssl/wolfcrypt/hmac.h>
- #include <wolfssl/wolfcrypt/kdf.h>
- #ifdef NO_INLINE
- #include <wolfssl/wolfcrypt/misc.h>
- #else
- #define WOLFSSL_MISC_INCLUDED
- #include <wolfcrypt/src/misc.c>
- #endif
- #ifdef HAVE_CURVE25519
- #include <wolfssl/wolfcrypt/curve25519.h>
- #endif
- #ifdef HAVE_CURVE448
- #include <wolfssl/wolfcrypt/curve448.h>
- #endif
- #ifdef HAVE_PQC
- #include <wolfssl/wolfcrypt/kyber.h>
- #ifdef WOLFSSL_WC_KYBER
- #include <wolfssl/wolfcrypt/wc_kyber.h>
- #elif defined(HAVE_LIBOQS)
- #include <oqs/kem.h>
- #include <wolfssl/wolfcrypt/ext_kyber.h>
- #elif defined(HAVE_PQM4)
- #include "api_kyber.h"
- #define PQM4_PUBLIC_KEY_LENGTH CRYPTO_PUBLICKEYBYTES
- #define PQM4_PRIVATE_KEY_LENGTH CRYPTO_SECRETKEYBYTES
- #define PQM4_SHARED_SECRET_LENGTH CRYPTO_BYTES
- #define PQM4_CIPHERTEXT_LENGTH CRYPTO_CIPHERTEXTBYTES
- #include <wolfssl/wolfcrypt/ext_kyber.h>
- #endif
- #endif
- #if defined(WOLFSSL_RENESAS_TSIP_TLS)
- #include <wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h>
- #endif
- #ifndef NO_TLS
- #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
- static int TLSX_KeyShare_IsSupported(int namedGroup);
- static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap);
- #endif
- #ifdef HAVE_SUPPORTED_CURVES
- static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions);
- #endif
- /* Digest enable checks */
- #ifdef NO_OLD_TLS /* TLS 1.2 only */
- #if defined(NO_SHA256) && !defined(WOLFSSL_SHA384) && \
- !defined(WOLFSSL_SHA512)
- #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
- #endif
- #else /* TLS 1.1 or older */
- #if defined(NO_MD5) && defined(NO_SHA)
- #error Must have SHA1 and MD5 enabled for old TLS
- #endif
- #endif
- #ifdef WOLFSSL_TLS13
- #if !defined(NO_DH) && \
- !defined(HAVE_FFDHE_2048) && !defined(HAVE_FFDHE_3072) && \
- !defined(HAVE_FFDHE_4096) && !defined(HAVE_FFDHE_6144) && \
- !defined(HAVE_FFDHE_8192)
- #error Please configure your TLS 1.3 DH key size using either: HAVE_FFDHE_2048, HAVE_FFDHE_3072, HAVE_FFDHE_4096, HAVE_FFDHE_6144 or HAVE_FFDHE_8192
- #endif
- #if !defined(NO_RSA) && !defined(WC_RSA_PSS)
- #error The build option WC_RSA_PSS is required for TLS 1.3 with RSA
- #endif
- #ifndef HAVE_TLS_EXTENSIONS
- #ifndef _MSC_VER
- #error "The build option HAVE_TLS_EXTENSIONS is required for TLS 1.3"
- #else
- #pragma message("Error: The build option HAVE_TLS_EXTENSIONS is required for TLS 1.3")
- #endif
- #endif
- #endif
- /* Warn if secrets logging is enabled */
- #if defined(SHOW_SECRETS) || defined(WOLFSSL_SSLKEYLOGFILE)
- #ifndef _MSC_VER
- #warning The SHOW_SECRETS and WOLFSSL_SSLKEYLOGFILE options should only be used for debugging and never in a production environment
- #else
- #pragma message("Warning: The SHOW_SECRETS and WOLFSSL_SSLKEYLOGFILE options should only be used for debugging and never in a production environment")
- #endif
- #endif
- /* Optional Pre-Master-Secret logging for Wireshark */
- #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SSLKEYLOGFILE)
- #ifndef WOLFSSL_SSLKEYLOGFILE_OUTPUT
- #define WOLFSSL_SSLKEYLOGFILE_OUTPUT "sslkeylog.log"
- #endif
- #endif
- #ifndef WOLFSSL_NO_TLS12
- #ifdef WOLFSSL_SHA384
- #define HSHASH_SZ WC_SHA384_DIGEST_SIZE
- #else
- #define HSHASH_SZ FINISHED_SZ
- #endif
- int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen)
- {
- int ret = 0;
- word32 hashSz = FINISHED_SZ;
- if (ssl == NULL || hash == NULL || hashLen == NULL || *hashLen < HSHASH_SZ)
- return BAD_FUNC_ARG;
- /* for constant timing perform these even if error */
- #ifndef NO_OLD_TLS
- ret |= wc_Md5GetHash(&ssl->hsHashes->hashMd5, hash);
- ret |= wc_ShaGetHash(&ssl->hsHashes->hashSha, &hash[WC_MD5_DIGEST_SIZE]);
- #endif
- if (IsAtLeastTLSv1_2(ssl)) {
- #ifndef NO_SHA256
- if (ssl->specs.mac_algorithm <= sha256_mac ||
- ssl->specs.mac_algorithm == blake2b_mac) {
- ret |= wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
- hashSz = WC_SHA256_DIGEST_SIZE;
- }
- #endif
- #ifdef WOLFSSL_SHA384
- if (ssl->specs.mac_algorithm == sha384_mac) {
- ret |= wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
- hashSz = WC_SHA384_DIGEST_SIZE;
- }
- #endif
- }
- *hashLen = hashSz;
- #ifdef WOLFSSL_CHECK_MEM_ZERO
- wc_MemZero_Add("TLS handshake hash", hash, hashSz);
- #endif
- if (ret != 0) {
- ret = BUILD_MSG_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- return ret;
- }
- int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
- {
- int ret;
- const byte* side = NULL;
- word32 hashSz = HSHASH_SZ;
- #if !defined(WOLFSSL_ASYNC_CRYPT) || defined(WC_ASYNC_NO_HASH)
- byte handshake_hash[HSHASH_SZ];
- #else
- WC_DECLARE_VAR(handshake_hash, byte, HSHASH_SZ, ssl->heap);
- if (handshake_hash == NULL)
- return MEMORY_E;
- #endif
- ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
- if (ret == 0) {
- if (XSTRNCMP((const char*)sender, (const char*)kTlsClientStr,
- SIZEOF_SENDER) == 0) {
- side = kTlsClientFinStr;
- }
- else if (XSTRNCMP((const char*)sender, (const char*)kTlsServerStr,
- SIZEOF_SENDER) == 0) {
- side = kTlsServerFinStr;
- }
- else {
- ret = BAD_FUNC_ARG;
- WOLFSSL_MSG("Unexpected sender value");
- }
- }
- if (ret == 0) {
- #ifdef WOLFSSL_HAVE_PRF
- #if !defined(NO_CERTS) && defined(HAVE_PK_CALLBACKS)
- if (ssl->ctx->TlsFinishedCb) {
- void* ctx = wolfSSL_GetTlsFinishedCtx(ssl);
- ret = ssl->ctx->TlsFinishedCb(ssl, side, handshake_hash, hashSz,
- (byte*)hashes, ctx);
- }
- if (!ssl->ctx->TlsFinishedCb || ret == PROTOCOLCB_UNAVAILABLE)
- #endif
- {
- PRIVATE_KEY_UNLOCK();
- ret = wc_PRF_TLS((byte*)hashes, TLS_FINISHED_SZ,
- ssl->arrays->masterSecret, SECRET_LEN, side,
- FINISHED_LABEL_SZ, handshake_hash, hashSz,
- IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
- ssl->heap, ssl->devId);
- PRIVATE_KEY_LOCK();
- }
- ForceZero(handshake_hash, hashSz);
- #else
- /* Pseudo random function must be enabled in the configuration. */
- ret = PRF_MISSING;
- WOLFSSL_ERROR_VERBOSE(ret);
- WOLFSSL_MSG("Pseudo-random function is not enabled");
- (void)side;
- (void)hashes;
- #endif
- }
- #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
- WC_FREE_VAR(handshake_hash, ssl->heap);
- #elif defined(WOLFSSL_CHECK_MEM_ZERO)
- wc_MemZero_Check(handshake_hash, HSHASH_SZ);
- #endif
- return ret;
- }
- #endif /* !WOLFSSL_NO_TLS12 */
- #ifndef NO_OLD_TLS
- #ifdef WOLFSSL_ALLOW_TLSV10
- ProtocolVersion MakeTLSv1(void)
- {
- ProtocolVersion pv;
- pv.major = SSLv3_MAJOR;
- pv.minor = TLSv1_MINOR;
- return pv;
- }
- #endif /* WOLFSSL_ALLOW_TLSV10 */
- ProtocolVersion MakeTLSv1_1(void)
- {
- ProtocolVersion pv;
- pv.major = SSLv3_MAJOR;
- pv.minor = TLSv1_1_MINOR;
- return pv;
- }
- #endif /* !NO_OLD_TLS */
- #ifndef WOLFSSL_NO_TLS12
- ProtocolVersion MakeTLSv1_2(void)
- {
- ProtocolVersion pv;
- pv.major = SSLv3_MAJOR;
- pv.minor = TLSv1_2_MINOR;
- return pv;
- }
- #endif /* !WOLFSSL_NO_TLS12 */
- #ifdef WOLFSSL_TLS13
- /* The TLS v1.3 protocol version.
- *
- * returns the protocol version data for TLS v1.3.
- */
- ProtocolVersion MakeTLSv1_3(void)
- {
- ProtocolVersion pv;
- pv.major = SSLv3_MAJOR;
- pv.minor = TLSv1_3_MINOR;
- return pv;
- }
- #endif
- #ifndef WOLFSSL_NO_TLS12
- #ifdef HAVE_EXTENDED_MASTER
- static const byte ext_master_label[EXT_MASTER_LABEL_SZ + 1] =
- "extended master secret";
- #endif
- static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
- static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion";
- static int _DeriveTlsKeys(byte* key_dig, word32 key_dig_len,
- const byte* ms, word32 msLen,
- const byte* sr, const byte* cr,
- int tls1_2, int hash_type,
- void* heap, int devId)
- {
- int ret;
- #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
- WC_DECLARE_VAR(seed, byte, SEED_LEN, heap);
- if (seed == NULL)
- return MEMORY_E;
- #else
- byte seed[SEED_LEN];
- #endif
- XMEMCPY(seed, sr, RAN_LEN);
- XMEMCPY(seed + RAN_LEN, cr, RAN_LEN);
- #ifdef WOLFSSL_HAVE_PRF
- PRIVATE_KEY_UNLOCK();
- ret = wc_PRF_TLS(key_dig, key_dig_len, ms, msLen, key_label, KEY_LABEL_SZ,
- seed, SEED_LEN, tls1_2, hash_type, heap, devId);
- PRIVATE_KEY_LOCK();
- #else
- /* Pseudo random function must be enabled in the configuration. */
- ret = PRF_MISSING;
- WOLFSSL_ERROR_VERBOSE(ret);
- WOLFSSL_MSG("Pseudo-random function is not enabled");
- (void)key_dig;
- (void)key_dig_len;
- (void)ms;
- (void)msLen;
- (void)tls1_2;
- (void)hash_type;
- (void)heap;
- (void)devId;
- (void)key_label;
- (void)master_label;
- #ifdef HAVE_EXTENDED_MASTER
- (void)ext_master_label;
- #endif
- #endif
- #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
- WC_FREE_VAR(seed, heap);
- #endif
- return ret;
- }
- /* External facing wrapper so user can call as well, 0 on success */
- int wolfSSL_DeriveTlsKeys(byte* key_dig, word32 key_dig_len,
- const byte* ms, word32 msLen,
- const byte* sr, const byte* cr,
- int tls1_2, int hash_type)
- {
- return _DeriveTlsKeys(key_dig, key_dig_len, ms, msLen, sr, cr, tls1_2,
- hash_type, NULL, INVALID_DEVID);
- }
- int DeriveTlsKeys(WOLFSSL* ssl)
- {
- int ret;
- int key_dig_len = 2 * ssl->specs.hash_size +
- 2 * ssl->specs.key_size +
- 2 * ssl->specs.iv_size;
- #ifdef WOLFSSL_SMALL_STACK
- byte* key_dig;
- #else
- byte key_dig[MAX_PRF_DIG];
- #endif
- #ifdef WOLFSSL_SMALL_STACK
- key_dig = (byte*)XMALLOC(MAX_PRF_DIG, ssl->heap, DYNAMIC_TYPE_DIGEST);
- if (key_dig == NULL) {
- return MEMORY_E;
- }
- #endif
- #if !defined(NO_CERTS) && defined(HAVE_PK_CALLBACKS)
- ret = PROTOCOLCB_UNAVAILABLE;
- if (ssl->ctx->GenSessionKeyCb) {
- void* ctx = wolfSSL_GetGenSessionKeyCtx(ssl);
- ret = ssl->ctx->GenSessionKeyCb(ssl, ctx);
- }
- if (!ssl->ctx->GenSessionKeyCb || ret == PROTOCOLCB_UNAVAILABLE)
- #endif
- ret = _DeriveTlsKeys(key_dig, key_dig_len,
- ssl->arrays->masterSecret, SECRET_LEN,
- ssl->arrays->serverRandom, ssl->arrays->clientRandom,
- IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
- ssl->heap, ssl->devId);
- if (ret == 0)
- ret = StoreKeys(ssl, key_dig, PROVISION_CLIENT_SERVER);
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST);
- #endif
- return ret;
- }
- static int _MakeTlsMasterSecret(byte* ms, word32 msLen,
- const byte* pms, word32 pmsLen,
- const byte* cr, const byte* sr,
- int tls1_2, int hash_type,
- void* heap, int devId)
- {
- int ret;
- #if !defined(WOLFSSL_ASYNC_CRYPT) || defined(WC_ASYNC_NO_HASH)
- byte seed[SEED_LEN];
- #else
- WC_DECLARE_VAR(seed, byte, SEED_LEN, heap);
- if (seed == NULL)
- return MEMORY_E;
- #endif
- XMEMCPY(seed, cr, RAN_LEN);
- XMEMCPY(seed + RAN_LEN, sr, RAN_LEN);
- #ifdef WOLFSSL_HAVE_PRF
- PRIVATE_KEY_UNLOCK();
- ret = wc_PRF_TLS(ms, msLen, pms, pmsLen, master_label, MASTER_LABEL_SZ,
- seed, SEED_LEN, tls1_2, hash_type, heap, devId);
- PRIVATE_KEY_LOCK();
- #else
- /* Pseudo random function must be enabled in the configuration. */
- ret = PRF_MISSING;
- WOLFSSL_MSG("Pseudo-random function is not enabled");
- (void)ms;
- (void)msLen;
- (void)pms;
- (void)pmsLen;
- (void)tls1_2;
- (void)hash_type;
- (void)heap;
- (void)devId;
- #endif
- #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
- WC_FREE_VAR(seed, heap);
- #endif
- return ret;
- }
- /* External facing wrapper so user can call as well, 0 on success */
- int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen,
- const byte* pms, word32 pmsLen,
- const byte* cr, const byte* sr,
- int tls1_2, int hash_type)
- {
- return _MakeTlsMasterSecret(ms, msLen, pms, pmsLen, cr, sr, tls1_2,
- hash_type, NULL, INVALID_DEVID);
- }
- #ifdef HAVE_EXTENDED_MASTER
- static int _MakeTlsExtendedMasterSecret(byte* ms, word32 msLen,
- const byte* pms, word32 pmsLen,
- const byte* sHash, word32 sHashLen,
- int tls1_2, int hash_type,
- void* heap, int devId)
- {
- int ret;
- #ifdef WOLFSSL_HAVE_PRF
- PRIVATE_KEY_UNLOCK();
- ret = wc_PRF_TLS(ms, msLen, pms, pmsLen, ext_master_label, EXT_MASTER_LABEL_SZ,
- sHash, sHashLen, tls1_2, hash_type, heap, devId);
- PRIVATE_KEY_LOCK();
- #else
- /* Pseudo random function must be enabled in the configuration. */
- ret = PRF_MISSING;
- WOLFSSL_MSG("Pseudo-random function is not enabled");
- (void)ms;
- (void)msLen;
- (void)pms;
- (void)pmsLen;
- (void)sHash;
- (void)sHashLen;
- (void)tls1_2;
- (void)hash_type;
- (void)heap;
- (void)devId;
- #endif
- return ret;
- }
- /* External facing wrapper so user can call as well, 0 on success */
- int wolfSSL_MakeTlsExtendedMasterSecret(byte* ms, word32 msLen,
- const byte* pms, word32 pmsLen,
- const byte* sHash, word32 sHashLen,
- int tls1_2, int hash_type)
- {
- return _MakeTlsExtendedMasterSecret(ms, msLen, pms, pmsLen, sHash, sHashLen,
- tls1_2, hash_type, NULL, INVALID_DEVID);
- }
- #endif /* HAVE_EXTENDED_MASTER */
- int MakeTlsMasterSecret(WOLFSSL* ssl)
- {
- int ret;
- #ifdef HAVE_EXTENDED_MASTER
- if (ssl->options.haveEMS) {
- word32 hashSz = HSHASH_SZ;
- #ifdef WOLFSSL_SMALL_STACK
- byte* handshake_hash = (byte*)XMALLOC(HSHASH_SZ, ssl->heap,
- DYNAMIC_TYPE_DIGEST);
- if (handshake_hash == NULL)
- return MEMORY_E;
- #else
- byte handshake_hash[HSHASH_SZ];
- #endif
- ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
- if (ret == 0) {
- ret = _MakeTlsExtendedMasterSecret(
- ssl->arrays->masterSecret, SECRET_LEN,
- ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
- handshake_hash, hashSz,
- IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
- ssl->heap, ssl->devId);
- ForceZero(handshake_hash, hashSz);
- }
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST);
- #elif defined(WOLFSSL_CHECK_MEM_ZERO)
- wc_MemZero_Check(handshake_hash, HSHASH_SZ);
- #endif
- }
- else
- #endif /* HAVE_EXTENDED_MASTER */
- {
- #if !defined(NO_CERTS) && defined(HAVE_PK_CALLBACKS)
- ret = PROTOCOLCB_UNAVAILABLE;
- if (ssl->ctx->GenMasterCb) {
- void* ctx = wolfSSL_GetGenMasterSecretCtx(ssl);
- ret = ssl->ctx->GenMasterCb(ssl, ctx);
- }
- if (!ssl->ctx->GenMasterCb || ret == PROTOCOLCB_UNAVAILABLE)
- #endif
- {
- ret = _MakeTlsMasterSecret(ssl->arrays->masterSecret,
- SECRET_LEN, ssl->arrays->preMasterSecret,
- ssl->arrays->preMasterSz, ssl->arrays->clientRandom,
- ssl->arrays->serverRandom, IsAtLeastTLSv1_2(ssl),
- ssl->specs.mac_algorithm, ssl->heap, ssl->devId);
- }
- }
- if (ret == 0) {
- #ifdef SHOW_SECRETS
- /* Wireshark Pre-Master-Secret Format:
- * CLIENT_RANDOM <clientrandom> <mastersecret>
- */
- const char* CLIENT_RANDOM_LABEL = "CLIENT_RANDOM";
- int i, pmsPos = 0;
- char pmsBuf[13 + 1 + 64 + 1 + 96 + 1 + 1];
- XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%s ",
- CLIENT_RANDOM_LABEL);
- pmsPos += XSTRLEN(CLIENT_RANDOM_LABEL) + 1;
- for (i = 0; i < RAN_LEN; i++) {
- XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%02x",
- ssl->arrays->clientRandom[i]);
- pmsPos += 2;
- }
- XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, " ");
- pmsPos += 1;
- for (i = 0; i < SECRET_LEN; i++) {
- XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%02x",
- ssl->arrays->masterSecret[i]);
- pmsPos += 2;
- }
- XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "\n");
- pmsPos += 1;
- /* print master secret */
- puts(pmsBuf);
- #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SSLKEYLOGFILE)
- {
- FILE* f = XFOPEN(WOLFSSL_SSLKEYLOGFILE_OUTPUT, "a");
- if (f != XBADFILE) {
- XFWRITE(pmsBuf, 1, pmsPos, f);
- XFCLOSE(f);
- }
- }
- #endif
- #endif /* SHOW_SECRETS */
- ret = DeriveTlsKeys(ssl);
- }
- return ret;
- }
- /* Used by EAP-TLS and EAP-TTLS to derive keying material from
- * the master_secret. */
- int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* msk, unsigned int len,
- const char* label)
- {
- int ret;
- #ifdef WOLFSSL_SMALL_STACK
- byte* seed;
- #else
- byte seed[SEED_LEN];
- #endif
- #ifdef WOLFSSL_SMALL_STACK
- seed = (byte*)XMALLOC(SEED_LEN, ssl->heap, DYNAMIC_TYPE_SEED);
- if (seed == NULL)
- return MEMORY_E;
- #endif
- /*
- * As per RFC-5281, the order of the client and server randoms is reversed
- * from that used by the TLS protocol to derive keys.
- */
- XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
- XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
- #ifdef WOLFSSL_HAVE_PRF
- PRIVATE_KEY_UNLOCK();
- ret = wc_PRF_TLS((byte*)msk, len, ssl->arrays->masterSecret, SECRET_LEN,
- (const byte *)label, (word32)XSTRLEN(label), seed, SEED_LEN,
- IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
- ssl->heap, ssl->devId);
- PRIVATE_KEY_LOCK();
- #else
- /* Pseudo random function must be enabled in the configuration. */
- ret = PRF_MISSING;
- WOLFSSL_MSG("Pseudo-random function is not enabled");
- (void)msk;
- (void)len;
- (void)label;
- #endif
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(seed, ssl->heap, DYNAMIC_TYPE_SEED);
- #endif
- return ret;
- }
- /* return HMAC digest type in wolfSSL format */
- int wolfSSL_GetHmacType(WOLFSSL* ssl)
- {
- if (ssl == NULL)
- return BAD_FUNC_ARG;
- switch (ssl->specs.mac_algorithm) {
- #ifndef NO_MD5
- case md5_mac:
- {
- return WC_MD5;
- }
- #endif
- #ifndef NO_SHA256
- case sha256_mac:
- {
- return WC_SHA256;
- }
- #endif
- #ifdef WOLFSSL_SHA384
- case sha384_mac:
- {
- return WC_SHA384;
- }
- #endif
- #ifndef NO_SHA
- case sha_mac:
- {
- return WC_SHA;
- }
- #endif
- #ifdef HAVE_BLAKE2
- case blake2b_mac:
- {
- return BLAKE2B_ID;
- }
- #endif
- default:
- {
- return WOLFSSL_FATAL_ERROR;
- }
- }
- }
- int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
- int verify)
- {
- if (ssl == NULL || inner == NULL)
- return BAD_FUNC_ARG;
- XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ);
- WriteSEQ(ssl, verify, inner);
- inner[SEQ_SZ] = (byte)content;
- inner[SEQ_SZ + ENUM_LEN] = ssl->version.major;
- inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor;
- c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ);
- return 0;
- }
- #ifndef WOLFSSL_AEAD_ONLY
- #if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS) && \
- !defined(HAVE_SELFTEST)
- /* Update the hash in the HMAC.
- *
- * hmac HMAC object.
- * data Data to be hashed.
- * sz Size of data to hash.
- * returns 0 on success, otherwise failure.
- */
- static int Hmac_HashUpdate(Hmac* hmac, const byte* data, word32 sz)
- {
- int ret = BAD_FUNC_ARG;
- switch (hmac->macType) {
- #ifndef NO_SHA
- case WC_SHA:
- ret = wc_ShaUpdate(&hmac->hash.sha, data, sz);
- break;
- #endif /* !NO_SHA */
- #ifndef NO_SHA256
- case WC_SHA256:
- ret = wc_Sha256Update(&hmac->hash.sha256, data, sz);
- break;
- #endif /* !NO_SHA256 */
- #ifdef WOLFSSL_SHA384
- case WC_SHA384:
- ret = wc_Sha384Update(&hmac->hash.sha384, data, sz);
- break;
- #endif /* WOLFSSL_SHA384 */
- #ifdef WOLFSSL_SHA512
- case WC_SHA512:
- ret = wc_Sha512Update(&hmac->hash.sha512, data, sz);
- break;
- #endif /* WOLFSSL_SHA512 */
- default:
- break;
- }
- return ret;
- }
- /* Finalize the hash but don't put the EOC, padding or length in.
- *
- * hmac HMAC object.
- * hash Hash result.
- * returns 0 on success, otherwise failure.
- */
- static int Hmac_HashFinalRaw(Hmac* hmac, unsigned char* hash)
- {
- int ret = BAD_FUNC_ARG;
- switch (hmac->macType) {
- #ifndef NO_SHA
- case WC_SHA:
- ret = wc_ShaFinalRaw(&hmac->hash.sha, hash);
- break;
- #endif /* !NO_SHA */
- #ifndef NO_SHA256
- case WC_SHA256:
- ret = wc_Sha256FinalRaw(&hmac->hash.sha256, hash);
- break;
- #endif /* !NO_SHA256 */
- #ifdef WOLFSSL_SHA384
- case WC_SHA384:
- ret = wc_Sha384FinalRaw(&hmac->hash.sha384, hash);
- break;
- #endif /* WOLFSSL_SHA384 */
- #ifdef WOLFSSL_SHA512
- case WC_SHA512:
- ret = wc_Sha512FinalRaw(&hmac->hash.sha512, hash);
- break;
- #endif /* WOLFSSL_SHA512 */
- default:
- break;
- }
- return ret;
- }
- /* Finalize the HMAC by performing outer hash.
- *
- * hmac HMAC object.
- * mac MAC result.
- * returns 0 on success, otherwise failure.
- */
- static int Hmac_OuterHash(Hmac* hmac, unsigned char* mac)
- {
- int ret = BAD_FUNC_ARG;
- wc_HashAlg hash;
- enum wc_HashType hashType = (enum wc_HashType)hmac->macType;
- int digestSz = wc_HashGetDigestSize(hashType);
- int blockSz = wc_HashGetBlockSize(hashType);
- if ((digestSz >= 0) && (blockSz >= 0)) {
- ret = wc_HashInit(&hash, hashType);
- }
- if (ret == 0) {
- ret = wc_HashUpdate(&hash, hashType, (byte*)hmac->opad,
- blockSz);
- if (ret == 0)
- ret = wc_HashUpdate(&hash, hashType, (byte*)hmac->innerHash,
- digestSz);
- if (ret == 0)
- ret = wc_HashFinal(&hash, hashType, mac);
- wc_HashFree(&hash, hashType);
- }
- return ret;
- }
- /* Calculate the HMAC of the header + message data.
- * Constant time implementation using wc_Sha*FinalRaw().
- *
- * hmac HMAC object.
- * digest MAC result.
- * in Message data.
- * sz Size of the message data.
- * header Constructed record header with length of handshake data.
- * returns 0 on success, otherwise failure.
- */
- static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,
- word32 sz, int macLen, byte* header)
- {
- byte lenBytes[8];
- int i, j;
- unsigned int k;
- int blockBits, blockMask;
- int lastBlockLen, extraLen, eocIndex;
- int blocks, safeBlocks, lenBlock, eocBlock;
- unsigned int maxLen;
- int blockSz, padSz;
- int ret;
- word32 realLen;
- byte extraBlock;
- switch (hmac->macType) {
- #ifndef NO_SHA
- case WC_SHA:
- blockSz = WC_SHA_BLOCK_SIZE;
- blockBits = 6;
- padSz = WC_SHA_BLOCK_SIZE - WC_SHA_PAD_SIZE + 1;
- break;
- #endif /* !NO_SHA */
- #ifndef NO_SHA256
- case WC_SHA256:
- blockSz = WC_SHA256_BLOCK_SIZE;
- blockBits = 6;
- padSz = WC_SHA256_BLOCK_SIZE - WC_SHA256_PAD_SIZE + 1;
- break;
- #endif /* !NO_SHA256 */
- #ifdef WOLFSSL_SHA384
- case WC_SHA384:
- blockSz = WC_SHA384_BLOCK_SIZE;
- blockBits = 7;
- padSz = WC_SHA384_BLOCK_SIZE - WC_SHA384_PAD_SIZE + 1;
- break;
- #endif /* WOLFSSL_SHA384 */
- #ifdef WOLFSSL_SHA512
- case WC_SHA512:
- blockSz = WC_SHA512_BLOCK_SIZE;
- blockBits = 7;
- padSz = WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE + 1;
- break;
- #endif /* WOLFSSL_SHA512 */
- default:
- return BAD_FUNC_ARG;
- }
- blockMask = blockSz - 1;
- /* Size of data to HMAC if padding length byte is zero. */
- maxLen = WOLFSSL_TLS_HMAC_INNER_SZ + sz - 1 - macLen;
- /* Complete data (including padding) has block for EOC and/or length. */
- extraBlock = ctSetLTE((maxLen + padSz) & blockMask, padSz);
- /* Total number of blocks for data including padding. */
- blocks = ((maxLen + blockSz - 1) >> blockBits) + extraBlock;
- /* Up to last 6 blocks can be hashed safely. */
- safeBlocks = blocks - 6;
- /* Length of message data. */
- realLen = maxLen - in[sz - 1];
- /* Number of message bytes in last block. */
- lastBlockLen = realLen & blockMask;
- /* Number of padding bytes in last block. */
- extraLen = ((blockSz * 2 - padSz - lastBlockLen) & blockMask) + 1;
- /* Number of blocks to create for hash. */
- lenBlock = (realLen + extraLen) >> blockBits;
- /* Block containing EOC byte. */
- eocBlock = realLen >> blockBits;
- /* Index of EOC byte in block. */
- eocIndex = realLen & blockMask;
- /* Add length of hmac's ipad to total length. */
- realLen += blockSz;
- /* Length as bits - 8 bytes bigendian. */
- c32toa(realLen >> ((sizeof(word32) * 8) - 3), lenBytes);
- c32toa(realLen << 3, lenBytes + sizeof(word32));
- ret = Hmac_HashUpdate(hmac, (unsigned char*)hmac->ipad, blockSz);
- if (ret != 0)
- return ret;
- XMEMSET(hmac->innerHash, 0, macLen);
- if (safeBlocks > 0) {
- ret = Hmac_HashUpdate(hmac, header, WOLFSSL_TLS_HMAC_INNER_SZ);
- if (ret != 0)
- return ret;
- ret = Hmac_HashUpdate(hmac, in, safeBlocks * blockSz -
- WOLFSSL_TLS_HMAC_INNER_SZ);
- if (ret != 0)
- return ret;
- }
- else
- safeBlocks = 0;
- XMEMSET(digest, 0, macLen);
- k = safeBlocks * blockSz;
- for (i = safeBlocks; i < blocks; i++) {
- unsigned char hashBlock[WC_MAX_BLOCK_SIZE];
- unsigned char isEocBlock = ctMaskEq(i, eocBlock);
- unsigned char isOutBlock = ctMaskEq(i, lenBlock);
- for (j = 0; j < blockSz; j++) {
- unsigned char atEoc = ctMaskEq(j, eocIndex) & isEocBlock;
- unsigned char pastEoc = ctMaskGT(j, eocIndex) & isEocBlock;
- unsigned char b = 0;
- if (k < WOLFSSL_TLS_HMAC_INNER_SZ)
- b = header[k];
- else if (k < maxLen)
- b = in[k - WOLFSSL_TLS_HMAC_INNER_SZ];
- k++;
- b = ctMaskSel(atEoc, 0x80, b);
- b &= (unsigned char)~(word32)pastEoc;
- b &= ((unsigned char)~(word32)isOutBlock) | isEocBlock;
- if (j >= blockSz - 8) {
- b = ctMaskSel(isOutBlock, lenBytes[j - (blockSz - 8)], b);
- }
- hashBlock[j] = b;
- }
- ret = Hmac_HashUpdate(hmac, hashBlock, blockSz);
- if (ret != 0)
- return ret;
- ret = Hmac_HashFinalRaw(hmac, hashBlock);
- if (ret != 0)
- return ret;
- for (j = 0; j < macLen; j++)
- ((unsigned char*)hmac->innerHash)[j] |= hashBlock[j] & isOutBlock;
- }
- ret = Hmac_OuterHash(hmac, digest);
- return ret;
- }
- #endif
- #if defined(WOLFSSL_NO_HASH_RAW) || defined(HAVE_FIPS) || \
- defined(HAVE_SELFTEST) || defined(HAVE_BLAKE2)
- /* Calculate the HMAC of the header + message data.
- * Constant time implementation using normal hashing operations.
- * Update-Final need to be constant time.
- *
- * hmac HMAC object.
- * digest MAC result.
- * in Message data.
- * sz Size of the message data.
- * header Constructed record header with length of handshake data.
- * returns 0 on success, otherwise failure.
- */
- static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in,
- word32 sz, byte* header)
- {
- byte dummy[WC_MAX_BLOCK_SIZE] = {0};
- int ret;
- word32 msgSz, blockSz, macSz, padSz, maxSz, realSz;
- word32 currSz, offset = 0;
- int msgBlocks, blocks, blockBits;
- int i;
- switch (hmac->macType) {
- #ifndef NO_SHA
- case WC_SHA:
- blockSz = WC_SHA_BLOCK_SIZE;
- blockBits = 6;
- macSz = WC_SHA_DIGEST_SIZE;
- padSz = WC_SHA_BLOCK_SIZE - WC_SHA_PAD_SIZE + 1;
- break;
- #endif /* !NO_SHA */
- #ifndef NO_SHA256
- case WC_SHA256:
- blockSz = WC_SHA256_BLOCK_SIZE;
- blockBits = 6;
- macSz = WC_SHA256_DIGEST_SIZE;
- padSz = WC_SHA256_BLOCK_SIZE - WC_SHA256_PAD_SIZE + 1;
- break;
- #endif /* !NO_SHA256 */
- #ifdef WOLFSSL_SHA384
- case WC_SHA384:
- blockSz = WC_SHA384_BLOCK_SIZE;
- blockBits = 7;
- macSz = WC_SHA384_DIGEST_SIZE;
- padSz = WC_SHA384_BLOCK_SIZE - WC_SHA384_PAD_SIZE + 1;
- break;
- #endif /* WOLFSSL_SHA384 */
- #ifdef WOLFSSL_SHA512
- case WC_SHA512:
- blockSz = WC_SHA512_BLOCK_SIZE;
- blockBits = 7;
- macSz = WC_SHA512_DIGEST_SIZE;
- padSz = WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE + 1;
- break;
- #endif /* WOLFSSL_SHA512 */
- #ifdef HAVE_BLAKE2
- case WC_HASH_TYPE_BLAKE2B:
- blockSz = BLAKE2B_BLOCKBYTES;
- blockBits = 7;
- macSz = BLAKE2B_256;
- padSz = 0;
- break;
- #endif /* HAVE_BLAKE2 */
- default:
- return BAD_FUNC_ARG;
- }
- msgSz = sz - (1 + in[sz - 1] + macSz);
- /* Make negative result 0 */
- msgSz &= ~(0 - (msgSz >> 31));
- realSz = WOLFSSL_TLS_HMAC_INNER_SZ + msgSz;
- maxSz = WOLFSSL_TLS_HMAC_INNER_SZ + (sz - 1) - macSz;
- /* Calculate #blocks processed in HMAC for max and real data. */
- blocks = maxSz >> blockBits;
- blocks += ((maxSz + padSz) % blockSz) < padSz;
- msgBlocks = realSz >> blockBits;
- /* #Extra blocks to process. */
- blocks -= msgBlocks + ((((realSz + padSz) % blockSz) < padSz) ? 1 : 0);
- /* Calculate whole blocks. */
- msgBlocks--;
- ret = wc_HmacUpdate(hmac, header, WOLFSSL_TLS_HMAC_INNER_SZ);
- if (ret == 0) {
- /* Fill the rest of the block with any available data. */
- currSz = ctMaskLT(msgSz, blockSz) & msgSz;
- currSz |= ctMaskGTE(msgSz, blockSz) & blockSz;
- currSz -= WOLFSSL_TLS_HMAC_INNER_SZ;
- currSz &= ~(0 - (currSz >> 31));
- ret = wc_HmacUpdate(hmac, in, currSz);
- offset = currSz;
- }
- if (ret == 0) {
- /* Do the hash operations on a block basis. */
- for (i = 0; i < msgBlocks; i++, offset += blockSz) {
- ret = wc_HmacUpdate(hmac, in + offset, blockSz);
- if (ret != 0)
- break;
- }
- }
- if (ret == 0)
- ret = wc_HmacUpdate(hmac, in + offset, msgSz - offset);
- if (ret == 0)
- ret = wc_HmacFinal(hmac, digest);
- if (ret == 0) {
- /* Do the dummy hash operations. Do at least one. */
- for (i = 0; i < blocks + 1; i++) {
- ret = wc_HmacUpdate(hmac, dummy, blockSz);
- if (ret != 0)
- break;
- }
- }
- return ret;
- }
- #endif
- int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
- int content, int verify, int epochOrder)
- {
- Hmac hmac;
- byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
- int ret = 0;
- const byte* macSecret = NULL;
- word32 hashSz = 0;
- if (ssl == NULL)
- return BAD_FUNC_ARG;
- #ifdef HAVE_TRUNCATED_HMAC
- hashSz = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
- : ssl->specs.hash_size;
- #else
- hashSz = ssl->specs.hash_size;
- #endif
- #ifdef HAVE_FUZZER
- /* Fuzz "in" buffer with sz to be used in HMAC algorithm */
- if (ssl->fuzzerCb) {
- if (verify && padSz >= 0) {
- ssl->fuzzerCb(ssl, in, sz + hashSz + padSz + 1, FUZZ_HMAC,
- ssl->fuzzerCtx);
- }
- else {
- ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
- }
- }
- #endif
- if (!ssl->options.dtls)
- wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
- else
- wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, epochOrder);
- ret = wc_HmacInit(&hmac, ssl->heap, ssl->devId);
- if (ret != 0)
- return ret;
- #ifdef WOLFSSL_DTLS
- if (ssl->options.dtls)
- macSecret = wolfSSL_GetDtlsMacSecret(ssl, verify, epochOrder);
- else
- macSecret = wolfSSL_GetMacSecret(ssl, verify);
- #else
- macSecret = wolfSSL_GetMacSecret(ssl, verify);
- #endif
- ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
- macSecret,
- ssl->specs.hash_size);
- if (ret == 0) {
- /* Constant time verification required. */
- if (verify && padSz >= 0) {
- #if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS) && \
- !defined(HAVE_SELFTEST)
- #ifdef HAVE_BLAKE2
- if (wolfSSL_GetHmacType(ssl) == WC_HASH_TYPE_BLAKE2B) {
- ret = Hmac_UpdateFinal(&hmac, digest, in,
- sz + hashSz + padSz + 1, myInner);
- }
- else
- #endif
- {
- ret = Hmac_UpdateFinal_CT(&hmac, digest, in,
- sz + hashSz + padSz + 1, hashSz, myInner);
- }
- #else
- ret = Hmac_UpdateFinal(&hmac, digest, in, sz + hashSz + padSz + 1,
- myInner);
- #endif
- }
- else {
- ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
- if (ret == 0)
- ret = wc_HmacUpdate(&hmac, in, sz); /* content */
- if (ret == 0)
- ret = wc_HmacFinal(&hmac, digest);
- }
- }
- wc_HmacFree(&hmac);
- return ret;
- }
- #endif /* WOLFSSL_AEAD_ONLY */
- #endif /* !WOLFSSL_NO_TLS12 */
- #ifdef HAVE_TLS_EXTENSIONS
- /**
- * The TLSX semaphore is used to calculate the size of the extensions to be sent
- * from one peer to another.
- */
- /** Supports up to 72 flags. Increase as needed. */
- #define SEMAPHORE_SIZE 9
- /**
- * Converts the extension type (id) to an index in the semaphore.
- *
- * Official reference for TLS extension types:
- * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml
- *
- * Motivation:
- * Previously, we used the extension type itself as the index of that
- * extension in the semaphore as the extension types were declared
- * sequentially, but maintain a semaphore as big as the number of available
- * extensions is no longer an option since the release of renegotiation_info.
- *
- * How to update:
- * Assign extension types that extrapolate the number of available semaphores
- * to the first available index going backwards in the semaphore array.
- * When adding a new extension type that don't extrapolate the number of
- * available semaphores, check for a possible collision with with a
- * 'remapped' extension type.
- */
- static WC_INLINE word16 TLSX_ToSemaphore(word16 type)
- {
- switch (type) {
- case TLSX_RENEGOTIATION_INFO: /* 0xFF01 */
- return 63;
- #ifdef WOLFSSL_QUIC
- case TLSX_KEY_QUIC_TP_PARAMS_DRAFT: /* 0xffa5 */
- return 64;
- #endif
- default:
- if (type > 62) {
- /* This message SHOULD only happens during the adding of
- new TLS extensions in which its IANA number overflows
- the current semaphore's range, or if its number already
- is assigned to be used by another extension.
- Use this check value for the new extension and decrement
- the check value by one. */
- WOLFSSL_MSG("### TLSX semaphore collision or overflow detected!");
- }
- }
- return type;
- }
- /** Checks if a specific light (tls extension) is not set in the semaphore. */
- #define IS_OFF(semaphore, light) \
- (!(((semaphore)[(light) / 8] & (byte) (0x01 << ((light) % 8)))))
- /** Turn on a specific light (tls extension) in the semaphore. */
- /* the semaphore marks the extensions already written to the message */
- #define TURN_ON(semaphore, light) \
- ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
- /** Turn off a specific light (tls extension) in the semaphore. */
- #define TURN_OFF(semaphore, light) \
- ((semaphore)[(light) / 8] &= (byte) ~(0x01 << ((light) % 8)))
- /** Creates a new extension. */
- static TLSX* TLSX_New(TLSX_Type type, const void* data, void* heap)
- {
- TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), heap, DYNAMIC_TYPE_TLSX);
- (void)heap;
- if (extension) {
- extension->type = type;
- extension->data = (void*)data;
- extension->resp = 0;
- extension->next = NULL;
- }
- return extension;
- }
- /**
- * Creates a new extension and pushes it to the provided list.
- * Checks for duplicate extensions, keeps the newest.
- */
- int TLSX_Push(TLSX** list, TLSX_Type type, const void* data, void* heap)
- {
- TLSX* extension = TLSX_New(type, data, heap);
- if (extension == NULL)
- return MEMORY_E;
- /* pushes the new extension on the list. */
- extension->next = *list;
- *list = extension;
- /* remove duplicate extensions, there should be only one of each type. */
- do {
- if (extension->next && extension->next->type == type) {
- TLSX *next = extension->next;
- extension->next = next->next;
- next->next = NULL;
- TLSX_FreeAll(next, heap);
- /* there is no way to occur more than
- * two extensions of the same type.
- */
- break;
- }
- } while ((extension = extension->next));
- return 0;
- }
- #ifdef WOLFSSL_TLS13
- /**
- * Creates a new extension and prepend it to the provided list.
- * Checks for duplicate extensions, keeps the newest.
- */
- static int TLSX_Prepend(TLSX** list, TLSX_Type type, void* data, void* heap)
- {
- TLSX* extension = TLSX_New(type, data, heap);
- TLSX* curr = *list;
- if (extension == NULL)
- return MEMORY_E;
- /* remove duplicate extensions, there should be only one of each type. */
- while (curr && curr->next) {
- if (curr->next->type == type) {
- TLSX *next = curr->next;
- curr->next = next->next;
- next->next = NULL;
- TLSX_FreeAll(next, heap);
- }
- curr = curr->next;
- }
- if (curr)
- curr->next = extension;
- else
- *list = extension;
- return 0;
- }
- #endif /* WOLFSSL_TLS13 */
- #ifndef NO_WOLFSSL_CLIENT
- int TLSX_CheckUnsupportedExtension(WOLFSSL* ssl, TLSX_Type type);
- int TLSX_CheckUnsupportedExtension(WOLFSSL* ssl, TLSX_Type type)
- {
- TLSX *extension = TLSX_Find(ssl->extensions, type);
- if (!extension)
- extension = TLSX_Find(ssl->ctx->extensions, type);
- return extension == NULL;
- }
- int TLSX_HandleUnsupportedExtension(WOLFSSL* ssl);
- int TLSX_HandleUnsupportedExtension(WOLFSSL* ssl)
- {
- SendAlert(ssl, alert_fatal, unsupported_extension);
- WOLFSSL_ERROR_VERBOSE(UNSUPPORTED_EXTENSION);
- return UNSUPPORTED_EXTENSION;
- }
- #else
- #define TLSX_CheckUnsupportedExtension(ssl, type) 0
- #define TLSX_HandleUnsupportedExtension(ssl) 0
- #endif
- #if !defined(NO_WOLFSSL_SERVER) || defined(WOLFSSL_TLS13)
- /** Mark an extension to be sent back to the client. */
- static void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type)
- {
- TLSX *extension = TLSX_Find(ssl->extensions, type);
- if (extension)
- extension->resp = 1;
- }
- #endif
- /******************************************************************************/
- /* Application-Layer Protocol Negotiation */
- /******************************************************************************/
- #ifdef HAVE_ALPN
- /** Creates a new ALPN object, providing protocol name to use. */
- static ALPN* TLSX_ALPN_New(char *protocol_name, word16 protocol_nameSz,
- void* heap)
- {
- ALPN *alpn;
- WOLFSSL_ENTER("TLSX_ALPN_New");
- if (protocol_name == NULL ||
- protocol_nameSz > WOLFSSL_MAX_ALPN_PROTO_NAME_LEN) {
- WOLFSSL_MSG("Invalid arguments");
- return NULL;
- }
- alpn = (ALPN*)XMALLOC(sizeof(ALPN), heap, DYNAMIC_TYPE_TLSX);
- if (alpn == NULL) {
- WOLFSSL_MSG("Memory failure");
- return NULL;
- }
- alpn->next = NULL;
- alpn->negotiated = 0;
- alpn->options = 0;
- alpn->protocol_name = (char*)XMALLOC(protocol_nameSz + 1,
- heap, DYNAMIC_TYPE_TLSX);
- if (alpn->protocol_name == NULL) {
- WOLFSSL_MSG("Memory failure");
- XFREE(alpn, heap, DYNAMIC_TYPE_TLSX);
- return NULL;
- }
- XMEMCPY(alpn->protocol_name, protocol_name, protocol_nameSz);
- alpn->protocol_name[protocol_nameSz] = 0;
- (void)heap;
- return alpn;
- }
- /** Releases an ALPN object. */
- static void TLSX_ALPN_Free(ALPN *alpn, void* heap)
- {
- (void)heap;
- if (alpn == NULL)
- return;
- XFREE(alpn->protocol_name, heap, DYNAMIC_TYPE_TLSX);
- XFREE(alpn, heap, DYNAMIC_TYPE_TLSX);
- }
- /** Releases all ALPN objects in the provided list. */
- static void TLSX_ALPN_FreeAll(ALPN *list, void* heap)
- {
- ALPN* alpn;
- while ((alpn = list)) {
- list = alpn->next;
- TLSX_ALPN_Free(alpn, heap);
- }
- }
- /** Tells the buffered size of the ALPN objects in a list. */
- static word16 TLSX_ALPN_GetSize(ALPN *list)
- {
- ALPN* alpn;
- word16 length = OPAQUE16_LEN; /* list length */
- while ((alpn = list)) {
- list = alpn->next;
- length++; /* protocol name length is on one byte */
- length += (word16)XSTRLEN(alpn->protocol_name);
- }
- return length;
- }
- /** Writes the ALPN objects of a list in a buffer. */
- static word16 TLSX_ALPN_Write(ALPN *list, byte *output)
- {
- ALPN* alpn;
- word16 length = 0;
- word16 offset = OPAQUE16_LEN; /* list length offset */
- while ((alpn = list)) {
- list = alpn->next;
- length = (word16)XSTRLEN(alpn->protocol_name);
- /* protocol name length */
- output[offset++] = (byte)length;
- /* protocol name value */
- XMEMCPY(output + offset, alpn->protocol_name, length);
- offset += length;
- }
- /* writing list length */
- c16toa(offset - OPAQUE16_LEN, output);
- return offset;
- }
- /** Finds a protocol name in the provided ALPN list */
- static ALPN* TLSX_ALPN_Find(ALPN *list, char *protocol_name, word16 size)
- {
- ALPN *alpn;
- if (list == NULL || protocol_name == NULL)
- return NULL;
- alpn = list;
- while (alpn != NULL && (
- (word16)XSTRLEN(alpn->protocol_name) != size ||
- XSTRNCMP(alpn->protocol_name, protocol_name, size)))
- alpn = alpn->next;
- return alpn;
- }
- /** Set the ALPN matching client and server requirements */
- static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size,
- void* heap)
- {
- ALPN *alpn;
- int ret;
- if (extensions == NULL || data == NULL)
- return BAD_FUNC_ARG;
- alpn = TLSX_ALPN_New((char *)data, size, heap);
- if (alpn == NULL) {
- WOLFSSL_MSG("Memory failure");
- return MEMORY_E;
- }
- alpn->negotiated = 1;
- ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, (void*)alpn,
- heap);
- if (ret != 0) {
- TLSX_ALPN_Free(alpn, heap);
- return ret;
- }
- return WOLFSSL_SUCCESS;
- }
- static int ALPN_find_match(WOLFSSL *ssl, TLSX **pextension,
- const byte **psel, byte *psel_len,
- const byte *alpn_val, word16 alpn_val_len)
- {
- TLSX *extension;
- ALPN *alpn, *list;
- const byte *sel = NULL, *s;
- byte sel_len = 0, wlen;
- extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
- if (extension == NULL)
- extension = TLSX_Find(ssl->ctx->extensions,
- TLSX_APPLICATION_LAYER_PROTOCOL);
- /* No ALPN configured here */
- if (extension == NULL || extension->data == NULL) {
- *pextension = NULL;
- *psel = NULL;
- *psel_len = 0;
- return 0;
- }
- list = (ALPN*)extension->data;
- for (s = alpn_val;
- (s - alpn_val) < alpn_val_len;
- s += wlen) {
- wlen = *s++; /* bounds already checked on save */
- alpn = TLSX_ALPN_Find(list, (char*)s, wlen);
- if (alpn != NULL) {
- WOLFSSL_MSG("ALPN protocol match");
- sel = s,
- sel_len = wlen;
- break;
- }
- }
- if (sel == NULL) {
- WOLFSSL_MSG("No ALPN protocol match");
- /* do nothing if no protocol match between client and server and option
- is set to continue (like OpenSSL) */
- if (list->options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) {
- WOLFSSL_MSG("Continue on mismatch");
- }
- else {
- SendAlert(ssl, alert_fatal, no_application_protocol);
- WOLFSSL_ERROR_VERBOSE(UNKNOWN_ALPN_PROTOCOL_NAME_E);
- return UNKNOWN_ALPN_PROTOCOL_NAME_E;
- }
- }
- *pextension = extension;
- *psel = sel;
- *psel_len = sel_len;
- return 0;
- }
- int ALPN_Select(WOLFSSL *ssl)
- {
- TLSX *extension;
- const byte *sel = NULL;
- byte sel_len = 0;
- int r = 0;
- WOLFSSL_ENTER("ALPN_Select");
- if (ssl->alpn_peer_requested == NULL)
- return 0;
- #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
- if (ssl->alpnSelect != NULL && ssl->options.side == WOLFSSL_SERVER_END) {
- if (ssl->alpnSelect(ssl, &sel, &sel_len, ssl->alpn_peer_requested,
- ssl->alpn_peer_requested_length,
- ssl->alpnSelectArg) == 0) {
- WOLFSSL_MSG("ALPN protocol match");
- }
- else {
- sel = NULL;
- sel_len = 0;
- }
- }
- #endif
- if (sel == NULL) {
- r = ALPN_find_match(ssl, &extension, &sel, &sel_len,
- ssl->alpn_peer_requested,
- ssl->alpn_peer_requested_length);
- if (r != 0)
- return r;
- }
- if (sel != NULL) {
- /* set the matching negotiated protocol */
- r = TLSX_SetALPN(&ssl->extensions, sel, sel_len, ssl->heap);
- if (r != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("TLSX_SetALPN failed");
- return BUFFER_ERROR;
- }
- /* reply to ALPN extension sent from peer */
- #ifndef NO_WOLFSSL_SERVER
- TLSX_SetResponse(ssl, TLSX_APPLICATION_LAYER_PROTOCOL);
- #endif
- }
- return 0;
- }
- /** Parses a buffer of ALPN extensions and set the first one matching
- * client and server requirements */
- static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, const byte *input, word16 length,
- byte isRequest)
- {
- word16 size = 0, offset = 0, wlen;
- int r = BUFFER_ERROR;
- const byte *s;
- if (OPAQUE16_LEN > length)
- return BUFFER_ERROR;
- ato16(input, &size);
- offset += OPAQUE16_LEN;
- /* validating alpn list length */
- if (size == 0 || length != OPAQUE16_LEN + size)
- return BUFFER_ERROR;
- /* validating length of entries before accepting */
- for (s = input + offset; (s - input) < size; s += wlen) {
- wlen = *s++;
- if (wlen == 0 || (s + wlen - input) > length)
- return BUFFER_ERROR;
- }
- if (isRequest) {
- /* keep the list sent by peer, if this is from a request. We
- * use it later in ALPN_Select() for evaluation. */
- if (ssl->alpn_peer_requested != NULL) {
- XFREE(ssl->alpn_peer_requested, ssl->heap, DYNAMIC_TYPE_ALPN);
- ssl->alpn_peer_requested_length = 0;
- }
- ssl->alpn_peer_requested = (byte *)XMALLOC(size, ssl->heap,
- DYNAMIC_TYPE_ALPN);
- if (ssl->alpn_peer_requested == NULL) {
- return MEMORY_ERROR;
- }
- ssl->alpn_peer_requested_length = size;
- XMEMCPY(ssl->alpn_peer_requested, (char*)input + offset, size);
- }
- else {
- /* a response, we should find the value in our config */
- const byte *sel = NULL;
- byte sel_len = 0;
- TLSX *extension = NULL;
- r = ALPN_find_match(ssl, &extension, &sel, &sel_len, input + offset, size);
- if (r != 0)
- return r;
- if (sel != NULL) {
- /* set the matching negotiated protocol */
- r = TLSX_SetALPN(&ssl->extensions, sel, sel_len, ssl->heap);
- if (r != WOLFSSL_SUCCESS) {
- WOLFSSL_MSG("TLSX_SetALPN failed");
- return BUFFER_ERROR;
- }
- }
- /* If we had nothing configured, the response is unexpected */
- else if (extension == NULL) {
- r = TLSX_HandleUnsupportedExtension(ssl);
- if (r != 0)
- return r;
- }
- }
- return 0;
- }
- /** Add a protocol name to the list of accepted usable ones */
- int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size, byte options,
- void* heap)
- {
- ALPN *alpn;
- TLSX *extension;
- int ret;
- if (extensions == NULL || data == NULL)
- return BAD_FUNC_ARG;
- alpn = TLSX_ALPN_New((char *)data, size, heap);
- if (alpn == NULL) {
- WOLFSSL_MSG("Memory failure");
- return MEMORY_E;
- }
- /* Set Options of ALPN */
- alpn->options = options;
- extension = TLSX_Find(*extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
- if (extension == NULL) {
- ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL,
- (void*)alpn, heap);
- if (ret != 0) {
- TLSX_ALPN_Free(alpn, heap);
- return ret;
- }
- }
- else {
- /* push new ALPN object to extension data. */
- alpn->next = (ALPN*)extension->data;
- extension->data = (void*)alpn;
- }
- return WOLFSSL_SUCCESS;
- }
- /** Get the protocol name set by the server */
- int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz)
- {
- TLSX *extension;
- ALPN *alpn;
- if (extensions == NULL || data == NULL || dataSz == NULL)
- return BAD_FUNC_ARG;
- extension = TLSX_Find(extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
- if (extension == NULL) {
- WOLFSSL_MSG("TLS extension not found");
- WOLFSSL_ERROR_VERBOSE(WOLFSSL_ALPN_NOT_FOUND);
- return WOLFSSL_ALPN_NOT_FOUND;
- }
- alpn = (ALPN *)extension->data;
- if (alpn == NULL) {
- WOLFSSL_MSG("ALPN extension not found");
- *data = NULL;
- *dataSz = 0;
- WOLFSSL_ERROR_VERBOSE(WOLFSSL_FATAL_ERROR);
- return WOLFSSL_FATAL_ERROR;
- }
- if (alpn->negotiated != 1) {
- /* consider as an error */
- if (alpn->options & WOLFSSL_ALPN_FAILED_ON_MISMATCH) {
- WOLFSSL_MSG("No protocol match with peer -> Failed");
- WOLFSSL_ERROR_VERBOSE(WOLFSSL_FATAL_ERROR);
- return WOLFSSL_FATAL_ERROR;
- }
- /* continue without negotiated protocol */
- WOLFSSL_MSG("No protocol match with peer -> Continue");
- WOLFSSL_ERROR_VERBOSE(WOLFSSL_ALPN_NOT_FOUND);
- return WOLFSSL_ALPN_NOT_FOUND;
- }
- if (alpn->next != NULL) {
- WOLFSSL_MSG("Only one protocol name must be accepted");
- WOLFSSL_ERROR_VERBOSE(WOLFSSL_FATAL_ERROR);
- return WOLFSSL_FATAL_ERROR;
- }
- *data = alpn->protocol_name;
- *dataSz = (word16)XSTRLEN((char*)*data);
- return WOLFSSL_SUCCESS;
- }
- #define ALPN_FREE_ALL TLSX_ALPN_FreeAll
- #define ALPN_GET_SIZE TLSX_ALPN_GetSize
- #define ALPN_WRITE TLSX_ALPN_Write
- #define ALPN_PARSE TLSX_ALPN_ParseAndSet
- #else /* HAVE_ALPN */
- #define ALPN_FREE_ALL(list, heap)
- #define ALPN_GET_SIZE(list) 0
- #define ALPN_WRITE(a, b) 0
- #define ALPN_PARSE(a, b, c, d) 0
- #endif /* HAVE_ALPN */
- /******************************************************************************/
- /* Server Name Indication */
- /******************************************************************************/
- #ifdef HAVE_SNI
- /** Creates a new SNI object. */
- static SNI* TLSX_SNI_New(byte type, const void* data, word16 size, void* heap)
- {
- SNI* sni = (SNI*)XMALLOC(sizeof(SNI), heap, DYNAMIC_TYPE_TLSX);
- (void)heap;
- if (sni) {
- sni->type = type;
- sni->next = NULL;
- #ifndef NO_WOLFSSL_SERVER
- sni->options = 0;
- sni->status = WOLFSSL_SNI_NO_MATCH;
- #endif
- switch (sni->type) {
- case WOLFSSL_SNI_HOST_NAME:
- sni->data.host_name = (char*)XMALLOC(size + 1, heap,
- DYNAMIC_TYPE_TLSX);
- if (sni->data.host_name) {
- XSTRNCPY(sni->data.host_name, (const char*)data, size);
- sni->data.host_name[size] = '\0';
- } else {
- XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
- sni = NULL;
- }
- break;
- default: /* invalid type */
- XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
- sni = NULL;
- }
- }
- return sni;
- }
- /** Releases a SNI object. */
- static void TLSX_SNI_Free(SNI* sni, void* heap)
- {
- if (sni) {
- switch (sni->type) {
- case WOLFSSL_SNI_HOST_NAME:
- XFREE(sni->data.host_name, heap, DYNAMIC_TYPE_TLSX);
- break;
- }
- XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
- }
- (void)heap;
- }
- /** Releases all SNI objects in the provided list. */
- static void TLSX_SNI_FreeAll(SNI* list, void* heap)
- {
- SNI* sni;
- while ((sni = list)) {
- list = sni->next;
- TLSX_SNI_Free(sni, heap);
- }
- }
- /** Tells the buffered size of the SNI objects in a list. */
- static word16 TLSX_SNI_GetSize(SNI* list)
- {
- SNI* sni;
- word16 length = OPAQUE16_LEN; /* list length */
- while ((sni = list)) {
- list = sni->next;
- length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
- switch (sni->type) {
- case WOLFSSL_SNI_HOST_NAME:
- length += (word16)XSTRLEN((char*)sni->data.host_name);
- break;
- }
- }
- return length;
- }
- /** Writes the SNI objects of a list in a buffer. */
- static word16 TLSX_SNI_Write(SNI* list, byte* output)
- {
- SNI* sni;
- word16 length = 0;
- word16 offset = OPAQUE16_LEN; /* list length offset */
- while ((sni = list)) {
- list = sni->next;
- output[offset++] = sni->type; /* sni type */
- switch (sni->type) {
- case WOLFSSL_SNI_HOST_NAME:
- length = (word16)XSTRLEN((char*)sni->data.host_name);
- c16toa(length, output + offset); /* sni length */
- offset += OPAQUE16_LEN;
- XMEMCPY(output + offset, sni->data.host_name, length);
- offset += length;
- break;
- }
- }
- c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
- return offset;
- }
- /** Finds a SNI object in the provided list. */
- static SNI* TLSX_SNI_Find(SNI *list, byte type)
- {
- SNI* sni = list;
- while (sni && sni->type != type)
- sni = sni->next;
- return sni;
- }
- #if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
- /** Sets the status of a SNI object. */
- static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status)
- {
- TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
- SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
- if (sni)
- sni->status = status;
- }
- #endif
- /** Gets the status of a SNI object. */
- byte TLSX_SNI_Status(TLSX* extensions, byte type)
- {
- TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
- SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
- if (sni)
- return sni->status;
- return 0;
- }
- /** Parses a buffer of SNI extensions. */
- static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte isRequest)
- {
- #ifndef NO_WOLFSSL_SERVER
- word16 size = 0;
- word16 offset = 0;
- int cacheOnly = 0;
- SNI *sni = NULL;
- byte type;
- int matchStat;
- byte matched;
- #endif
- TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
- if (!extension)
- extension = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
- if (!isRequest) {
- #ifndef NO_WOLFSSL_CLIENT
- if (!extension || !extension->data)
- return TLSX_HandleUnsupportedExtension(ssl);
- if (length > 0)
- return BUFFER_ERROR; /* SNI response MUST be empty. */
- /* This call enables wolfSSL_SNI_GetRequest() to be called in the
- * client side to fetch the used SNI. It will only work if the SNI
- * was set at the SSL object level. Right now we only support one
- * name type, WOLFSSL_SNI_HOST_NAME, but in the future, the
- * inclusion of other name types will turn this method inaccurate,
- * as the extension response doesn't contains information of which
- * name was accepted.
- */
- TLSX_SNI_SetStatus(ssl->extensions, WOLFSSL_SNI_HOST_NAME,
- WOLFSSL_SNI_REAL_MATCH);
- return 0;
- #endif
- }
- #ifndef NO_WOLFSSL_SERVER
- if (!extension || !extension->data) {
- /* This will keep SNI even though TLSX_UseSNI has not been called.
- * Enable it so that the received sni is available to functions
- * that use a custom callback when SNI is received.
- */
- #ifdef WOLFSSL_ALWAYS_KEEP_SNI
- cacheOnly = 1;
- #endif
- if (ssl->ctx->sniRecvCb) {
- cacheOnly = 1;
- }
- if (cacheOnly) {
- WOLFSSL_MSG("Forcing SSL object to store SNI parameter");
- }
- else {
- /* Skipping, SNI not enabled at server side. */
- return 0;
- }
- }
- if (OPAQUE16_LEN > length)
- return BUFFER_ERROR;
- ato16(input, &size);
- offset += OPAQUE16_LEN;
- /* validating sni list length */
- if (length != OPAQUE16_LEN + size || size == 0)
- return BUFFER_ERROR;
- /* SNI was badly specified and only one type is now recognized and allowed.
- * Only one SNI value per type (RFC6066), so, no loop. */
- type = input[offset++];
- if (type != WOLFSSL_SNI_HOST_NAME)
- return BUFFER_ERROR;
- if (offset + OPAQUE16_LEN > length)
- return BUFFER_ERROR;
- ato16(input + offset, &size);
- offset += OPAQUE16_LEN;
- if (offset + size != length || size == 0)
- return BUFFER_ERROR;
- if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type)))
- return 0; /* not using this type of SNI. */
- #ifdef WOLFSSL_TLS13
- /* Don't process the second ClientHello SNI extension if there
- * was problems with the first.
- */
- if (!cacheOnly && sni->status != 0)
- return 0;
- #endif
- matched = cacheOnly || (XSTRLEN(sni->data.host_name) == size &&
- XSTRNCMP(sni->data.host_name, (const char*)input + offset, size) == 0);
- if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) {
- int r = TLSX_UseSNI(&ssl->extensions, type, input + offset, size,
- ssl->heap);
- if (r != WOLFSSL_SUCCESS)
- return r; /* throws error. */
- if (cacheOnly) {
- WOLFSSL_MSG("Forcing storage of SNI, Fake match");
- matchStat = WOLFSSL_SNI_FORCE_KEEP;
- }
- else if (matched) {
- WOLFSSL_MSG("SNI did match!");
- matchStat = WOLFSSL_SNI_REAL_MATCH;
- }
- else {
- WOLFSSL_MSG("fake SNI match from ANSWER_ON_MISMATCH");
- matchStat = WOLFSSL_SNI_FAKE_MATCH;
- }
- TLSX_SNI_SetStatus(ssl->extensions, type, (byte)matchStat);
- if (!cacheOnly)
- TLSX_SetResponse(ssl, TLSX_SERVER_NAME);
- }
- else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) {
- SendAlert(ssl, alert_fatal, unrecognized_name);
- WOLFSSL_ERROR_VERBOSE(UNKNOWN_SNI_HOST_NAME_E);
- return UNKNOWN_SNI_HOST_NAME_E;
- }
- #else
- (void)input;
- #endif
- #if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
- (void)length;
- #endif
- return 0;
- }
- static int TLSX_SNI_VerifyParse(WOLFSSL* ssl, byte isRequest)
- {
- (void)ssl;
- if (isRequest) {
- #ifndef NO_WOLFSSL_SERVER
- TLSX* ctx_ext = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
- TLSX* ssl_ext = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
- SNI* ctx_sni = ctx_ext ? (SNI*)ctx_ext->data : NULL;
- SNI* ssl_sni = ssl_ext ? (SNI*)ssl_ext->data : NULL;
- SNI* sni = NULL;
- for (; ctx_sni; ctx_sni = ctx_sni->next) {
- if (ctx_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
- sni = TLSX_SNI_Find(ssl_sni, ctx_sni->type);
- if (sni) {
- if (sni->status != WOLFSSL_SNI_NO_MATCH)
- continue;
- /* if ssl level overrides ctx level, it is ok. */
- if ((sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) == 0)
- continue;
- }
- SendAlert(ssl, alert_fatal, handshake_failure);
- WOLFSSL_ERROR_VERBOSE(SNI_ABSENT_ERROR);
- return SNI_ABSENT_ERROR;
- }
- }
- for (; ssl_sni; ssl_sni = ssl_sni->next) {
- if (ssl_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
- if (ssl_sni->status != WOLFSSL_SNI_NO_MATCH)
- continue;
- SendAlert(ssl, alert_fatal, handshake_failure);
- WOLFSSL_ERROR_VERBOSE(SNI_ABSENT_ERROR);
- return SNI_ABSENT_ERROR;
- }
- }
- #endif /* NO_WOLFSSL_SERVER */
- }
- return 0;
- }
- int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size,
- void* heap)
- {
- TLSX* extension;
- SNI* sni = NULL;
- if (extensions == NULL || data == NULL)
- return BAD_FUNC_ARG;
- if ((sni = TLSX_SNI_New(type, data, size, heap)) == NULL)
- return MEMORY_E;
- extension = TLSX_Find(*extensions, TLSX_SERVER_NAME);
- if (!extension) {
- int ret = TLSX_Push(extensions, TLSX_SERVER_NAME, (void*)sni, heap);
- if (ret != 0) {
- TLSX_SNI_Free(sni, heap);
- return ret;
- }
- }
- else {
- /* push new SNI object to extension data. */
- sni->next = (SNI*)extension->data;
- extension->data = (void*)sni;
- /* remove duplicate SNI, there should be only one of each type. */
- do {
- if (sni->next && sni->next->type == type) {
- SNI* next = sni->next;
- sni->next = next->next;
- TLSX_SNI_Free(next, heap);
- /* there is no way to occur more than
- * two SNIs of the same type.
- */
- break;
- }
- } while ((sni = sni->next));
- }
- return WOLFSSL_SUCCESS;
- }
- #ifndef NO_WOLFSSL_SERVER
- /** Tells the SNI requested by the client. */
- word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data)
- {
- TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
- SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
- if (sni && sni->status != WOLFSSL_SNI_NO_MATCH) {
- switch (sni->type) {
- case WOLFSSL_SNI_HOST_NAME:
- if (data) {
- *data = sni->data.host_name;
- return (word16)XSTRLEN((char*)*data);
- }
- }
- }
- return 0;
- }
- /** Sets the options for a SNI object. */
- void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
- {
- TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
- SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
- if (sni)
- sni->options = options;
- }
- /** Retrieves a SNI request from a client hello buffer. */
- int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
- byte type, byte* sni, word32* inOutSz)
- {
- word32 offset = 0;
- word32 len32 = 0;
- word16 len16 = 0;
- if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST)
- return INCOMPLETE_DATA;
- /* TLS record header */
- if ((enum ContentType) clientHello[offset++] != handshake) {
- /* checking for SSLv2.0 client hello according to: */
- /* http://tools.ietf.org/html/rfc4346#appendix-E.1 */
- if ((enum HandShakeType) clientHello[++offset] == client_hello) {
- offset += ENUM_LEN + VERSION_SZ; /* skip version */
- ato16(clientHello + offset, &len16);
- offset += OPAQUE16_LEN;
- if (len16 % 3) /* cipher_spec_length must be multiple of 3 */
- return BUFFER_ERROR;
- ato16(clientHello + offset, &len16);
- /* Returning SNI_UNSUPPORTED do not increment offset here */
- if (len16 != 0) /* session_id_length must be 0 */
- return BUFFER_ERROR;
- WOLFSSL_ERROR_VERBOSE(SNI_UNSUPPORTED);
- return SNI_UNSUPPORTED;
- }
- return BUFFER_ERROR;
- }
- if (clientHello[offset++] != SSLv3_MAJOR)
- return BUFFER_ERROR;
- if (clientHello[offset++] < TLSv1_MINOR) {
- WOLFSSL_ERROR_VERBOSE(SNI_UNSUPPORTED);
- return SNI_UNSUPPORTED;
- }
- ato16(clientHello + offset, &len16);
- offset += OPAQUE16_LEN;
- if (offset + len16 > helloSz)
- return INCOMPLETE_DATA;
- /* Handshake header */
- if ((enum HandShakeType) clientHello[offset] != client_hello)
- return BUFFER_ERROR;
- c24to32(clientHello + offset + 1, &len32);
- offset += HANDSHAKE_HEADER_SZ;
- if (offset + len32 > helloSz)
- return BUFFER_ERROR;
- /* client hello */
- offset += VERSION_SZ + RAN_LEN; /* version, random */
- if (helloSz < offset + clientHello[offset])
- return BUFFER_ERROR;
- offset += ENUM_LEN + clientHello[offset]; /* skip session id */
- /* cypher suites */
- if (helloSz < offset + OPAQUE16_LEN)
- return BUFFER_ERROR;
- ato16(clientHello + offset, &len16);
- offset += OPAQUE16_LEN;
- if (helloSz < offset + len16)
- return BUFFER_ERROR;
- offset += len16; /* skip cypher suites */
- /* compression methods */
- if (helloSz < offset + 1)
- return BUFFER_ERROR;
- if (helloSz < offset + clientHello[offset])
- return BUFFER_ERROR;
- offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */
- /* extensions */
- if (helloSz < offset + OPAQUE16_LEN)
- return 0; /* no extensions in client hello. */
- ato16(clientHello + offset, &len16);
- offset += OPAQUE16_LEN;
- if (helloSz < offset + len16)
- return BUFFER_ERROR;
- while (len16 >= OPAQUE16_LEN + OPAQUE16_LEN) {
- word16 extType;
- word16 extLen;
- ato16(clientHello + offset, &extType);
- offset += OPAQUE16_LEN;
- ato16(clientHello + offset, &extLen);
- offset += OPAQUE16_LEN;
- if (helloSz < offset + extLen)
- return BUFFER_ERROR;
- if (extType != TLSX_SERVER_NAME) {
- offset += extLen; /* skip extension */
- } else {
- word16 listLen;
- ato16(clientHello + offset, &listLen);
- offset += OPAQUE16_LEN;
- if (helloSz < offset + listLen)
- return BUFFER_ERROR;
- while (listLen > ENUM_LEN + OPAQUE16_LEN) {
- byte sniType = clientHello[offset++];
- word16 sniLen;
- ato16(clientHello + offset, &sniLen);
- offset += OPAQUE16_LEN;
- if (helloSz < offset + sniLen)
- return BUFFER_ERROR;
- if (sniType != type) {
- offset += sniLen;
- listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
- continue;
- }
- *inOutSz = min(sniLen, *inOutSz);
- XMEMCPY(sni, clientHello + offset, *inOutSz);
- return WOLFSSL_SUCCESS;
- }
- }
- len16 -= min(2 * OPAQUE16_LEN + extLen, len16);
- }
- return len16 ? BUFFER_ERROR : 0;
- }
- #endif
- #define SNI_FREE_ALL TLSX_SNI_FreeAll
- #define SNI_GET_SIZE TLSX_SNI_GetSize
- #define SNI_WRITE TLSX_SNI_Write
- #define SNI_PARSE TLSX_SNI_Parse
- #define SNI_VERIFY_PARSE TLSX_SNI_VerifyParse
- #else
- #define SNI_FREE_ALL(list, heap)
- #define SNI_GET_SIZE(list) 0
- #define SNI_WRITE(a, b) 0
- #define SNI_PARSE(a, b, c, d) 0
- #define SNI_VERIFY_PARSE(a, b) 0
- #endif /* HAVE_SNI */
- /******************************************************************************/
- /* Trusted CA Key Indication */
- /******************************************************************************/
- #ifdef HAVE_TRUSTED_CA
- /** Creates a new TCA object. */
- static TCA* TLSX_TCA_New(byte type, const byte* id, word16 idSz, void* heap)
- {
- TCA* tca = (TCA*)XMALLOC(sizeof(TCA), heap, DYNAMIC_TYPE_TLSX);
- if (tca) {
- XMEMSET(tca, 0, sizeof(TCA));
- tca->type = type;
- switch (type) {
- case WOLFSSL_TRUSTED_CA_PRE_AGREED:
- break;
- #ifndef NO_SHA
- case WOLFSSL_TRUSTED_CA_KEY_SHA1:
- case WOLFSSL_TRUSTED_CA_CERT_SHA1:
- if (idSz == WC_SHA_DIGEST_SIZE &&
- (tca->id =
- (byte*)XMALLOC(idSz, heap, DYNAMIC_TYPE_TLSX))) {
- XMEMCPY(tca->id, id, idSz);
- tca->idSz = idSz;
- }
- else {
- XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
- tca = NULL;
- }
- break;
- #endif
- case WOLFSSL_TRUSTED_CA_X509_NAME:
- if (idSz > 0 &&
- (tca->id =
- (byte*)XMALLOC(idSz, heap, DYNAMIC_TYPE_TLSX))) {
- XMEMCPY(tca->id, id, idSz);
- tca->idSz = idSz;
- }
- else {
- XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
- tca = NULL;
- }
- break;
- default: /* invalid type */
- XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
- tca = NULL;
- }
- }
- (void)heap;
- return tca;
- }
- /** Releases a TCA object. */
- static void TLSX_TCA_Free(TCA* tca, void* heap)
- {
- (void)heap;
- if (tca) {
- if (tca->id)
- XFREE(tca->id, heap, DYNAMIC_TYPE_TLSX);
- XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
- }
- }
- /** Releases all TCA objects in the provided list. */
- static void TLSX_TCA_FreeAll(TCA* list, void* heap)
- {
- TCA* tca;
- while ((tca = list)) {
- list = tca->next;
- TLSX_TCA_Free(tca, heap);
- }
- }
- /** Tells the buffered size of the TCA objects in a list. */
- static word16 TLSX_TCA_GetSize(TCA* list)
- {
- TCA* tca;
- word16 length = OPAQUE16_LEN; /* list length */
- while ((tca = list)) {
- list = tca->next;
- length += ENUM_LEN; /* tca type */
- switch (tca->type) {
- case WOLFSSL_TRUSTED_CA_PRE_AGREED:
- break;
- case WOLFSSL_TRUSTED_CA_KEY_SHA1:
- case WOLFSSL_TRUSTED_CA_CERT_SHA1:
- length += tca->idSz;
- break;
- case WOLFSSL_TRUSTED_CA_X509_NAME:
- length += OPAQUE16_LEN + tca->idSz;
- break;
- }
- }
- return length;
- }
- /** Writes the TCA objects of a list in a buffer. */
- static word16 TLSX_TCA_Write(TCA* list, byte* output)
- {
- TCA* tca;
- word16 offset = OPAQUE16_LEN; /* list length offset */
- while ((tca = list)) {
- list = tca->next;
- output[offset++] = tca->type; /* tca type */
- switch (tca->type) {
- case WOLFSSL_TRUSTED_CA_PRE_AGREED:
- break;
- #ifndef NO_SHA
- case WOLFSSL_TRUSTED_CA_KEY_SHA1:
- case WOLFSSL_TRUSTED_CA_CERT_SHA1:
- if (tca->id != NULL) {
- XMEMCPY(output + offset, tca->id, tca->idSz);
- offset += tca->idSz;
- }
- else {
- /* ID missing. Set to an empty string. */
- c16toa(0, output + offset);
- offset += OPAQUE16_LEN;
- }
- break;
- #endif
- case WOLFSSL_TRUSTED_CA_X509_NAME:
- if (tca->id != NULL) {
- c16toa(tca->idSz, output + offset); /* tca length */
- offset += OPAQUE16_LEN;
- XMEMCPY(output + offset, tca->id, tca->idSz);
- offset += tca->idSz;
- }
- else {
- /* ID missing. Set to an empty string. */
- c16toa(0, output + offset);
- offset += OPAQUE16_LEN;
- }
- break;
- default:
- /* ID unknown. Set to an empty string. */
- c16toa(0, output + offset);
- offset += OPAQUE16_LEN;
- }
- }
- c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
- return offset;
- }
- #ifndef NO_WOLFSSL_SERVER
- static TCA* TLSX_TCA_Find(TCA *list, byte type, const byte* id, word16 idSz)
- {
- TCA* tca = list;
- while (tca && tca->type != type && type != WOLFSSL_TRUSTED_CA_PRE_AGREED &&
- idSz != tca->idSz && !XMEMCMP(id, tca->id, idSz))
- tca = tca->next;
- return tca;
- }
- #endif /* NO_WOLFSSL_SERVER */
- /** Parses a buffer of TCA extensions. */
- static int TLSX_TCA_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte isRequest)
- {
- #ifndef NO_WOLFSSL_SERVER
- word16 size = 0;
- word16 offset = 0;
- #endif
- TLSX *extension = TLSX_Find(ssl->extensions, TLSX_TRUSTED_CA_KEYS);
- if (!extension)
- extension = TLSX_Find(ssl->ctx->extensions, TLSX_TRUSTED_CA_KEYS);
- if (!isRequest) {
- #ifndef NO_WOLFSSL_CLIENT
- if (!extension || !extension->data)
- return TLSX_HandleUnsupportedExtension(ssl);
- if (length > 0)
- return BUFFER_ERROR; /* TCA response MUST be empty. */
- /* Set the flag that we're good for keys */
- TLSX_SetResponse(ssl, TLSX_TRUSTED_CA_KEYS);
- return 0;
- #endif
- }
- #ifndef NO_WOLFSSL_SERVER
- if (!extension || !extension->data) {
- /* Skipping, TCA not enabled at server side. */
- return 0;
- }
- if (OPAQUE16_LEN > length)
- return BUFFER_ERROR;
- ato16(input, &size);
- offset += OPAQUE16_LEN;
- /* validating tca list length */
- if (length != OPAQUE16_LEN + size)
- return BUFFER_ERROR;
- for (size = 0; offset < length; offset += size) {
- TCA *tca = NULL;
- byte type;
- const byte* id = NULL;
- word16 idSz = 0;
- if (offset + ENUM_LEN > length)
- return BUFFER_ERROR;
- type = input[offset++];
- switch (type) {
- case WOLFSSL_TRUSTED_CA_PRE_AGREED:
- break;
- #ifndef NO_SHA
- case WOLFSSL_TRUSTED_CA_KEY_SHA1:
- case WOLFSSL_TRUSTED_CA_CERT_SHA1:
- if (offset + WC_SHA_DIGEST_SIZE > length)
- return BUFFER_ERROR;
- idSz = WC_SHA_DIGEST_SIZE;
- id = input + offset;
- offset += idSz;
- break;
- #endif
- case WOLFSSL_TRUSTED_CA_X509_NAME:
- if (offset + OPAQUE16_LEN > length)
- return BUFFER_ERROR;
- ato16(input + offset, &idSz);
- offset += OPAQUE16_LEN;
- if ((offset > length) || (idSz > length - offset))
- return BUFFER_ERROR;
- id = input + offset;
- offset += idSz;
- break;
- default:
- WOLFSSL_ERROR_VERBOSE(TCA_INVALID_ID_TYPE);
- return TCA_INVALID_ID_TYPE;
- }
- /* Find the type/ID in the TCA list. */
- tca = TLSX_TCA_Find((TCA*)extension->data, type, id, idSz);
- if (tca != NULL) {
- /* Found it. Set the response flag and break out of the loop. */
- TLSX_SetResponse(ssl, TLSX_TRUSTED_CA_KEYS);
- break;
- }
- }
- #else
- (void)input;
- #endif
- return 0;
- }
- /* Checks to see if the server sent a response for the TCA. */
- static int TLSX_TCA_VerifyParse(WOLFSSL* ssl, byte isRequest)
- {
- (void)ssl;
- if (!isRequest) {
- #ifndef NO_WOLFSSL_CLIENT
- TLSX* extension = TLSX_Find(ssl->extensions, TLSX_TRUSTED_CA_KEYS);
- if (extension && !extension->resp) {
- SendAlert(ssl, alert_fatal, handshake_failure);
- WOLFSSL_ERROR_VERBOSE(TCA_ABSENT_ERROR);
- return TCA_ABSENT_ERROR;
- }
- #endif /* NO_WOLFSSL_CLIENT */
- }
- return 0;
- }
- int TLSX_UseTrustedCA(TLSX** extensions, byte type,
- const byte* id, word16 idSz, void* heap)
- {
- TLSX* extension;
- TCA* tca = NULL;
- if (extensions == NULL)
- return BAD_FUNC_ARG;
- if ((tca = TLSX_TCA_New(type, id, idSz, heap)) == NULL)
- return MEMORY_E;
- extension = TLSX_Find(*extensions, TLSX_TRUSTED_CA_KEYS);
- if (!extension) {
- int ret = TLSX_Push(extensions, TLSX_TRUSTED_CA_KEYS, (void*)tca, heap);
- if (ret != 0) {
- TLSX_TCA_Free(tca, heap);
- return ret;
- }
- }
- else {
- /* push new TCA object to extension data. */
- tca->next = (TCA*)extension->data;
- extension->data = (void*)tca;
- }
- return WOLFSSL_SUCCESS;
- }
- #define TCA_FREE_ALL TLSX_TCA_FreeAll
- #define TCA_GET_SIZE TLSX_TCA_GetSize
- #define TCA_WRITE TLSX_TCA_Write
- #define TCA_PARSE TLSX_TCA_Parse
- #define TCA_VERIFY_PARSE TLSX_TCA_VerifyParse
- #else /* HAVE_TRUSTED_CA */
- #define TCA_FREE_ALL(list, heap)
- #define TCA_GET_SIZE(list) 0
- #define TCA_WRITE(a, b) 0
- #define TCA_PARSE(a, b, c, d) 0
- #define TCA_VERIFY_PARSE(a, b) 0
- #endif /* HAVE_TRUSTED_CA */
- /******************************************************************************/
- /* Max Fragment Length Negotiation */
- /******************************************************************************/
- #ifdef HAVE_MAX_FRAGMENT
- static word16 TLSX_MFL_Write(byte* data, byte* output)
- {
- output[0] = data[0];
- return ENUM_LEN;
- }
- static int TLSX_MFL_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte isRequest)
- {
- if (length != ENUM_LEN)
- return BUFFER_ERROR;
- #ifdef WOLFSSL_OLD_UNSUPPORTED_EXTENSION
- (void) isRequest;
- #else
- if (!isRequest)
- if (TLSX_CheckUnsupportedExtension(ssl, TLSX_MAX_FRAGMENT_LENGTH))
- return TLSX_HandleUnsupportedExtension(ssl);
- #endif
- switch (*input) {
- case WOLFSSL_MFL_2_8 : ssl->max_fragment = 256; break;
- case WOLFSSL_MFL_2_9 : ssl->max_fragment = 512; break;
- case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
- case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
- case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
- case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
- default:
- SendAlert(ssl, alert_fatal, illegal_parameter);
- WOLFSSL_ERROR_VERBOSE(UNKNOWN_MAX_FRAG_LEN_E);
- return UNKNOWN_MAX_FRAG_LEN_E;
- }
- #ifndef NO_WOLFSSL_SERVER
- if (isRequest) {
- int ret = TLSX_UseMaxFragment(&ssl->extensions, *input, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret; /* throw error */
- TLSX_SetResponse(ssl, TLSX_MAX_FRAGMENT_LENGTH);
- }
- #endif
- return 0;
- }
- int TLSX_UseMaxFragment(TLSX** extensions, byte mfl, void* heap)
- {
- byte* data = NULL;
- int ret = 0;
- if (extensions == NULL || mfl < WOLFSSL_MFL_MIN || mfl > WOLFSSL_MFL_MAX)
- return BAD_FUNC_ARG;
- data = (byte*)XMALLOC(ENUM_LEN, heap, DYNAMIC_TYPE_TLSX);
- if (data == NULL)
- return MEMORY_E;
- data[0] = mfl;
- ret = TLSX_Push(extensions, TLSX_MAX_FRAGMENT_LENGTH, data, heap);
- if (ret != 0) {
- XFREE(data, heap, DYNAMIC_TYPE_TLSX);
- return ret;
- }
- return WOLFSSL_SUCCESS;
- }
- #define MFL_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX)
- #define MFL_GET_SIZE(data) ENUM_LEN
- #define MFL_WRITE TLSX_MFL_Write
- #define MFL_PARSE TLSX_MFL_Parse
- #else
- #define MFL_FREE_ALL(a, b)
- #define MFL_GET_SIZE(a) 0
- #define MFL_WRITE(a, b) 0
- #define MFL_PARSE(a, b, c, d) 0
- #endif /* HAVE_MAX_FRAGMENT */
- /******************************************************************************/
- /* Truncated HMAC */
- /******************************************************************************/
- #ifdef HAVE_TRUNCATED_HMAC
- static int TLSX_THM_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte isRequest)
- {
- if (length != 0 || input == NULL)
- return BUFFER_ERROR;
- if (!isRequest) {
- #ifndef WOLFSSL_OLD_UNSUPPORTED_EXTENSION
- if (TLSX_CheckUnsupportedExtension(ssl, TLSX_TRUNCATED_HMAC))
- return TLSX_HandleUnsupportedExtension(ssl);
- #endif
- }
- else {
- #ifndef NO_WOLFSSL_SERVER
- int ret = TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret; /* throw error */
- TLSX_SetResponse(ssl, TLSX_TRUNCATED_HMAC);
- #endif
- }
- ssl->truncated_hmac = 1;
- return 0;
- }
- int TLSX_UseTruncatedHMAC(TLSX** extensions, void* heap)
- {
- int ret = 0;
- if (extensions == NULL)
- return BAD_FUNC_ARG;
- ret = TLSX_Push(extensions, TLSX_TRUNCATED_HMAC, NULL, heap);
- if (ret != 0)
- return ret;
- return WOLFSSL_SUCCESS;
- }
- #define THM_PARSE TLSX_THM_Parse
- #else
- #define THM_PARSE(a, b, c, d) 0
- #endif /* HAVE_TRUNCATED_HMAC */
- /******************************************************************************/
- /* Certificate Status Request */
- /******************************************************************************/
- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
- static void TLSX_CSR_Free(CertificateStatusRequest* csr, void* heap)
- {
- switch (csr->status_type) {
- case WOLFSSL_CSR_OCSP:
- FreeOcspRequest(&csr->request.ocsp);
- break;
- }
- XFREE(csr, heap, DYNAMIC_TYPE_TLSX);
- (void)heap;
- }
- static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest)
- {
- word16 size = 0;
- /* shut up compiler warnings */
- (void) csr; (void) isRequest;
- #ifndef NO_WOLFSSL_CLIENT
- if (isRequest) {
- switch (csr->status_type) {
- case WOLFSSL_CSR_OCSP:
- size += ENUM_LEN + 2 * OPAQUE16_LEN;
- if (csr->request.ocsp.nonceSz)
- size += OCSP_NONCE_EXT_SZ;
- break;
- }
- }
- #endif
- #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
- if (!isRequest && csr->ssl->options.tls1_3)
- return OPAQUE8_LEN + OPAQUE24_LEN + csr->response.length;
- #endif
- return size;
- }
- static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
- byte isRequest)
- {
- /* shut up compiler warnings */
- (void) csr; (void) output; (void) isRequest;
- #ifndef NO_WOLFSSL_CLIENT
- if (isRequest) {
- word16 offset = 0;
- word16 length = 0;
- /* type */
- output[offset++] = csr->status_type;
- switch (csr->status_type) {
- case WOLFSSL_CSR_OCSP:
- /* responder id list */
- c16toa(0, output + offset);
- offset += OPAQUE16_LEN;
- /* request extensions */
- if (csr->request.ocsp.nonceSz)
- length = (word16)EncodeOcspRequestExtensions(
- &csr->request.ocsp,
- output + offset + OPAQUE16_LEN,
- OCSP_NONCE_EXT_SZ);
- c16toa(length, output + offset);
- offset += OPAQUE16_LEN + length;
- break;
- }
- return offset;
- }
- #endif
- #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
- if (!isRequest && csr->ssl->options.tls1_3) {
- word16 offset = 0;
- output[offset++] = csr->status_type;
- c32to24(csr->response.length, output + offset);
- offset += OPAQUE24_LEN;
- XMEMCPY(output + offset, csr->response.buffer, csr->response.length);
- offset += csr->response.length;
- return offset;
- }
- #endif
- return 0;
- }
- static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte isRequest)
- {
- int ret;
- #if !defined(NO_WOLFSSL_SERVER)
- byte status_type;
- word16 size = 0;
- #if defined(WOLFSSL_TLS13)
- DecodedCert* cert;
- #endif
- #endif
- #if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER) \
- && defined(WOLFSSL_TLS13)
- OcspRequest* request;
- TLSX* extension;
- CertificateStatusRequest* csr;
- #endif
- #if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_TLS13) \
- || !defined(NO_WOLFSSL_SERVER)
- word32 offset = 0;
- #endif
- #if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_TLS13)
- word32 resp_length;
- #endif
- /* shut up compiler warnings */
- (void) ssl; (void) input;
- if (!isRequest) {
- #ifndef NO_WOLFSSL_CLIENT
- extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
- csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
- if (!csr) {
- /* look at context level */
- extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST);
- csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
- if (!csr) /* unexpected extension */
- return TLSX_HandleUnsupportedExtension(ssl);
- /* enable extension at ssl level */
- ret = TLSX_UseCertificateStatusRequest(&ssl->extensions,
- csr->status_type, csr->options, ssl,
- ssl->heap, ssl->devId);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- switch (csr->status_type) {
- case WOLFSSL_CSR_OCSP:
- /* propagate nonce */
- if (csr->request.ocsp.nonceSz) {
- request =
- (OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions);
- if (request) {
- XMEMCPY(request->nonce, csr->request.ocsp.nonce,
- csr->request.ocsp.nonceSz);
- request->nonceSz = csr->request.ocsp.nonceSz;
- }
- }
- break;
- }
- }
- ssl->status_request = 1;
- #ifdef WOLFSSL_TLS13
- if (ssl->options.tls1_3) {
- /* Get the new extension potentially created above. */
- extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
- csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
- if (csr == NULL)
- return MEMORY_ERROR;
- ret = 0;
- if (OPAQUE8_LEN + OPAQUE24_LEN > length)
- ret = BUFFER_ERROR;
- if (ret == 0 && input[offset++] != WOLFSSL_CSR_OCSP) {
- ret = BAD_CERTIFICATE_STATUS_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- if (ret == 0) {
- c24to32(input + offset, &resp_length);
- offset += OPAQUE24_LEN;
- if (offset + resp_length != length)
- ret = BUFFER_ERROR;
- }
- if (ret == 0) {
- csr->response.buffer = (byte*)(input + offset);
- csr->response.length = resp_length;
- }
- return ret;
- }
- else
- #endif
- {
- /* extension_data MUST be empty. */
- return length ? BUFFER_ERROR : 0;
- }
- #endif
- }
- else {
- #ifndef NO_WOLFSSL_SERVER
- if (length == 0)
- return 0;
- status_type = input[offset++];
- switch (status_type) {
- case WOLFSSL_CSR_OCSP: {
- /* skip responder_id_list */
- if ((int)(length - offset) < OPAQUE16_LEN)
- return BUFFER_ERROR;
- ato16(input + offset, &size);
- offset += OPAQUE16_LEN + size;
- /* skip request_extensions */
- if ((int)(length - offset) < OPAQUE16_LEN)
- return BUFFER_ERROR;
- ato16(input + offset, &size);
- offset += OPAQUE16_LEN + size;
- if (offset > length)
- return BUFFER_ERROR;
- /* is able to send OCSP response? */
- if (SSL_CM(ssl) == NULL || !SSL_CM(ssl)->ocspStaplingEnabled)
- return 0;
- }
- break;
- /* unknown status type */
- default:
- return 0;
- }
- /* if using status_request and already sending it, skip this one */
- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
- if (ssl->status_request_v2)
- return 0;
- #endif
- /* accept the first good status_type and return */
- ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
- 0, ssl, ssl->heap, ssl->devId);
- if (ret != WOLFSSL_SUCCESS)
- return ret; /* throw error */
- #if defined(WOLFSSL_TLS13)
- if (ssl->options.tls1_3) {
- cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
- DYNAMIC_TYPE_DCERT);
- if (cert == NULL) {
- return MEMORY_E;
- }
- InitDecodedCert(cert, ssl->buffers.certificate->buffer,
- ssl->buffers.certificate->length, ssl->heap);
- ret = ParseCert(cert, CERT_TYPE, 1, SSL_CM(ssl));
- if (ret != 0 ) {
- XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
- return ret;
- }
- ret = TLSX_CSR_InitRequest(ssl->extensions, cert, ssl->heap);
- if (ret != 0 ) {
- XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
- return ret;
- }
- XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
- extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
- csr = extension ?
- (CertificateStatusRequest*)extension->data : NULL;
- if (csr == NULL)
- return MEMORY_ERROR;
- request = &csr->request.ocsp;
- ret = CreateOcspResponse(ssl, &request, &csr->response);
- if (ret != 0)
- return ret;
- if (csr->response.buffer)
- TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST);
- }
- else
- #endif
- TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST);
- ssl->status_request = status_type;
- #endif
- }
- return 0;
- }
- int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert, void* heap)
- {
- TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
- CertificateStatusRequest* csr = extension ?
- (CertificateStatusRequest*)extension->data : NULL;
- int ret = 0;
- if (csr) {
- switch (csr->status_type) {
- case WOLFSSL_CSR_OCSP: {
- byte nonce[MAX_OCSP_NONCE_SZ];
- int nonceSz = csr->request.ocsp.nonceSz;
- /* preserve nonce */
- XMEMCPY(nonce, csr->request.ocsp.nonce, nonceSz);
- if ((ret = InitOcspRequest(&csr->request.ocsp, cert, 0, heap))
- != 0)
- return ret;
- /* restore nonce */
- XMEMCPY(csr->request.ocsp.nonce, nonce, nonceSz);
- csr->request.ocsp.nonceSz = nonceSz;
- }
- break;
- }
- }
- return ret;
- }
- void* TLSX_CSR_GetRequest(TLSX* extensions)
- {
- TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
- CertificateStatusRequest* csr = extension ?
- (CertificateStatusRequest*)extension->data : NULL;
- if (csr) {
- switch (csr->status_type) {
- case WOLFSSL_CSR_OCSP:
- return &csr->request.ocsp;
- }
- }
- return NULL;
- }
- int TLSX_CSR_ForceRequest(WOLFSSL* ssl)
- {
- TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
- CertificateStatusRequest* csr = extension ?
- (CertificateStatusRequest*)extension->data : NULL;
- if (csr) {
- switch (csr->status_type) {
- case WOLFSSL_CSR_OCSP:
- if (SSL_CM(ssl)->ocspEnabled) {
- csr->request.ocsp.ssl = ssl;
- return CheckOcspRequest(SSL_CM(ssl)->ocsp,
- &csr->request.ocsp, NULL);
- }
- else {
- WOLFSSL_ERROR_VERBOSE(OCSP_LOOKUP_FAIL);
- return OCSP_LOOKUP_FAIL;
- }
- }
- }
- return 0;
- }
- int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type,
- byte options, WOLFSSL* ssl, void* heap,
- int devId)
- {
- CertificateStatusRequest* csr = NULL;
- int ret = 0;
- if (!extensions || status_type != WOLFSSL_CSR_OCSP)
- return BAD_FUNC_ARG;
- csr = (CertificateStatusRequest*)
- XMALLOC(sizeof(CertificateStatusRequest), heap, DYNAMIC_TYPE_TLSX);
- if (!csr)
- return MEMORY_E;
- ForceZero(csr, sizeof(CertificateStatusRequest));
- csr->status_type = status_type;
- csr->options = options;
- csr->ssl = ssl;
- switch (csr->status_type) {
- case WOLFSSL_CSR_OCSP:
- if (options & WOLFSSL_CSR_OCSP_USE_NONCE) {
- WC_RNG rng;
- #ifndef HAVE_FIPS
- ret = wc_InitRng_ex(&rng, heap, devId);
- #else
- ret = wc_InitRng(&rng);
- (void)devId;
- #endif
- if (ret == 0) {
- if (wc_RNG_GenerateBlock(&rng, csr->request.ocsp.nonce,
- MAX_OCSP_NONCE_SZ) == 0)
- csr->request.ocsp.nonceSz = MAX_OCSP_NONCE_SZ;
- wc_FreeRng(&rng);
- }
- }
- break;
- }
- if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr, heap)) != 0) {
- XFREE(csr, heap, DYNAMIC_TYPE_TLSX);
- return ret;
- }
- return WOLFSSL_SUCCESS;
- }
- #define CSR_FREE_ALL TLSX_CSR_Free
- #define CSR_GET_SIZE TLSX_CSR_GetSize
- #define CSR_WRITE TLSX_CSR_Write
- #define CSR_PARSE TLSX_CSR_Parse
- #else
- #define CSR_FREE_ALL(data, heap)
- #define CSR_GET_SIZE(a, b) 0
- #define CSR_WRITE(a, b, c) 0
- #define CSR_PARSE(a, b, c, d) 0
- #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
- /******************************************************************************/
- /* Certificate Status Request v2 */
- /******************************************************************************/
- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
- static void TLSX_CSR2_FreeAll(CertificateStatusRequestItemV2* csr2, void* heap)
- {
- CertificateStatusRequestItemV2* next;
- for (; csr2; csr2 = next) {
- next = csr2->next;
- switch (csr2->status_type) {
- case WOLFSSL_CSR2_OCSP:
- case WOLFSSL_CSR2_OCSP_MULTI:
- while(csr2->requests--)
- FreeOcspRequest(&csr2->request.ocsp[csr2->requests]);
- break;
- }
- XFREE(csr2, heap, DYNAMIC_TYPE_TLSX);
- }
- (void)heap;
- }
- static word16 TLSX_CSR2_GetSize(CertificateStatusRequestItemV2* csr2,
- byte isRequest)
- {
- word16 size = 0;
- /* shut up compiler warnings */
- (void) csr2; (void) isRequest;
- #ifndef NO_WOLFSSL_CLIENT
- if (isRequest) {
- CertificateStatusRequestItemV2* next;
- for (size = OPAQUE16_LEN; csr2; csr2 = next) {
- next = csr2->next;
- switch (csr2->status_type) {
- case WOLFSSL_CSR2_OCSP:
- case WOLFSSL_CSR2_OCSP_MULTI:
- size += ENUM_LEN + 3 * OPAQUE16_LEN;
- if (csr2->request.ocsp[0].nonceSz)
- size += OCSP_NONCE_EXT_SZ;
- break;
- }
- }
- }
- #endif
- return size;
- }
- static word16 TLSX_CSR2_Write(CertificateStatusRequestItemV2* csr2,
- byte* output, byte isRequest)
- {
- /* shut up compiler warnings */
- (void) csr2; (void) output; (void) isRequest;
- #ifndef NO_WOLFSSL_CLIENT
- if (isRequest) {
- word16 offset;
- word16 length;
- for (offset = OPAQUE16_LEN; csr2 != NULL; csr2 = csr2->next) {
- /* status_type */
- output[offset++] = csr2->status_type;
- /* request */
- switch (csr2->status_type) {
- case WOLFSSL_CSR2_OCSP:
- case WOLFSSL_CSR2_OCSP_MULTI:
- /* request_length */
- length = 2 * OPAQUE16_LEN;
- if (csr2->request.ocsp[0].nonceSz)
- length += OCSP_NONCE_EXT_SZ;
- c16toa(length, output + offset);
- offset += OPAQUE16_LEN;
- /* responder id list */
- c16toa(0, output + offset);
- offset += OPAQUE16_LEN;
- /* request extensions */
- length = 0;
- if (csr2->request.ocsp[0].nonceSz)
- length = (word16)EncodeOcspRequestExtensions(
- &csr2->request.ocsp[0],
- output + offset + OPAQUE16_LEN,
- OCSP_NONCE_EXT_SZ);
- c16toa(length, output + offset);
- offset += OPAQUE16_LEN + length;
- break;
- }
- }
- /* list size */
- c16toa(offset - OPAQUE16_LEN, output);
- return offset;
- }
- #endif
- return 0;
- }
- static int TLSX_CSR2_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte isRequest)
- {
- int ret;
- /* shut up compiler warnings */
- (void) ssl; (void) input;
- if (!isRequest) {
- #ifndef NO_WOLFSSL_CLIENT
- TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
- CertificateStatusRequestItemV2* csr2 = extension ?
- (CertificateStatusRequestItemV2*)extension->data : NULL;
- if (!csr2) {
- /* look at context level */
- extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST_V2);
- csr2 = extension ?
- (CertificateStatusRequestItemV2*)extension->data : NULL;
- if (!csr2) /* unexpected extension */
- return TLSX_HandleUnsupportedExtension(ssl);
- /* enable extension at ssl level */
- for (; csr2; csr2 = csr2->next) {
- ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
- csr2->status_type, csr2->options, ssl->heap,
- ssl->devId);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- switch (csr2->status_type) {
- case WOLFSSL_CSR2_OCSP:
- /* followed by */
- case WOLFSSL_CSR2_OCSP_MULTI:
- /* propagate nonce */
- if (csr2->request.ocsp[0].nonceSz) {
- OcspRequest* request =
- (OcspRequest*)TLSX_CSR2_GetRequest(ssl->extensions,
- csr2->status_type, 0);
- if (request) {
- XMEMCPY(request->nonce,
- csr2->request.ocsp[0].nonce,
- csr2->request.ocsp[0].nonceSz);
- request->nonceSz =
- csr2->request.ocsp[0].nonceSz;
- }
- }
- break;
- }
- }
- }
- ssl->status_request_v2 = 1;
- return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
- #endif
- }
- else {
- #ifndef NO_WOLFSSL_SERVER
- byte status_type;
- word16 request_length;
- word16 offset = 0;
- word16 size = 0;
- /* list size */
- if (offset + OPAQUE16_LEN >= length) {
- return BUFFER_E;
- }
- ato16(input + offset, &request_length);
- offset += OPAQUE16_LEN;
- if (length - OPAQUE16_LEN != request_length)
- return BUFFER_ERROR;
- while (length > offset) {
- if ((int)(length - offset) < ENUM_LEN + OPAQUE16_LEN)
- return BUFFER_ERROR;
- status_type = input[offset++];
- ato16(input + offset, &request_length);
- offset += OPAQUE16_LEN;
- if (length - offset < request_length)
- return BUFFER_ERROR;
- switch (status_type) {
- case WOLFSSL_CSR2_OCSP:
- case WOLFSSL_CSR2_OCSP_MULTI:
- /* skip responder_id_list */
- if ((int)(length - offset) < OPAQUE16_LEN)
- return BUFFER_ERROR;
- ato16(input + offset, &size);
- if (length - offset < size)
- return BUFFER_ERROR;
- offset += OPAQUE16_LEN + size;
- /* skip request_extensions */
- if ((int)(length - offset) < OPAQUE16_LEN)
- return BUFFER_ERROR;
- ato16(input + offset, &size);
- if (length - offset < size)
- return BUFFER_ERROR;
- offset += OPAQUE16_LEN + size;
- if (offset > length)
- return BUFFER_ERROR;
- /* is able to send OCSP response? */
- if (SSL_CM(ssl) == NULL
- || !SSL_CM(ssl)->ocspStaplingEnabled)
- continue;
- break;
- default:
- /* unknown status type, skipping! */
- offset += request_length;
- continue;
- }
- /* if using status_request and already sending it, remove it
- * and prefer to use the v2 version */
- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
- if (ssl->status_request) {
- ssl->status_request = 0;
- TLSX_Remove(&ssl->extensions, TLSX_STATUS_REQUEST, ssl->heap);
- }
- #endif
- /* TLS 1.3 servers MUST NOT act upon presence or information in
- * this extension (RFC 8448 Section 4.4.2.1).
- */
- if (!IsAtLeastTLSv1_3(ssl->version)) {
- /* accept the first good status_type and return */
- ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
- status_type, 0, ssl->heap, ssl->devId);
- if (ret != WOLFSSL_SUCCESS)
- return ret; /* throw error */
- TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST_V2);
- ssl->status_request_v2 = status_type;
- }
- return 0;
- }
- #endif
- }
- return 0;
- }
- int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer,
- void* heap)
- {
- TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
- CertificateStatusRequestItemV2* csr2 = extension ?
- (CertificateStatusRequestItemV2*)extension->data : NULL;
- int ret = 0;
- for (; csr2; csr2 = csr2->next) {
- switch (csr2->status_type) {
- case WOLFSSL_CSR2_OCSP:
- if (!isPeer || csr2->requests != 0)
- break;
- FALL_THROUGH; /* followed by */
- case WOLFSSL_CSR2_OCSP_MULTI: {
- if (csr2->requests < 1 + MAX_CHAIN_DEPTH) {
- byte nonce[MAX_OCSP_NONCE_SZ];
- int nonceSz = csr2->request.ocsp[0].nonceSz;
- /* preserve nonce, replicating nonce of ocsp[0] */
- XMEMCPY(nonce, csr2->request.ocsp[0].nonce, nonceSz);
- if ((ret = InitOcspRequest(
- &csr2->request.ocsp[csr2->requests], cert,
- 0, heap)) != 0)
- return ret;
- /* restore nonce */
- XMEMCPY(csr2->request.ocsp[csr2->requests].nonce,
- nonce, nonceSz);
- csr2->request.ocsp[csr2->requests].nonceSz = nonceSz;
- csr2->requests++;
- }
- }
- break;
- }
- }
- (void)cert;
- return ret;
- }
- void* TLSX_CSR2_GetRequest(TLSX* extensions, byte status_type, byte idx)
- {
- TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
- CertificateStatusRequestItemV2* csr2 = extension ?
- (CertificateStatusRequestItemV2*)extension->data : NULL;
- for (; csr2; csr2 = csr2->next) {
- if (csr2->status_type == status_type) {
- switch (csr2->status_type) {
- case WOLFSSL_CSR2_OCSP:
- /* followed by */
- case WOLFSSL_CSR2_OCSP_MULTI:
- /* requests are initialized in the reverse order */
- return idx < csr2->requests
- ? &csr2->request.ocsp[csr2->requests - idx - 1]
- : NULL;
- }
- }
- }
- return NULL;
- }
- int TLSX_CSR2_ForceRequest(WOLFSSL* ssl)
- {
- TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
- CertificateStatusRequestItemV2* csr2 = extension ?
- (CertificateStatusRequestItemV2*)extension->data : NULL;
- /* forces only the first one */
- if (csr2) {
- switch (csr2->status_type) {
- case WOLFSSL_CSR2_OCSP:
- /* followed by */
- case WOLFSSL_CSR2_OCSP_MULTI:
- if (SSL_CM(ssl)->ocspEnabled) {
- csr2->request.ocsp[0].ssl = ssl;
- return CheckOcspRequest(SSL_CM(ssl)->ocsp,
- &csr2->request.ocsp[0], NULL);
- }
- else {
- WOLFSSL_ERROR_VERBOSE(OCSP_LOOKUP_FAIL);
- return OCSP_LOOKUP_FAIL;
- }
- }
- }
- return 0;
- }
- int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type,
- byte options, void* heap, int devId)
- {
- TLSX* extension = NULL;
- CertificateStatusRequestItemV2* csr2 = NULL;
- int ret = 0;
- if (!extensions)
- return BAD_FUNC_ARG;
- if (status_type != WOLFSSL_CSR2_OCSP
- && status_type != WOLFSSL_CSR2_OCSP_MULTI)
- return BAD_FUNC_ARG;
- csr2 = (CertificateStatusRequestItemV2*)
- XMALLOC(sizeof(CertificateStatusRequestItemV2), heap, DYNAMIC_TYPE_TLSX);
- if (!csr2)
- return MEMORY_E;
- ForceZero(csr2, sizeof(CertificateStatusRequestItemV2));
- csr2->status_type = status_type;
- csr2->options = options;
- csr2->next = NULL;
- switch (csr2->status_type) {
- case WOLFSSL_CSR2_OCSP:
- case WOLFSSL_CSR2_OCSP_MULTI:
- if (options & WOLFSSL_CSR2_OCSP_USE_NONCE) {
- WC_RNG rng;
- #ifndef HAVE_FIPS
- ret = wc_InitRng_ex(&rng, heap, devId);
- #else
- ret = wc_InitRng(&rng);
- (void)devId;
- #endif
- if (ret == 0) {
- if (wc_RNG_GenerateBlock(&rng, csr2->request.ocsp[0].nonce,
- MAX_OCSP_NONCE_SZ) == 0)
- csr2->request.ocsp[0].nonceSz = MAX_OCSP_NONCE_SZ;
- wc_FreeRng(&rng);
- }
- }
- break;
- }
- /* append new item */
- if ((extension = TLSX_Find(*extensions, TLSX_STATUS_REQUEST_V2))) {
- CertificateStatusRequestItemV2* last =
- (CertificateStatusRequestItemV2*)extension->data;
- for (; last->next; last = last->next);
- last->next = csr2;
- }
- else if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST_V2, csr2,heap))) {
- XFREE(csr2, heap, DYNAMIC_TYPE_TLSX);
- return ret;
- }
- return WOLFSSL_SUCCESS;
- }
- #define CSR2_FREE_ALL TLSX_CSR2_FreeAll
- #define CSR2_GET_SIZE TLSX_CSR2_GetSize
- #define CSR2_WRITE TLSX_CSR2_Write
- #define CSR2_PARSE TLSX_CSR2_Parse
- #else
- #define CSR2_FREE_ALL(data, heap)
- #define CSR2_GET_SIZE(a, b) 0
- #define CSR2_WRITE(a, b, c) 0
- #define CSR2_PARSE(a, b, c, d) 0
- #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
- /******************************************************************************/
- /* Supported Elliptic Curves */
- /******************************************************************************/
- #ifdef HAVE_SUPPORTED_CURVES
- #if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448) \
- && !defined(HAVE_FFDHE) && !defined(HAVE_PQC)
- #error Elliptic Curves Extension requires Elliptic Curve Cryptography or liboqs groups. \
- Use --enable-ecc and/or --enable-liboqs in the configure script or \
- define HAVE_ECC. Alternatively use FFDHE for DH ciphersuites.
- #endif
- static int TLSX_SupportedCurve_New(SupportedCurve** curve, word16 name,
- void* heap)
- {
- if (curve == NULL)
- return BAD_FUNC_ARG;
- (void)heap;
- *curve = (SupportedCurve*)XMALLOC(sizeof(SupportedCurve), heap,
- DYNAMIC_TYPE_TLSX);
- if (*curve == NULL)
- return MEMORY_E;
- (*curve)->name = name;
- (*curve)->next = NULL;
- return 0;
- }
- static int TLSX_PointFormat_New(PointFormat** point, byte format, void* heap)
- {
- if (point == NULL)
- return BAD_FUNC_ARG;
- (void)heap;
- *point = (PointFormat*)XMALLOC(sizeof(PointFormat), heap,
- DYNAMIC_TYPE_TLSX);
- if (*point == NULL)
- return MEMORY_E;
- (*point)->format = format;
- (*point)->next = NULL;
- return 0;
- }
- static void TLSX_SupportedCurve_FreeAll(SupportedCurve* list, void* heap)
- {
- SupportedCurve* curve;
- while ((curve = list)) {
- list = curve->next;
- XFREE(curve, heap, DYNAMIC_TYPE_TLSX);
- }
- (void)heap;
- }
- static void TLSX_PointFormat_FreeAll(PointFormat* list, void* heap)
- {
- PointFormat* point;
- while ((point = list)) {
- list = point->next;
- XFREE(point, heap, DYNAMIC_TYPE_TLSX);
- }
- (void)heap;
- }
- static int TLSX_SupportedCurve_Append(SupportedCurve* list, word16 name,
- void* heap)
- {
- int ret = BAD_FUNC_ARG;
- while (list) {
- if (list->name == name) {
- ret = 0; /* curve already in use */
- break;
- }
- if (list->next == NULL) {
- ret = TLSX_SupportedCurve_New(&list->next, name, heap);
- break;
- }
- list = list->next;
- }
- return ret;
- }
- static int TLSX_PointFormat_Append(PointFormat* list, byte format, void* heap)
- {
- int ret = BAD_FUNC_ARG;
- while (list) {
- if (list->format == format) {
- ret = 0; /* format already in use */
- break;
- }
- if (list->next == NULL) {
- ret = TLSX_PointFormat_New(&list->next, format, heap);
- break;
- }
- list = list->next;
- }
- return ret;
- }
- #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
- #if defined(HAVE_FFDHE) && (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
- defined(HAVE_CURVE448))
- static void TLSX_SupportedCurve_ValidateRequest(const WOLFSSL* ssl,
- const byte* semaphore)
- {
- /* If all pre-defined parameter types for key exchange are supported then
- * always send SupportedGroups extension.
- */
- (void)ssl;
- (void)semaphore;
- }
- #else
- static void TLSX_SupportedCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
- {
- word16 i;
- for (i = 0; i < ssl->suites->suiteSz; i += 2) {
- if (ssl->suites->suites[i] == TLS13_BYTE)
- return;
- if ((ssl->suites->suites[i] == ECC_BYTE) ||
- (ssl->suites->suites[i] == ECDHE_PSK_BYTE) ||
- (ssl->suites->suites[i] == CHACHA_BYTE)) {
- #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
- defined(HAVE_CURVE448)
- return;
- #endif
- }
- #ifdef HAVE_FFDHE
- else {
- return;
- }
- #endif
- }
- /* turns semaphore on to avoid sending this extension. */
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
- }
- #endif
- /* Only send PointFormats if TLSv13, ECC or CHACHA cipher suite present.
- */
- static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
- {
- word16 i;
- for (i = 0; i < ssl->suites->suiteSz; i += 2) {
- if (ssl->suites->suites[i] == TLS13_BYTE)
- return;
- if ((ssl->suites->suites[i] == ECC_BYTE) ||
- (ssl->suites->suites[i] == ECDHE_PSK_BYTE) ||
- (ssl->suites->suites[i] == CHACHA_BYTE)) {
- #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
- defined(HAVE_CURVE448)
- return;
- #endif
- }
- }
- #ifdef HAVE_FFDHE
- (void)semaphore;
- return;
- #else
- /* turns semaphore on to avoid sending this extension. */
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
- #endif
- }
- #endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
- #ifndef NO_WOLFSSL_SERVER
- static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore)
- {
- #if defined(HAVE_FFDHE) || defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
- defined(HAVE_CURVE448)
- (void)semaphore;
- #endif
- if (ssl->options.cipherSuite0 == TLS13_BYTE)
- return;
- #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
- if (ssl->options.cipherSuite0 == ECC_BYTE ||
- ssl->options.cipherSuite0 == ECDHE_PSK_BYTE ||
- ssl->options.cipherSuite0 == CHACHA_BYTE) {
- return;
- }
- #endif
- /* turns semaphore on to avoid sending this extension. */
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
- }
- #endif /* !NO_WOLFSSL_SERVER */
- #ifndef NO_WOLFSSL_CLIENT
- static word16 TLSX_SupportedCurve_GetSize(SupportedCurve* list)
- {
- SupportedCurve* curve;
- word16 length = OPAQUE16_LEN; /* list length */
- while ((curve = list)) {
- list = curve->next;
- length += OPAQUE16_LEN; /* curve length */
- }
- return length;
- }
- #endif
- static word16 TLSX_PointFormat_GetSize(PointFormat* list)
- {
- PointFormat* point;
- word16 length = ENUM_LEN; /* list length */
- while ((point = list)) {
- list = point->next;
- length += ENUM_LEN; /* format length */
- }
- return length;
- }
- #ifndef NO_WOLFSSL_CLIENT
- static word16 TLSX_SupportedCurve_Write(SupportedCurve* list, byte* output)
- {
- word16 offset = OPAQUE16_LEN;
- while (list) {
- c16toa(list->name, output + offset);
- offset += OPAQUE16_LEN;
- list = list->next;
- }
- c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
- return offset;
- }
- #endif
- static word16 TLSX_PointFormat_Write(PointFormat* list, byte* output)
- {
- word16 offset = ENUM_LEN;
- while (list) {
- output[offset++] = list->format;
- list = list->next;
- }
- output[0] = (byte)(offset - ENUM_LEN);
- return offset;
- }
- #if !defined(NO_WOLFSSL_SERVER) || (defined(WOLFSSL_TLS13) && \
- !defined(WOLFSSL_NO_SERVER_GROUPS_EXT))
- static int TLSX_SupportedCurve_Parse(WOLFSSL* ssl, const byte* input,
- word16 length, byte isRequest)
- {
- word16 offset;
- word16 name;
- int ret;
- if(!isRequest && !IsAtLeastTLSv1_3(ssl->version)) {
- #ifdef WOLFSSL_ALLOW_SERVER_SC_EXT
- return 0;
- #else
- return BUFFER_ERROR; /* servers doesn't send this extension. */
- #endif
- }
- if (OPAQUE16_LEN > length || length % OPAQUE16_LEN)
- return BUFFER_ERROR;
- ato16(input, &offset);
- /* validating curve list length */
- if (length != OPAQUE16_LEN + offset)
- return BUFFER_ERROR;
- offset = OPAQUE16_LEN;
- if (offset == length)
- return 0;
- #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
- if (!isRequest) {
- TLSX* extension;
- SupportedCurve* curve;
- extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
- if (extension != NULL) {
- /* Replace client list with server list of supported groups. */
- curve = (SupportedCurve*)extension->data;
- extension->data = NULL;
- TLSX_SupportedCurve_FreeAll(curve, ssl->heap);
- ato16(input + offset, &name);
- offset += OPAQUE16_LEN;
- ret = TLSX_SupportedCurve_New(&curve, name, ssl->heap);
- if (ret != 0)
- return ret; /* throw error */
- extension->data = (void*)curve;
- }
- }
- #endif
- for (; offset < length; offset += OPAQUE16_LEN) {
- ato16(input + offset, &name);
- ret = TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
- /* If it is BAD_FUNC_ARG then it is a group we do not support, but
- * that is fine. */
- if (ret != WOLFSSL_SUCCESS && ret != BAD_FUNC_ARG) {
- return ret;
- }
- }
- return 0;
- }
- #endif
- #if !defined(NO_WOLFSSL_SERVER)
- #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
- /* Checks the priority of the groups on the server and set the supported groups
- * response if there is a group not advertised by the client that is preferred.
- *
- * ssl SSL/TLS object.
- * returns 0 on success, otherwise an error.
- */
- int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl)
- {
- int ret;
- TLSX* extension;
- TLSX* priority = NULL;
- TLSX* ext = NULL;
- word16 name;
- SupportedCurve* curve;
- extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
- /* May be doing PSK with no key exchange. */
- if (extension == NULL)
- return 0;
- ret = TLSX_PopulateSupportedGroups(ssl, &priority);
- if (ret != WOLFSSL_SUCCESS) {
- TLSX_FreeAll(priority, ssl->heap);
- return ret;
- }
- ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS);
- if (ext == NULL) {
- WOLFSSL_MSG("Could not find supported groups extension");
- TLSX_FreeAll(priority, ssl->heap);
- return 0;
- }
- curve = (SupportedCurve*)ext->data;
- name = curve->name;
- curve = (SupportedCurve*)extension->data;
- while (curve != NULL) {
- if (curve->name == name)
- break;
- curve = curve->next;
- }
- if (curve == NULL) {
- /* Couldn't find the preferred group in client list. */
- extension->resp = 1;
- /* Send server list back and free client list. */
- curve = (SupportedCurve*)extension->data;
- extension->data = ext->data;
- ext->data = curve;
- }
- TLSX_FreeAll(priority, ssl->heap);
- return 0;
- }
- #endif /* WOLFSSL_TLS13 && !WOLFSSL_NO_SERVER_GROUPS_EXT */
- #if defined(HAVE_FFDHE) && !defined(WOLFSSL_NO_TLS12)
- #ifdef HAVE_PUBLIC_FFDHE
- static int tlsx_ffdhe_find_group(WOLFSSL* ssl, SupportedCurve* clientGroup,
- SupportedCurve* serverGroup)
- {
- int ret = 0;
- SupportedCurve* group;
- const DhParams* params = NULL;
- for (; serverGroup != NULL; serverGroup = serverGroup->next) {
- if (!WOLFSSL_NAMED_GROUP_IS_FFHDE(serverGroup->name))
- continue;
- for (group = clientGroup; group != NULL; group = group->next) {
- if (serverGroup->name != group->name)
- continue;
- switch (serverGroup->name) {
- #ifdef HAVE_FFDHE_2048
- case WOLFSSL_FFDHE_2048:
- params = wc_Dh_ffdhe2048_Get();
- break;
- #endif
- #ifdef HAVE_FFDHE_3072
- case WOLFSSL_FFDHE_3072:
- params = wc_Dh_ffdhe3072_Get();
- break;
- #endif
- #ifdef HAVE_FFDHE_4096
- case WOLFSSL_FFDHE_4096:
- params = wc_Dh_ffdhe4096_Get();
- break;
- #endif
- #ifdef HAVE_FFDHE_6144
- case WOLFSSL_FFDHE_6144:
- params = wc_Dh_ffdhe6144_Get();
- break;
- #endif
- #ifdef HAVE_FFDHE_8192
- case WOLFSSL_FFDHE_8192:
- params = wc_Dh_ffdhe8192_Get();
- break;
- #endif
- default:
- break;
- }
- if (params == NULL) {
- ret = BAD_FUNC_ARG;
- break;
- }
- if (params->p_len >= ssl->options.minDhKeySz &&
- params->p_len <= ssl->options.maxDhKeySz) {
- break;
- }
- }
- if (ret != 0)
- break;
- if ((group != NULL) && (serverGroup->name == group->name))
- break;
- }
- if ((ret == 0) && (serverGroup != NULL) && (params != NULL)) {
- ssl->buffers.serverDH_P.buffer = (unsigned char *)params->p;
- ssl->buffers.serverDH_P.length = params->p_len;
- ssl->buffers.serverDH_G.buffer = (unsigned char *)params->g;
- ssl->buffers.serverDH_G.length = params->g_len;
- ssl->namedGroup = serverGroup->name;
- #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \
- !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
- ssl->options.dhDoKeyTest = 0;
- #endif
- ssl->options.haveDH = 1;
- }
- return ret;
- }
- #else
- static int tlsx_ffdhe_find_group(WOLFSSL* ssl, SupportedCurve* clientGroup,
- SupportedCurve* serverGroup)
- {
- int ret = 0;
- SupportedCurve* group;
- word32 p_len;
- for (; serverGroup != NULL; serverGroup = serverGroup->next) {
- if (!WOLFSSL_NAMED_GROUP_IS_FFHDE(serverGroup->name))
- continue;
- for (group = clientGroup; group != NULL; group = group->next) {
- if (serverGroup->name != group->name)
- continue;
- wc_DhGetNamedKeyParamSize(serverGroup->name, &p_len, NULL, NULL);
- if (p_len == 0) {
- ret = BAD_FUNC_ARG;
- break;
- }
- if (p_len >= ssl->options.minDhKeySz &&
- p_len <= ssl->options.maxDhKeySz) {
- break;
- }
- }
- if (ret != 0)
- break;
- if ((group != NULL) && (serverGroup->name == group->name))
- break;
- }
- if ((ret == 0) && (serverGroup != NULL)) {
- word32 pSz, gSz;
- ssl->buffers.serverDH_P.buffer = NULL;
- ssl->buffers.serverDH_G.buffer = NULL;
- ret = wc_DhGetNamedKeyParamSize(serverGroup->name, &pSz, &gSz, NULL);
- if (ret == 0) {
- ssl->buffers.serverDH_P.buffer =
- (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- if (ssl->buffers.serverDH_P.buffer == NULL)
- ret = MEMORY_E;
- else
- ssl->buffers.serverDH_P.length = pSz;
- }
- if (ret == 0) {
- ssl->buffers.serverDH_G.buffer =
- (byte*)XMALLOC(gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- if (ssl->buffers.serverDH_G.buffer == NULL) {
- ret = MEMORY_E;
- } else
- ssl->buffers.serverDH_G.length = gSz;
- }
- if (ret == 0) {
- ret = wc_DhCopyNamedKey(serverGroup->name,
- ssl->buffers.serverDH_P.buffer, &pSz,
- ssl->buffers.serverDH_G.buffer, &gSz,
- NULL, NULL);
- }
- if (ret == 0) {
- ssl->buffers.weOwnDH = 1;
- ssl->namedGroup = serverGroup->name;
- #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \
- !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
- ssl->options.dhDoKeyTest = 0;
- #endif
- ssl->options.haveDH = 1;
- }
- else {
- if (ssl->buffers.serverDH_P.buffer != NULL) {
- XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
- DYNAMIC_TYPE_PUBLIC_KEY);
- ssl->buffers.serverDH_P.length = 0;
- ssl->buffers.serverDH_P.buffer = NULL;
- }
- if (ssl->buffers.serverDH_G.buffer != NULL) {
- XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
- DYNAMIC_TYPE_PUBLIC_KEY);
- ssl->buffers.serverDH_G.length = 0;
- ssl->buffers.serverDH_G.buffer = NULL;
- }
- }
- }
- return ret;
- }
- #endif
- /* Set the highest priority common FFDHE group on the server as compared to
- * client extensions.
- *
- * ssl SSL/TLS object.
- * returns 0 on success, otherwise an error.
- */
- int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl)
- {
- int ret;
- TLSX* priority = NULL;
- TLSX* ext = NULL;
- TLSX* extension;
- SupportedCurve* clientGroup;
- SupportedCurve* serverGroup;
- SupportedCurve* group;
- int found = 0;
- extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
- /* May be doing PSK with no key exchange. */
- if (extension == NULL)
- return 0;
- clientGroup = (SupportedCurve*)extension->data;
- for (group = clientGroup; group != NULL; group = group->next) {
- if (WOLFSSL_NAMED_GROUP_IS_FFHDE(group->name)) {
- found = 1;
- break;
- }
- }
- if (!found)
- return 0;
- if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
- XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
- DYNAMIC_TYPE_PUBLIC_KEY);
- }
- if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
- XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
- DYNAMIC_TYPE_PUBLIC_KEY);
- }
- ssl->buffers.serverDH_P.buffer = NULL;
- ssl->buffers.serverDH_G.buffer = NULL;
- ssl->buffers.weOwnDH = 0;
- ssl->options.haveDH = 0;
- ret = TLSX_PopulateSupportedGroups(ssl, &priority);
- if (ret == WOLFSSL_SUCCESS) {
- ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS);
- serverGroup = (SupportedCurve*)ext->data;
- ret = tlsx_ffdhe_find_group(ssl, clientGroup, serverGroup);
- }
- TLSX_FreeAll(priority, ssl->heap);
- return ret;
- }
- #endif /* HAVE_FFDHE && !WOLFSSL_NO_TLS12 */
- #endif /* !NO_WOLFSSL_SERVER */
- #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
- /* Return the preferred group.
- *
- * ssl SSL/TLS object.
- * checkSupported Whether to check for the first supported group.
- * returns BAD_FUNC_ARG if no group found, otherwise the group.
- */
- int TLSX_SupportedCurve_Preferred(WOLFSSL* ssl, int checkSupported)
- {
- TLSX* extension;
- SupportedCurve* curve;
- extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
- if (extension == NULL)
- return BAD_FUNC_ARG;
- curve = (SupportedCurve*)extension->data;
- while (curve != NULL) {
- if (!checkSupported || TLSX_KeyShare_IsSupported(curve->name))
- return curve->name;
- curve = curve->next;
- }
- return BAD_FUNC_ARG;
- }
- #endif /* HAVE_SUPPORTED_CURVES */
- #ifndef NO_WOLFSSL_SERVER
- static int TLSX_PointFormat_Parse(WOLFSSL* ssl, const byte* input,
- word16 length, byte isRequest)
- {
- int ret;
- /* validating formats list length */
- if (ENUM_LEN > length || length != (word16)ENUM_LEN + input[0])
- return BUFFER_ERROR;
- if (isRequest) {
- /* adding uncompressed point format to response */
- ret = TLSX_UsePointFormat(&ssl->extensions, WOLFSSL_EC_PF_UNCOMPRESSED,
- ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret; /* throw error */
- TLSX_SetResponse(ssl, TLSX_EC_POINT_FORMATS);
- }
- return 0;
- }
- #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
- int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
- TLSX* extension = NULL;
- SupportedCurve* curve = NULL;
- word32 oid = 0;
- word32 defOid = 0;
- word32 defSz = 80; /* Maximum known curve size is 66. */
- word32 nextOid = 0;
- word32 nextSz = 80; /* Maximum known curve size is 66. */
- word32 currOid = ssl->ecdhCurveOID;
- int ephmSuite = 0;
- word16 octets = 0; /* according to 'ecc_set_type ecc_sets[];' */
- int key = 0; /* validate key */
- (void)oid;
- if (first == CHACHA_BYTE) {
- switch (second) {
- case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256:
- case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
- case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256:
- return 1; /* no suite restriction */
- case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256:
- case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
- break;
- }
- }
- if (first == ECC_BYTE || first == ECDHE_PSK_BYTE || first == CHACHA_BYTE)
- extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
- if (!extension)
- return 1; /* no suite restriction */
- for (curve = (SupportedCurve*)extension->data;
- curve && !key;
- curve = curve->next) {
- #ifdef OPENSSL_EXTRA
- /* skip if name is not in supported ECC range
- * or disabled by user */
- if (curve->name > WOLFSSL_ECC_MAX ||
- wolfSSL_curve_is_disabled(ssl, curve->name))
- continue;
- #endif
- /* find supported curve */
- switch (curve->name) {
- #ifdef HAVE_ECC
- #if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP160R1:
- oid = ECC_SECP160R1_OID;
- octets = 20;
- break;
- #endif /* !NO_ECC_SECP */
- #ifdef HAVE_ECC_SECPR2
- case WOLFSSL_ECC_SECP160R2:
- oid = ECC_SECP160R2_OID;
- octets = 20;
- break;
- #endif /* HAVE_ECC_SECPR2 */
- #ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP160K1:
- oid = ECC_SECP160K1_OID;
- octets = 20;
- break;
- #endif /* HAVE_ECC_KOBLITZ */
- #endif
- #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP192R1:
- oid = ECC_SECP192R1_OID;
- octets = 24;
- break;
- #endif /* !NO_ECC_SECP */
- #ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP192K1:
- oid = ECC_SECP192K1_OID;
- octets = 24;
- break;
- #endif /* HAVE_ECC_KOBLITZ */
- #endif
- #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP224R1:
- oid = ECC_SECP224R1_OID;
- octets = 28;
- break;
- #endif /* !NO_ECC_SECP */
- #ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP224K1:
- oid = ECC_SECP224K1_OID;
- octets = 28;
- break;
- #endif /* HAVE_ECC_KOBLITZ */
- #endif
- #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP256R1:
- oid = ECC_SECP256R1_OID;
- octets = 32;
- break;
- #endif /* !NO_ECC_SECP */
- #endif /* !NO_ECC256 || HAVE_ALL_CURVES */
- #endif
- #if (defined(HAVE_CURVE25519) || defined(HAVE_ED25519)) && ECC_MIN_KEY_SZ <= 256
- case WOLFSSL_ECC_X25519:
- oid = ECC_X25519_OID;
- octets = 32;
- break;
- #endif /* HAVE_CURVE25519 */
- #ifdef HAVE_ECC
- #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
- #ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP256K1:
- oid = ECC_SECP256K1_OID;
- octets = 32;
- break;
- #endif /* HAVE_ECC_KOBLITZ */
- #ifdef HAVE_ECC_BRAINPOOL
- case WOLFSSL_ECC_BRAINPOOLP256R1:
- oid = ECC_BRAINPOOLP256R1_OID;
- octets = 32;
- break;
- #endif /* HAVE_ECC_BRAINPOOL */
- #endif
- #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP384R1:
- oid = ECC_SECP384R1_OID;
- octets = 48;
- break;
- #endif /* !NO_ECC_SECP */
- #ifdef HAVE_ECC_BRAINPOOL
- case WOLFSSL_ECC_BRAINPOOLP384R1:
- oid = ECC_BRAINPOOLP384R1_OID;
- octets = 48;
- break;
- #endif /* HAVE_ECC_BRAINPOOL */
- #endif
- #endif
- #if (defined(HAVE_CURVE448) || defined(HAVE_ED448)) && ECC_MIN_KEY_SZ <= 448
- case WOLFSSL_ECC_X448:
- oid = ECC_X448_OID;
- octets = 57;
- break;
- #endif /* HAVE_CURVE448 */
- #ifdef HAVE_ECC
- #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
- #ifdef HAVE_ECC_BRAINPOOL
- case WOLFSSL_ECC_BRAINPOOLP512R1:
- oid = ECC_BRAINPOOLP512R1_OID;
- octets = 64;
- break;
- #endif /* HAVE_ECC_BRAINPOOL */
- #endif
- #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP521R1:
- oid = ECC_SECP521R1_OID;
- octets = 66;
- break;
- #endif /* !NO_ECC_SECP */
- #endif
- #endif
- default: continue; /* unsupported curve */
- }
- #ifdef HAVE_ECC
- /* Set default Oid */
- if (defOid == 0 && ssl->eccTempKeySz <= octets && defSz > octets) {
- defOid = oid;
- defSz = octets;
- }
- /* The eccTempKeySz is the preferred ephemeral key size */
- if (currOid == 0 && ssl->eccTempKeySz == octets)
- currOid = oid;
- if ((nextOid == 0 || nextSz > octets) && ssl->eccTempKeySz <= octets) {
- nextOid = oid;
- nextSz = octets;
- }
- #else
- if (defOid == 0 && defSz > octets) {
- defOid = oid;
- defSz = octets;
- }
- if (currOid == 0)
- currOid = oid;
- if (nextOid == 0 || nextSz > octets) {
- nextOid = oid;
- nextSz = octets;
- }
- #endif
- if (first == ECC_BYTE) {
- switch (second) {
- #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
- /* ECDHE_ECDSA */
- case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
- case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
- case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
- case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
- case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
- case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
- case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
- case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
- key |= ssl->ecdhCurveOID == oid;
- ephmSuite = 1;
- break;
- #ifdef WOLFSSL_STATIC_DH
- /* ECDH_ECDSA */
- case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
- case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
- case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
- case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
- case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
- case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
- case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
- if (oid == ECC_X25519_OID && defOid == oid) {
- defOid = 0;
- defSz = 80;
- }
- if (oid == ECC_X448_OID && defOid == oid) {
- defOid = 0;
- defSz = 80;
- }
- key |= ssl->pkCurveOID == oid;
- break;
- #endif /* WOLFSSL_STATIC_DH */
- #endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
- #ifndef NO_RSA
- /* ECDHE_RSA */
- case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
- case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
- case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
- case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
- key |= ssl->ecdhCurveOID == oid;
- ephmSuite = 1;
- break;
- #if defined(HAVE_ECC) && defined(WOLFSSL_STATIC_DH)
- /* ECDH_RSA */
- case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
- case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
- case TLS_ECDH_RSA_WITH_RC4_128_SHA:
- case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
- case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
- case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
- if (oid == ECC_X25519_OID && defOid == oid) {
- defOid = 0;
- defSz = 80;
- }
- if (oid == ECC_X448_OID && defOid == oid) {
- defOid = 0;
- defSz = 80;
- }
- key |= ssl->pkCurveOID == oid;
- break;
- #endif /* HAVE_ECC && WOLFSSL_STATIC_DH */
- #endif
- default:
- if (oid == ECC_X25519_OID && defOid == oid) {
- defOid = 0;
- defSz = 80;
- }
- if (oid == ECC_X448_OID && defOid == oid) {
- defOid = 0;
- defSz = 80;
- }
- key = 1;
- break;
- }
- }
- /* ChaCha20-Poly1305 ECC cipher suites */
- if (first == CHACHA_BYTE) {
- switch (second) {
- #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
- /* ECDHE_ECDSA */
- case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
- case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
- key |= ssl->ecdhCurveOID == oid;
- ephmSuite = 1;
- break;
- #endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
- #ifndef NO_RSA
- /* ECDHE_RSA */
- case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
- case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
- key |= ssl->ecdhCurveOID == oid;
- ephmSuite = 1;
- break;
- #endif
- default:
- key = 1;
- break;
- }
- }
- }
- /* Choose the default if it is at the required strength. */
- #ifdef HAVE_ECC
- if (ssl->ecdhCurveOID == 0 && defSz == ssl->eccTempKeySz)
- #else
- if (ssl->ecdhCurveOID == 0)
- #endif
- {
- key = 1;
- ssl->ecdhCurveOID = defOid;
- }
- /* Choose any curve at the required strength. */
- if (ssl->ecdhCurveOID == 0) {
- key = 1;
- ssl->ecdhCurveOID = currOid;
- }
- /* Choose the default if it is at the next highest strength. */
- if (ssl->ecdhCurveOID == 0 && defSz == nextSz)
- ssl->ecdhCurveOID = defOid;
- /* Choose any curve at the next highest strength. */
- if (ssl->ecdhCurveOID == 0)
- ssl->ecdhCurveOID = nextOid;
- /* No curve and ephemeral ECC suite requires a matching curve. */
- if (ssl->ecdhCurveOID == 0 && ephmSuite)
- key = 0;
- return key;
- }
- #endif
- #endif /* NO_WOLFSSL_SERVER */
- int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, void* heap)
- {
- TLSX* extension = NULL;
- SupportedCurve* curve = NULL;
- int ret;
- if (extensions == NULL) {
- return BAD_FUNC_ARG;
- }
- #ifdef WOLFSSL_TLS13
- if (! TLSX_KeyShare_IsSupported(name)) {
- return BAD_FUNC_ARG;
- }
- #endif
- extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
- if (!extension) {
- ret = TLSX_SupportedCurve_New(&curve, name, heap);
- if (ret != 0)
- return ret;
- ret = TLSX_Push(extensions, TLSX_SUPPORTED_GROUPS, curve, heap);
- if (ret != 0) {
- XFREE(curve, heap, DYNAMIC_TYPE_TLSX);
- return ret;
- }
- }
- else {
- ret = TLSX_SupportedCurve_Append((SupportedCurve*)extension->data, name,
- heap);
- if (ret != 0)
- return ret;
- }
- return WOLFSSL_SUCCESS;
- }
- int TLSX_UsePointFormat(TLSX** extensions, byte format, void* heap)
- {
- TLSX* extension = NULL;
- PointFormat* point = NULL;
- int ret = 0;
- if (extensions == NULL)
- return BAD_FUNC_ARG;
- extension = TLSX_Find(*extensions, TLSX_EC_POINT_FORMATS);
- if (!extension) {
- ret = TLSX_PointFormat_New(&point, format, heap);
- if (ret != 0)
- return ret;
- ret = TLSX_Push(extensions, TLSX_EC_POINT_FORMATS, point, heap);
- if (ret != 0) {
- XFREE(point, heap, DYNAMIC_TYPE_TLSX);
- return ret;
- }
- }
- else {
- ret = TLSX_PointFormat_Append((PointFormat*)extension->data, format,
- heap);
- if (ret != 0)
- return ret;
- }
- return WOLFSSL_SUCCESS;
- }
- #define EC_FREE_ALL TLSX_SupportedCurve_FreeAll
- #define EC_VALIDATE_REQUEST TLSX_SupportedCurve_ValidateRequest
- #ifndef NO_WOLFSSL_CLIENT
- #define EC_GET_SIZE TLSX_SupportedCurve_GetSize
- #define EC_WRITE TLSX_SupportedCurve_Write
- #else
- #define EC_GET_SIZE(list) 0
- #define EC_WRITE(a, b) 0
- #endif
- #if !defined(NO_WOLFSSL_SERVER) || (defined(WOLFSSL_TLS13) && \
- !defined(WOLFSSL_NO_SERVER_GROUPS_EXT))
- #define EC_PARSE TLSX_SupportedCurve_Parse
- #else
- #define EC_PARSE(a, b, c, d) 0
- #endif
- #define PF_FREE_ALL TLSX_PointFormat_FreeAll
- #define PF_VALIDATE_REQUEST TLSX_PointFormat_ValidateRequest
- #define PF_VALIDATE_RESPONSE TLSX_PointFormat_ValidateResponse
- #define PF_GET_SIZE TLSX_PointFormat_GetSize
- #define PF_WRITE TLSX_PointFormat_Write
- #ifndef NO_WOLFSSL_SERVER
- #define PF_PARSE TLSX_PointFormat_Parse
- #else
- #define PF_PARSE(a, b, c, d) 0
- #endif
- #else
- #define EC_FREE_ALL(list, heap)
- #define EC_GET_SIZE(list) 0
- #define EC_WRITE(a, b) 0
- #define EC_PARSE(a, b, c, d) 0
- #define EC_VALIDATE_REQUEST(a, b)
- #define PF_FREE_ALL(list, heap)
- #define PF_GET_SIZE(list) 0
- #define PF_WRITE(a, b) 0
- #define PF_PARSE(a, b, c, d) 0
- #define PF_VALIDATE_REQUEST(a, b)
- #define PF_VALIDATE_RESPONSE(a, b)
- #endif /* HAVE_SUPPORTED_CURVES */
- /******************************************************************************/
- /* Renegotiation Indication */
- /******************************************************************************/
- #if defined(HAVE_SECURE_RENEGOTIATION) \
- || defined(HAVE_SERVER_RENEGOTIATION_INFO)
- static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data,
- int isRequest)
- {
- byte length = OPAQUE8_LEN; /* empty info length */
- /* data will be NULL for HAVE_SERVER_RENEGOTIATION_INFO only */
- if (data && data->enabled && data->verifySet) {
- /* client sends client_verify_data only */
- length += TLS_FINISHED_SZ;
- /* server also sends server_verify_data */
- if (!isRequest)
- length += TLS_FINISHED_SZ;
- }
- return length;
- }
- static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data,
- byte* output, int isRequest)
- {
- word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */
- if (data && data->enabled && data->verifySet) {
- /* client sends client_verify_data only */
- XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ);
- offset += TLS_FINISHED_SZ;
- /* server also sends server_verify_data */
- if (!isRequest) {
- XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ);
- offset += TLS_FINISHED_SZ;
- }
- }
- output[0] = (byte)(offset - 1); /* info length - self */
- return offset;
- }
- static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, const byte* input,
- word16 length, byte isRequest)
- {
- int ret = SECURE_RENEGOTIATION_E;
- if (length >= OPAQUE8_LEN) {
- if (isRequest) {
- #ifndef NO_WOLFSSL_SERVER
- if (ssl->secure_renegotiation == NULL) {
- ret = wolfSSL_UseSecureRenegotiation(ssl);
- if (ret == WOLFSSL_SUCCESS)
- ret = 0;
- }
- if (ret != 0 && ret != SECURE_RENEGOTIATION_E) {
- }
- else if (ssl->secure_renegotiation == NULL) {
- }
- else if (!ssl->secure_renegotiation->enabled) {
- if (*input == 0) {
- input++; /* get past size */
- ssl->secure_renegotiation->enabled = 1;
- TLSX_SetResponse(ssl, TLSX_RENEGOTIATION_INFO);
- ret = 0;
- }
- else {
- /* already in error state */
- WOLFSSL_MSG("SCR client verify data present");
- }
- }
- else if (*input == TLS_FINISHED_SZ) {
- if (length < TLS_FINISHED_SZ + 1) {
- WOLFSSL_MSG("SCR malformed buffer");
- ret = BUFFER_E;
- }
- else {
- input++; /* get past size */
- /* validate client verify data */
- if (XMEMCMP(input,
- ssl->secure_renegotiation->client_verify_data,
- TLS_FINISHED_SZ) == 0) {
- WOLFSSL_MSG("SCR client verify data match");
- TLSX_SetResponse(ssl, TLSX_RENEGOTIATION_INFO);
- ret = 0; /* verified */
- }
- else {
- /* already in error state */
- WOLFSSL_MSG("SCR client verify data Failure");
- }
- }
- }
- #endif
- }
- else if (ssl->secure_renegotiation != NULL) {
- #ifndef NO_WOLFSSL_CLIENT
- if (!ssl->secure_renegotiation->enabled) {
- if (*input == 0) {
- ssl->secure_renegotiation->enabled = 1;
- ret = 0;
- }
- }
- else if (*input == 2 * TLS_FINISHED_SZ &&
- length == 2 * TLS_FINISHED_SZ + OPAQUE8_LEN) {
- input++; /* get past size */
- /* validate client and server verify data */
- if (XMEMCMP(input,
- ssl->secure_renegotiation->client_verify_data,
- TLS_FINISHED_SZ) == 0 &&
- XMEMCMP(input + TLS_FINISHED_SZ,
- ssl->secure_renegotiation->server_verify_data,
- TLS_FINISHED_SZ) == 0) {
- WOLFSSL_MSG("SCR client and server verify data match");
- ret = 0; /* verified */
- }
- else {
- /* already in error state */
- WOLFSSL_MSG("SCR client and server verify data Failure");
- }
- }
- #endif
- }
- }
- if (ret != 0) {
- WOLFSSL_ERROR_VERBOSE(ret);
- SendAlert(ssl, alert_fatal, handshake_failure);
- }
- return ret;
- }
- int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap)
- {
- int ret = 0;
- SecureRenegotiation* data;
- data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), heap,
- DYNAMIC_TYPE_TLSX);
- if (data == NULL)
- return MEMORY_E;
- XMEMSET(data, 0, sizeof(SecureRenegotiation));
- ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, data, heap);
- if (ret != 0) {
- XFREE(data, heap, DYNAMIC_TYPE_TLSX);
- return ret;
- }
- return WOLFSSL_SUCCESS;
- }
- #ifdef HAVE_SERVER_RENEGOTIATION_INFO
- int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap)
- {
- int ret;
- /* send empty renegotiation_info extension */
- TLSX* ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO);
- if (ext == NULL) {
- ret = TLSX_UseSecureRenegotiation(extensions, heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO);
- }
- if (ext)
- ext->resp = 1;
- return WOLFSSL_SUCCESS;
- }
- #endif /* HAVE_SERVER_RENEGOTIATION_INFO */
- #define SCR_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX)
- #define SCR_GET_SIZE TLSX_SecureRenegotiation_GetSize
- #define SCR_WRITE TLSX_SecureRenegotiation_Write
- #define SCR_PARSE TLSX_SecureRenegotiation_Parse
- #else
- #define SCR_FREE_ALL(a, heap)
- #define SCR_GET_SIZE(a, b) 0
- #define SCR_WRITE(a, b, c) 0
- #define SCR_PARSE(a, b, c, d) 0
- #endif /* HAVE_SECURE_RENEGOTIATION || HAVE_SERVER_RENEGOTIATION_INFO */
- /******************************************************************************/
- /* Session Tickets */
- /******************************************************************************/
- #ifdef HAVE_SESSION_TICKET
- #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
- static void TLSX_SessionTicket_ValidateRequest(WOLFSSL* ssl)
- {
- TLSX* extension = TLSX_Find(ssl->extensions, TLSX_SESSION_TICKET);
- SessionTicket* ticket = extension ?
- (SessionTicket*)extension->data : NULL;
- if (ticket) {
- /* TODO validate ticket timeout here! */
- if (ticket->lifetime == 0xfffffff) {
- /* send empty ticket on timeout */
- TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
- }
- }
- }
- #endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
- static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest)
- {
- (void)isRequest;
- return ticket ? ticket->size : 0;
- }
- static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output,
- int isRequest)
- {
- word16 offset = 0; /* empty ticket */
- if (isRequest && ticket) {
- XMEMCPY(output + offset, ticket->data, ticket->size);
- offset += ticket->size;
- }
- return offset;
- }
- static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, const byte* input,
- word16 length, byte isRequest)
- {
- int ret = 0;
- (void) input; /* avoid unused parameter if NO_WOLFSSL_SERVER defined */
- if (!isRequest) {
- if (TLSX_CheckUnsupportedExtension(ssl, TLSX_SESSION_TICKET))
- return TLSX_HandleUnsupportedExtension(ssl);
- if (length != 0)
- return BUFFER_ERROR;
- #ifndef NO_WOLFSSL_CLIENT
- ssl->expect_session_ticket = 1;
- #endif
- }
- #ifndef NO_WOLFSSL_SERVER
- else {
- /* server side */
- if (ssl->ctx->ticketEncCb == NULL) {
- WOLFSSL_MSG("Client sent session ticket, server has no callback");
- return 0;
- }
- if (length > SESSION_TICKET_LEN) {
- ret = BAD_TICKET_MSG_SZ;
- WOLFSSL_ERROR_VERBOSE(ret);
- } else if (IsAtLeastTLSv1_3(ssl->version)) {
- WOLFSSL_MSG("Process client ticket rejected, TLS 1.3 no support");
- ssl->options.rejectTicket = 1;
- ret = 0; /* not fatal */
- } else if (ssl->options.noTicketTls12) {
- /* ignore ticket request */
- } else if (length == 0) {
- /* blank ticket */
- ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
- if (ret == WOLFSSL_SUCCESS) {
- ret = 0;
- /* send blank ticket */
- TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);
- ssl->options.createTicket = 1; /* will send ticket msg */
- ssl->options.useTicket = 1;
- ssl->options.resuming = 0; /* no standard resumption */
- ssl->arrays->sessionIDSz = 0; /* no echo on blank ticket */
- }
- } else {
- /* got actual ticket from client */
- ret = DoClientTicket(ssl, input, length);
- if (ret == WOLFSSL_TICKET_RET_OK) { /* use ticket to resume */
- WOLFSSL_MSG("Using existing client ticket");
- ssl->options.useTicket = 1;
- ssl->options.resuming = 1;
- /* SERVER: ticket is peer auth. */
- ssl->options.peerAuthGood = 1;
- } else if (ret == WOLFSSL_TICKET_RET_CREATE) {
- WOLFSSL_MSG("Using existing client ticket, creating new one");
- ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
- if (ret == WOLFSSL_SUCCESS) {
- ret = 0;
- TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);
- /* send blank ticket */
- ssl->options.createTicket = 1; /* will send ticket msg */
- ssl->options.useTicket = 1;
- ssl->options.resuming = 1;
- /* SERVER: ticket is peer auth. */
- ssl->options.peerAuthGood = 1;
- }
- } else if (ret == WOLFSSL_TICKET_RET_REJECT) {
- WOLFSSL_MSG("Process client ticket rejected, not using");
- ssl->options.rejectTicket = 1;
- ret = 0; /* not fatal */
- } else if (ret == VERSION_ERROR) {
- WOLFSSL_MSG("Process client ticket rejected, bad TLS version");
- ssl->options.rejectTicket = 1;
- ret = 0; /* not fatal */
- } else if (ret == WOLFSSL_TICKET_RET_FATAL) {
- WOLFSSL_MSG("Process client ticket fatal error, not using");
- } else if (ret < 0) {
- WOLFSSL_MSG("Process client ticket unknown error, not using");
- }
- }
- }
- #endif /* NO_WOLFSSL_SERVER */
- #if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
- (void)ssl;
- #endif
- return ret;
- }
- WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime,
- byte* data, word16 size, void* heap)
- {
- SessionTicket* ticket = (SessionTicket*)XMALLOC(sizeof(SessionTicket),
- heap, DYNAMIC_TYPE_TLSX);
- if (ticket) {
- ticket->data = (byte*)XMALLOC(size, heap, DYNAMIC_TYPE_TLSX);
- if (ticket->data == NULL) {
- XFREE(ticket, heap, DYNAMIC_TYPE_TLSX);
- return NULL;
- }
- XMEMCPY(ticket->data, data, size);
- ticket->size = size;
- ticket->lifetime = lifetime;
- }
- (void)heap;
- return ticket;
- }
- WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket, void* heap)
- {
- if (ticket) {
- XFREE(ticket->data, heap, DYNAMIC_TYPE_TLSX);
- XFREE(ticket, heap, DYNAMIC_TYPE_TLSX);
- }
- (void)heap;
- }
- int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket, void* heap)
- {
- int ret = 0;
- if (extensions == NULL)
- return BAD_FUNC_ARG;
- /* If the ticket is NULL, the client will request a new ticket from the
- server. Otherwise, the client will use it in the next client hello. */
- if ((ret = TLSX_Push(extensions, TLSX_SESSION_TICKET, (void*)ticket, heap))
- != 0)
- return ret;
- return WOLFSSL_SUCCESS;
- }
- #define WOLF_STK_VALIDATE_REQUEST TLSX_SessionTicket_ValidateRequest
- #define WOLF_STK_GET_SIZE TLSX_SessionTicket_GetSize
- #define WOLF_STK_WRITE TLSX_SessionTicket_Write
- #define WOLF_STK_PARSE TLSX_SessionTicket_Parse
- #define WOLF_STK_FREE(stk, heap) TLSX_SessionTicket_Free((SessionTicket*)(stk),(heap))
- #else
- #define WOLF_STK_FREE(a, b)
- #define WOLF_STK_VALIDATE_REQUEST(a)
- #define WOLF_STK_GET_SIZE(a, b) 0
- #define WOLF_STK_WRITE(a, b, c) 0
- #define WOLF_STK_PARSE(a, b, c, d) 0
- #endif /* HAVE_SESSION_TICKET */
- #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
- /******************************************************************************/
- /* Encrypt-then-MAC */
- /******************************************************************************/
- #ifndef WOLFSSL_NO_TLS12
- static int TLSX_EncryptThenMac_Use(WOLFSSL* ssl);
- /**
- * Get the size of the Encrypt-Then-MAC extension.
- *
- * msgType Type of message to put extension into.
- * pSz Size of extension data.
- * return SANITY_MSG_E when the message is not allowed to have extension and
- * 0 otherwise.
- */
- static int TLSX_EncryptThenMac_GetSize(byte msgType, word16* pSz)
- {
- (void)pSz;
- if (msgType != client_hello && msgType != server_hello) {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Empty extension */
- return 0;
- }
- /**
- * Write the Encrypt-Then-MAC extension.
- *
- * data Unused
- * output Extension data buffer. Unused.
- * msgType Type of message to put extension into.
- * pSz Size of extension data.
- * return SANITY_MSG_E when the message is not allowed to have extension and
- * 0 otherwise.
- */
- static int TLSX_EncryptThenMac_Write(void* data, byte* output, byte msgType,
- word16* pSz)
- {
- (void)data;
- (void)output;
- (void)pSz;
- if (msgType != client_hello && msgType != server_hello) {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Empty extension */
- return 0;
- }
- /**
- * Parse the Encrypt-Then-MAC extension.
- *
- * ssl SSL object
- * input Extension data buffer.
- * length Length of this extension's data.
- * msgType Type of message to extension appeared in.
- * return SANITY_MSG_E when the message is not allowed to have extension,
- * BUFFER_ERROR when the extension's data is invalid,
- * MEMORY_E when unable to allocate memory and
- * 0 otherwise.
- */
- static int TLSX_EncryptThenMac_Parse(WOLFSSL* ssl, const byte* input,
- word16 length, byte msgType)
- {
- int ret;
- (void)input;
- if (msgType != client_hello && msgType != server_hello) {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Empty extension */
- if (length != 0)
- return BUFFER_ERROR;
- if (msgType == client_hello) {
- /* Check the user hasn't disallowed use of Encrypt-Then-Mac. */
- if (!ssl->options.disallowEncThenMac) {
- ssl->options.encThenMac = 1;
- /* Set the extension reply. */
- ret = TLSX_EncryptThenMac_Use(ssl);
- if (ret != 0)
- return ret;
- }
- return 0;
- }
- /* Server Hello */
- if (ssl->options.disallowEncThenMac) {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- ssl->options.encThenMac = 1;
- return 0;
- }
- /**
- * Add the Encrypt-Then-MAC extension to list.
- *
- * ssl SSL object
- * return MEMORY_E when unable to allocate memory and 0 otherwise.
- */
- static int TLSX_EncryptThenMac_Use(WOLFSSL* ssl)
- {
- int ret = 0;
- TLSX* extension;
- /* Find the Encrypt-Then-Mac extension if it exists. */
- extension = TLSX_Find(ssl->extensions, TLSX_ENCRYPT_THEN_MAC);
- if (extension == NULL) {
- /* Push new Encrypt-Then-Mac extension. */
- ret = TLSX_Push(&ssl->extensions, TLSX_ENCRYPT_THEN_MAC, NULL,
- ssl->heap);
- if (ret != 0)
- return ret;
- }
- return 0;
- }
- /**
- * Set the Encrypt-Then-MAC extension as one to respond too.
- *
- * ssl SSL object
- * return EXT_MISSING when EncryptThenMac extension not in list.
- */
- int TLSX_EncryptThenMac_Respond(WOLFSSL* ssl)
- {
- TLSX* extension;
- extension = TLSX_Find(ssl->extensions, TLSX_ENCRYPT_THEN_MAC);
- if (extension == NULL)
- return EXT_MISSING;
- extension->resp = 1;
- return 0;
- }
- #define ETM_GET_SIZE TLSX_EncryptThenMac_GetSize
- #define ETM_WRITE TLSX_EncryptThenMac_Write
- #define ETM_PARSE TLSX_EncryptThenMac_Parse
- #else
- #define ETM_GET_SIZE(a, b) 0
- #define ETM_WRITE(a, b, c, d) 0
- #define ETM_PARSE(a, b, c, d) 0
- #endif /* !WOLFSSL_NO_TLS12 */
- #endif /* HAVE_ENCRYPT_THEN_MAC && !WOLFSSL_AEAD_ONLY */
- #ifdef WOLFSSL_SRTP
- /******************************************************************************/
- /* DTLS SRTP (Secure Real-time Transport Protocol) */
- /******************************************************************************/
- /* Only support single SRTP profile */
- typedef struct TlsxSrtp {
- word16 profileCount;
- word16 ids; /* selected bits */
- } TlsxSrtp;
- static int TLSX_UseSRTP_GetSize(TlsxSrtp *srtp)
- {
- /* SRTP Profile Len (2)
- * SRTP Profiles (2)
- * MKI (master key id) Length */
- return (OPAQUE16_LEN + (srtp->profileCount * OPAQUE16_LEN) + 1);
- }
- static TlsxSrtp* TLSX_UseSRTP_New(word16 ids, void* heap)
- {
- TlsxSrtp* srtp;
- int i;
- srtp = (TlsxSrtp*)XMALLOC(sizeof(TlsxSrtp), heap, DYNAMIC_TYPE_TLSX);
- if (srtp == NULL) {
- WOLFSSL_MSG("TLSX SRTP Memory failure");
- return NULL;
- }
- /* count and test each bit set */
- srtp->profileCount = 0;
- for (i=0; i<16; i++) {
- if (ids & (1 << i)) {
- srtp->profileCount++;
- }
- }
- srtp->ids = ids;
- return srtp;
- }
- static void TLSX_UseSRTP_Free(TlsxSrtp *srtp, void* heap)
- {
- if (srtp != NULL) {
- XFREE(srtp, heap, DYNAMIC_TYPE_TLSX);
- }
- (void)heap;
- }
- static int TLSX_UseSRTP_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte isRequest)
- {
- int ret = BAD_FUNC_ARG;
- word16 profile_len = 0;
- word16 profile_value = 0;
- word16 offset = 0;
- #ifndef NO_WOLFSSL_SERVER
- int i;
- TlsxSrtp* srtp = NULL;
- #endif
- if (length < OPAQUE16_LEN) {
- return BUFFER_ERROR;
- }
- /* reset selected DTLS SRTP profile ID */
- ssl->dtlsSrtpId = 0;
- /* total length, not include itself */
- ato16(input, &profile_len);
- offset += OPAQUE16_LEN;
- if (!isRequest) {
- #ifndef NO_WOLFSSL_CLIENT
- if (length < offset + OPAQUE16_LEN)
- return BUFFER_ERROR;
- ato16(input + offset, &profile_value);
- /* check that the profile received was in the ones we support */
- if (profile_value < 16 &&
- (ssl->dtlsSrtpProfiles & (1 << profile_value))) {
- ssl->dtlsSrtpId = profile_value;
- ret = 0; /* success */
- }
- #endif
- }
- #ifndef NO_WOLFSSL_SERVER
- else {
- /* parse remainder one profile at a time, looking for match in CTX */
- ret = 0;
- for (i=offset; i<length; i+=OPAQUE16_LEN) {
- ato16(input+i, &profile_value);
- /* find first match */
- if (profile_value < 16 &&
- ssl->dtlsSrtpProfiles & (1 << profile_value)) {
- ssl->dtlsSrtpId = profile_value;
- /* make sure we respond with selected SRTP id selected */
- srtp = TLSX_UseSRTP_New((1 << profile_value), ssl->heap);
- if (srtp != NULL) {
- ret = TLSX_Push(&ssl->extensions, TLSX_USE_SRTP,
- (void*)srtp, ssl->heap);
- if (ret == 0) {
- TLSX_SetResponse(ssl, TLSX_USE_SRTP);
- /* successfully set extension */
- }
- }
- else {
- ret = MEMORY_E;
- }
- break;
- }
- }
- }
- if (ret == 0 && ssl->dtlsSrtpId == 0) {
- WOLFSSL_MSG("TLSX_UseSRTP_Parse profile not found!");
- /* not fatal */
- }
- else if (ret != 0) {
- ssl->dtlsSrtpId = 0;
- TLSX_UseSRTP_Free(srtp, ssl->heap);
- }
- #endif
- (void)profile_len;
- return ret;
- }
- static word16 TLSX_UseSRTP_Write(TlsxSrtp* srtp, byte* output)
- {
- word16 offset = 0;
- int i, j;
- c16toa(srtp->profileCount*2, output+offset);
- offset += OPAQUE16_LEN;
- for (i=0; i< srtp->profileCount; i+=2) {
- for (j=0; j<16; j++) {
- if (srtp->ids & (1 << j)) {
- c16toa(j, output+offset);
- offset += OPAQUE16_LEN;
- }
- }
- }
- output[offset++] = 0x00; /* MKI Length */
- return offset;
- }
- static int TLSX_UseSRTP(TLSX** extensions, word16 profiles, void* heap)
- {
- int ret = 0;
- TLSX* extension;
- if (extensions == NULL) {
- return BAD_FUNC_ARG;
- }
- extension = TLSX_Find(*extensions, TLSX_USE_SRTP);
- if (extension == NULL) {
- TlsxSrtp* srtp = TLSX_UseSRTP_New(profiles, heap);
- if (srtp == NULL) {
- return MEMORY_E;
- }
- ret = TLSX_Push(extensions, TLSX_USE_SRTP, (void*)srtp, heap);
- if (ret != 0) {
- TLSX_UseSRTP_Free(srtp, heap);
- }
- }
- return ret;
- }
- #ifndef NO_WOLFSSL_SERVER
- #define SRTP_FREE TLSX_UseSRTP_Free
- #define SRTP_PARSE TLSX_UseSRTP_Parse
- #define SRTP_WRITE TLSX_UseSRTP_Write
- #define SRTP_GET_SIZE TLSX_UseSRTP_GetSize
- #else
- #define SRTP_FREE(a, b)
- #define SRTP_PARSE(a, b, c, d) 0
- #define SRTP_WRITE(a, b) 0
- #define SRTP_GET_SIZE(a) 0
- #endif
- #endif /* WOLFSSL_SRTP */
- /******************************************************************************/
- /* Supported Versions */
- /******************************************************************************/
- #ifdef WOLFSSL_TLS13
- static WC_INLINE int versionIsGreater(byte isDtls, byte a, byte b)
- {
- (void)isDtls;
- #ifdef WOLFSSL_DTLS
- /* DTLS version increases backwards (-1,-2,-3,etc) */
- if (isDtls)
- return a < b;
- #endif /* WOLFSSL_DTLS */
- return a > b;
- }
- static WC_INLINE int versionIsLesser(byte isDtls, byte a, byte b)
- {
- (void)isDtls;
- #ifdef WOLFSSL_DTLS
- /* DTLS version increases backwards (-1,-2,-3,etc) */
- if (isDtls)
- return a > b;
- #endif /* WOLFSSL_DTLS */
- return a < b;
- }
- static WC_INLINE int versionIsAtLeast(byte isDtls, byte a, byte b)
- {
- (void)isDtls;
- #ifdef WOLFSSL_DTLS
- /* DTLS version increases backwards (-1,-2,-3,etc) */
- if (isDtls)
- return a <= b;
- #endif /* WOLFSSL_DTLS */
- return a >= b;
- }
- static WC_INLINE int versionIsLessEqual(byte isDtls, byte a, byte b)
- {
- (void)isDtls;
- #ifdef WOLFSSL_DTLS
- /* DTLS version increases backwards (-1,-2,-3,etc) */
- if (isDtls)
- return a >= b;
- #endif /* WOLFSSL_DTLS */
- return a <= b;
- }
- /* Return the size of the SupportedVersions extension's data.
- *
- * data The SSL/TLS object.
- * msgType The type of the message this extension is being written into.
- * returns the length of data that will be in the extension.
- */
- static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
- {
- WOLFSSL* ssl = (WOLFSSL*)data;
- byte tls13Minor, tls12Minor, tls11Minor, isDtls;
- isDtls = !!ssl->options.dtls;
- tls13Minor = (byte)(isDtls ? DTLSv1_3_MINOR : TLSv1_3_MINOR);
- tls12Minor = (byte)(isDtls ? DTLSv1_2_MINOR : TLSv1_2_MINOR);
- tls11Minor = (byte)(isDtls ? DTLS_MINOR : TLSv1_1_MINOR);
- /* unused on some configuration */
- (void)tls12Minor;
- (void)tls13Minor;
- (void)tls11Minor;
- if (msgType == client_hello) {
- /* TLS v1.2 and TLS v1.3 */
- int cnt = 0;
- if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls13Minor)
- #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
- defined(WOLFSSL_WPAS_SMALL)
- && (ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0
- #endif
- ) {
- cnt++;
- }
- if (ssl->options.downgrade) {
- #ifndef WOLFSSL_NO_TLS12
- if (versionIsLessEqual(
- isDtls, ssl->options.minDowngrade, tls12Minor)
- #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
- defined(WOLFSSL_WPAS_SMALL)
- && (ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0
- #endif
- ) {
- cnt++;
- }
- #endif
- #ifndef NO_OLD_TLS
- if (versionIsLessEqual(
- isDtls, ssl->options.minDowngrade, tls11Minor)
- #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
- defined(WOLFSSL_WPAS_SMALL)
- && (ssl->options.mask & SSL_OP_NO_TLSv1_1) == 0
- #endif
- ) {
- cnt++;
- }
- #ifdef WOLFSSL_ALLOW_TLSV10
- if (!ssl->options.dtls && (ssl->options.minDowngrade <= TLSv1_MINOR)
- #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
- defined(WOLFSSL_WPAS_SMALL)
- && (ssl->options.mask & SSL_OP_NO_TLSv1) == 0
- #endif
- ) {
- cnt++;
- }
- #endif
- #endif
- }
- *pSz += (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
- }
- else if (msgType == server_hello || msgType == hello_retry_request) {
- *pSz += OPAQUE16_LEN;
- }
- else {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- return 0;
- }
- /* Writes the SupportedVersions extension into the buffer.
- *
- * data The SSL/TLS object.
- * output The buffer to write the extension into.
- * msgType The type of the message this extension is being written into.
- * returns the length of data that was written.
- */
- static int TLSX_SupportedVersions_Write(void* data, byte* output,
- byte msgType, word16* pSz)
- {
- WOLFSSL* ssl = (WOLFSSL*)data;
- byte major;
- byte* cnt;
- byte tls13minor, tls12minor, tls11minor, isDtls = 0;
- tls13minor = (byte)TLSv1_3_MINOR;
- tls12minor = (byte)TLSv1_2_MINOR;
- tls11minor = (byte)TLSv1_1_MINOR;
- /* unused in some configuration */
- (void)tls11minor;
- (void)tls12minor;
- #ifdef WOLFSSL_DTLS13
- if (ssl->options.dtls) {
- tls13minor = (byte)DTLSv1_3_MINOR;
- tls12minor = (byte)DTLSv1_2_MINOR;
- tls11minor = (byte)DTLS_MINOR;
- isDtls = 1;
- }
- #endif /* WOLFSSL_DTLS13 */
- if (msgType == client_hello) {
- major = ssl->ctx->method->version.major;
- cnt = output++;
- *cnt = 0;
- if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls13minor)
- #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
- defined(WOLFSSL_WPAS_SMALL)
- && (ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0
- #endif
- ) {
- *cnt += OPAQUE16_LEN;
- #ifdef WOLFSSL_TLS13_DRAFT
- /* The TLS draft major number. */
- *(output++) = TLS_DRAFT_MAJOR;
- /* Version of draft supported. */
- *(output++) = TLS_DRAFT_MINOR;
- #else
- *(output++) = major;
- *(output++) = tls13minor;
- #endif
- }
- if (ssl->options.downgrade) {
- #ifndef WOLFSSL_NO_TLS12
- if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls12minor)
- #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
- defined(WOLFSSL_WPAS_SMALL)
- && (ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0
- #endif
- ) {
- *cnt += OPAQUE16_LEN;
- *(output++) = major;
- *(output++) = tls12minor;
- }
- #endif
- #ifndef NO_OLD_TLS
- if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls11minor)
- #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
- defined(WOLFSSL_WPAS_SMALL)
- && (ssl->options.mask & SSL_OP_NO_TLSv1_1) == 0
- #endif
- ) {
- *cnt += OPAQUE16_LEN;
- *(output++) = major;
- *(output++) = tls11minor;
- }
- #ifdef WOLFSSL_ALLOW_TLSV10
- if (!ssl->options.dtls && (ssl->options.minDowngrade <= TLSv1_MINOR)
- #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
- defined(WOLFSSL_WPAS_SMALL)
- && (ssl->options.mask & SSL_OP_NO_TLSv1) == 0
- #endif
- ) {
- *cnt += OPAQUE16_LEN;
- *(output++) = major;
- *(output++) = (byte)TLSv1_MINOR;
- }
- #endif
- #endif
- }
- *pSz += (word16)(OPAQUE8_LEN + *cnt);
- }
- else if (msgType == server_hello || msgType == hello_retry_request) {
- output[0] = ssl->version.major;
- output[1] = ssl->version.minor;
- *pSz += OPAQUE16_LEN;
- }
- else {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- return 0;
- }
- /* Parse the SupportedVersions extension.
- *
- * ssl The SSL/TLS object.
- * input The buffer with the extension data.
- * length The length of the extension data.
- * msgType The type of the message this extension is being parsed from.
- * returns 0 on success, otherwise failure.
- */
- static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
- word16 length, byte msgType)
- {
- ProtocolVersion pv = ssl->ctx->method->version;
- int i;
- int len;
- byte newMinor = 0;
- int set = 0;
- int ret;
- byte major, minor;
- byte tls13minor, tls12minor;
- byte isDtls;
- tls13minor = TLSv1_3_MINOR;
- tls12minor = TLSv1_2_MINOR;
- isDtls = ssl->options.dtls == 1;
- #ifdef WOLFSSL_DTLS13
- if (ssl->options.dtls) {
- tls13minor = DTLSv1_3_MINOR;
- tls12minor = DTLSv1_2_MINOR;
- }
- #endif /* WOLFSSL_DTLS13 */
- if (msgType == client_hello) {
- /* Must contain a length and at least one version. */
- if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1)
- return BUFFER_ERROR;
- len = *input;
- /* Protocol version array must fill rest of data. */
- if (length != (word16)OPAQUE8_LEN + len)
- return BUFFER_ERROR;
- input++;
- /* Find first match. */
- for (i = 0; i < len; i += OPAQUE16_LEN) {
- major = input[i];
- minor = input[i + OPAQUE8_LEN];
- #ifdef WOLFSSL_TLS13_DRAFT
- if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
- major = SSLv3_MAJOR;
- minor = TLSv1_3_MINOR;
- }
- #else
- if (major == TLS_DRAFT_MAJOR)
- continue;
- #endif
- if (major != pv.major)
- continue;
- /* No upgrade allowed. */
- if (versionIsGreater(isDtls, minor, ssl->version.minor))
- continue;
- /* Check downgrade. */
- if (versionIsLesser(isDtls, minor, ssl->version.minor)) {
- if (!ssl->options.downgrade)
- continue;
- if (versionIsLesser(
- isDtls, minor, ssl->options.minDowngrade))
- continue;
- if (newMinor == 0 &&
- versionIsGreater(
- isDtls, minor, ssl->options.oldMinor)) {
- /* Downgrade the version. */
- ssl->version.minor = minor;
- }
- }
- if (versionIsAtLeast(isDtls, minor, tls13minor)) {
- ssl->options.tls1_3 = 1;
- /* TLS v1.3 requires supported version extension */
- if (TLSX_Find(ssl->extensions, TLSX_SUPPORTED_VERSIONS) == NULL) {
- ret = TLSX_Prepend(&ssl->extensions,
- TLSX_SUPPORTED_VERSIONS, ssl, ssl->heap);
- if (ret != 0) {
- return ret;
- }
- TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS);
- }
- if (versionIsGreater(isDtls, minor, newMinor)) {
- ssl->version.minor = minor;
- newMinor = minor;
- }
- }
- else if (versionIsGreater(
- isDtls, minor, ssl->options.oldMinor))
- ssl->options.oldMinor = minor;
- set = 1;
- }
- if (!set) {
- SendAlert(ssl, alert_fatal, wolfssl_alert_protocol_version);
- WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
- return VERSION_ERROR;
- }
- }
- else if (msgType == server_hello || msgType == hello_retry_request) {
- /* Must contain one version. */
- if (length != OPAQUE16_LEN)
- return BUFFER_ERROR;
- major = input[0];
- minor = input[OPAQUE8_LEN];
- if (major != pv.major) {
- WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
- return VERSION_ERROR;
- }
- /* Can't downgrade with this extension below TLS v1.3. */
- if (versionIsLesser(isDtls, minor, tls13minor)) {
- WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
- return VERSION_ERROR;
- }
- /* Version is TLS v1.2 to handle downgrading from TLS v1.3+. */
- if (ssl->options.downgrade && ssl->version.minor == tls12minor) {
- /* Set minor version back to TLS v1.3+ */
- ssl->version.minor = ssl->ctx->method->version.minor;
- }
- /* No upgrade allowed. */
- if (versionIsLesser(isDtls, ssl->version.minor, minor)) {
- WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
- return VERSION_ERROR;
- }
- /* Check downgrade. */
- if (versionIsGreater(isDtls, ssl->version.minor, minor)) {
- if (!ssl->options.downgrade) {
- WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
- return VERSION_ERROR;
- }
- if (versionIsLesser(
- isDtls, minor, ssl->options.minDowngrade)) {
- WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
- return VERSION_ERROR;
- }
- /* Downgrade the version. */
- ssl->version.minor = minor;
- }
- }
- else {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- return 0;
- }
- /* Sets a new SupportedVersions extension into the extension list.
- *
- * extensions The list of extensions.
- * data The extensions specific data.
- * heap The heap used for allocation.
- * returns 0 on success, otherwise failure.
- */
- static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data,
- void* heap)
- {
- if (extensions == NULL || data == NULL)
- return BAD_FUNC_ARG;
- return TLSX_Push(extensions, TLSX_SUPPORTED_VERSIONS, data, heap);
- }
- #define SV_GET_SIZE TLSX_SupportedVersions_GetSize
- #define SV_WRITE TLSX_SupportedVersions_Write
- #define SV_PARSE TLSX_SupportedVersions_Parse
- #else
- #define SV_GET_SIZE(a, b, c) 0
- #define SV_WRITE(a, b, c, d) 0
- #define SV_PARSE(a, b, c, d) 0
- #endif /* WOLFSSL_TLS13 */
- #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
- /******************************************************************************/
- /* Cookie */
- /******************************************************************************/
- /* Free the cookie data.
- *
- * cookie Cookie data.
- * heap The heap used for allocation.
- */
- static void TLSX_Cookie_FreeAll(Cookie* cookie, void* heap)
- {
- (void)heap;
- if (cookie != NULL)
- XFREE(cookie, heap, DYNAMIC_TYPE_TLSX);
- }
- /* Get the size of the encoded Cookie extension.
- * In messages: ClientHello and HelloRetryRequest.
- *
- * cookie The cookie to write.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes of the encoded Cookie extension.
- */
- static int TLSX_Cookie_GetSize(Cookie* cookie, byte msgType, word16* pSz)
- {
- if (msgType == client_hello || msgType == hello_retry_request) {
- *pSz += OPAQUE16_LEN + cookie->len;
- }
- else {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- return 0;
- }
- /* Writes the Cookie extension into the output buffer.
- * Assumes that the the output buffer is big enough to hold data.
- * In messages: ClientHello and HelloRetryRequest.
- *
- * cookie The cookie to write.
- * output The buffer to write into.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes written into the buffer.
- */
- static int TLSX_Cookie_Write(Cookie* cookie, byte* output, byte msgType,
- word16* pSz)
- {
- if (msgType == client_hello || msgType == hello_retry_request) {
- c16toa(cookie->len, output);
- output += OPAQUE16_LEN;
- XMEMCPY(output, &cookie->data, cookie->len);
- *pSz += OPAQUE16_LEN + cookie->len;
- }
- else {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- return 0;
- }
- /* Parse the Cookie extension.
- * In messages: ClientHello and HelloRetryRequest.
- *
- * ssl The SSL/TLS object.
- * input The extension data.
- * length The length of the extension data.
- * msgType The type of the message this extension is being parsed from.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_Cookie_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte msgType)
- {
- word16 len;
- word16 idx = 0;
- TLSX* extension;
- Cookie* cookie;
- if (msgType != client_hello && msgType != hello_retry_request) {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Message contains length and Cookie which must be at least one byte
- * in length.
- */
- if (length < OPAQUE16_LEN + 1)
- return BUFFER_E;
- ato16(input + idx, &len);
- idx += OPAQUE16_LEN;
- if (length - idx != len)
- return BUFFER_E;
- if (msgType == hello_retry_request)
- return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 0);
- /* client_hello */
- extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
- if (extension == NULL) {
- #ifdef WOLFSSL_DTLS13
- if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version))
- /* Allow a cookie extension with DTLS 1.3 because it is possible
- * that a different SSL instance sent the cookie but we are now
- * receiving it. */
- return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 0);
- else
- #endif
- {
- WOLFSSL_ERROR_VERBOSE(HRR_COOKIE_ERROR);
- return HRR_COOKIE_ERROR;
- }
- }
- cookie = (Cookie*)extension->data;
- if (cookie->len != len || XMEMCMP(&cookie->data, input + idx, len) != 0) {
- WOLFSSL_ERROR_VERBOSE(HRR_COOKIE_ERROR);
- return HRR_COOKIE_ERROR;
- }
- /* Request seen. */
- extension->resp = 0;
- return 0;
- }
- /* Use the data to create a new Cookie object in the extensions.
- *
- * ssl SSL/TLS object.
- * data Cookie data.
- * len Length of cookie data in bytes.
- * mac MAC data.
- * macSz Length of MAC data in bytes.
- * resp Indicates the extension will go into a response (HelloRetryRequest).
- * returns 0 on success and other values indicate failure.
- */
- int TLSX_Cookie_Use(WOLFSSL* ssl, const byte* data, word16 len, byte* mac,
- byte macSz, int resp)
- {
- int ret = 0;
- TLSX* extension;
- Cookie* cookie;
- /* Find the cookie extension if it exists. */
- extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
- if (extension == NULL) {
- /* Push new cookie extension. */
- ret = TLSX_Push(&ssl->extensions, TLSX_COOKIE, NULL, ssl->heap);
- if (ret != 0)
- return ret;
- extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
- if (extension == NULL)
- return MEMORY_E;
- }
- /* The Cookie structure has one byte for cookie data already. */
- cookie = (Cookie*)XMALLOC(sizeof(Cookie) + len + macSz - 1, ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (cookie == NULL)
- return MEMORY_E;
- cookie->len = len + macSz;
- XMEMCPY(&cookie->data, data, len);
- if (mac != NULL)
- XMEMCPY(&cookie->data + len, mac, macSz);
- if (extension->data != NULL)
- XFREE(extension->data, ssl->heap, DYNAMIC_TYPE_TLSX);
- extension->data = (void*)cookie;
- extension->resp = (byte)resp;
- return 0;
- }
- #define CKE_FREE_ALL TLSX_Cookie_FreeAll
- #define CKE_GET_SIZE TLSX_Cookie_GetSize
- #define CKE_WRITE TLSX_Cookie_Write
- #define CKE_PARSE TLSX_Cookie_Parse
- #else
- #define CKE_FREE_ALL(a, b) 0
- #define CKE_GET_SIZE(a, b, c) 0
- #define CKE_WRITE(a, b, c, d) 0
- #define CKE_PARSE(a, b, c, d) 0
- #endif
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- /******************************************************************************/
- /* Signature Algorithms */
- /******************************************************************************/
- /* Return the size of the SignatureAlgorithms extension's data.
- *
- * data Unused
- * returns the length of data that will be in the extension.
- */
- static word16 TLSX_SignatureAlgorithms_GetSize(void* data)
- {
- WOLFSSL* ssl = (WOLFSSL*)data;
- return OPAQUE16_LEN + ssl->suites->hashSigAlgoSz;
- }
- /* Creates a bit string of supported hash algorithms with RSA PSS.
- * The bit string is used when determining which signature algorithm to use
- * when creating the CertificateVerify message.
- * Note: Valid data has an even length as each signature algorithm is two bytes.
- *
- * ssl The SSL/TLS object.
- * input The buffer with the list of supported signature algorithms.
- * length The length of the list in bytes.
- * returns 0 on success, BUFFER_ERROR when the length is not even.
- */
- static int TLSX_SignatureAlgorithms_MapPss(WOLFSSL *ssl, const byte* input,
- word16 length)
- {
- word16 i;
- if ((length & 1) == 1)
- return BUFFER_ERROR;
- ssl->pssAlgo = 0;
- for (i = 0; i < length; i += 2) {
- if (input[i] == rsa_pss_sa_algo && input[i + 1] <= sha512_mac)
- ssl->pssAlgo |= 1 << input[i + 1];
- #ifdef WOLFSSL_TLS13
- if (input[i] == rsa_pss_sa_algo && input[i + 1] >= pss_sha256 &&
- input[i + 1] <= pss_sha512) {
- ssl->pssAlgo |= 1 << input[i + 1];
- }
- #endif
- }
- return 0;
- }
- /* Writes the SignatureAlgorithms extension into the buffer.
- *
- * data Unused
- * output The buffer to write the extension into.
- * returns the length of data that was written.
- */
- static word16 TLSX_SignatureAlgorithms_Write(void* data, byte* output)
- {
- WOLFSSL* ssl = (WOLFSSL*)data;
- c16toa(ssl->suites->hashSigAlgoSz, output);
- XMEMCPY(output + OPAQUE16_LEN, ssl->suites->hashSigAlgo,
- ssl->suites->hashSigAlgoSz);
- TLSX_SignatureAlgorithms_MapPss(ssl, output + OPAQUE16_LEN,
- ssl->suites->hashSigAlgoSz);
- return OPAQUE16_LEN + ssl->suites->hashSigAlgoSz;
- }
- /* Parse the SignatureAlgorithms extension.
- *
- * ssl The SSL/TLS object.
- * input The buffer with the extension data.
- * length The length of the extension data.
- * returns 0 on success, otherwise failure.
- */
- static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, const byte* input,
- word16 length, byte isRequest, Suites* suites)
- {
- word16 len;
- if (!isRequest)
- return BUFFER_ERROR;
- /* Must contain a length and at least algorithm. */
- if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0)
- return BUFFER_ERROR;
- ato16(input, &len);
- input += OPAQUE16_LEN;
- /* Algorithm array must fill rest of data. */
- if (length != OPAQUE16_LEN + len)
- return BUFFER_ERROR;
- /* Sig Algo list size must be even. */
- if (suites->hashSigAlgoSz % 2 != 0)
- return BUFFER_ERROR;
- /* truncate hashSigAlgo list if too long */
- suites->hashSigAlgoSz = len;
- if (suites->hashSigAlgoSz > WOLFSSL_MAX_SIGALGO) {
- WOLFSSL_MSG("TLSX SigAlgo list exceeds max, truncating");
- suites->hashSigAlgoSz = WOLFSSL_MAX_SIGALGO;
- }
- XMEMCPY(suites->hashSigAlgo, input, suites->hashSigAlgoSz);
- return TLSX_SignatureAlgorithms_MapPss(ssl, input, len);
- }
- /* Sets a new SignatureAlgorithms extension into the extension list.
- *
- * extensions The list of extensions.
- * data The extensions specific data.
- * heap The heap used for allocation.
- * returns 0 on success, otherwise failure.
- */
- static int TLSX_SetSignatureAlgorithms(TLSX** extensions, const void* data,
- void* heap)
- {
- if (extensions == NULL)
- return BAD_FUNC_ARG;
- return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS, data, heap);
- }
- #define SA_GET_SIZE TLSX_SignatureAlgorithms_GetSize
- #define SA_WRITE TLSX_SignatureAlgorithms_Write
- #define SA_PARSE TLSX_SignatureAlgorithms_Parse
- #endif
- /******************************************************************************/
- /* Signature Algorithms Certificate */
- /******************************************************************************/
- #if defined(WOLFSSL_TLS13) && !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- /* Return the size of the SignatureAlgorithms extension's data.
- *
- * data Unused
- * returns the length of data that will be in the extension.
- */
- static word16 TLSX_SignatureAlgorithmsCert_GetSize(void* data)
- {
- WOLFSSL* ssl = (WOLFSSL*)data;
- return OPAQUE16_LEN + ssl->certHashSigAlgoSz;
- }
- /* Writes the SignatureAlgorithmsCert extension into the buffer.
- *
- * data Unused
- * output The buffer to write the extension into.
- * returns the length of data that was written.
- */
- static word16 TLSX_SignatureAlgorithmsCert_Write(void* data, byte* output)
- {
- WOLFSSL* ssl = (WOLFSSL*)data;
- c16toa(ssl->certHashSigAlgoSz, output);
- XMEMCPY(output + OPAQUE16_LEN, ssl->certHashSigAlgo,
- ssl->certHashSigAlgoSz);
- return OPAQUE16_LEN + ssl->certHashSigAlgoSz;
- }
- /* Parse the SignatureAlgorithmsCert extension.
- *
- * ssl The SSL/TLS object.
- * input The buffer with the extension data.
- * length The length of the extension data.
- * returns 0 on success, otherwise failure.
- */
- static int TLSX_SignatureAlgorithmsCert_Parse(WOLFSSL *ssl, const byte* input,
- word16 length, byte isRequest)
- {
- word16 len;
- if (!isRequest)
- return BUFFER_ERROR;
- /* Must contain a length and at least algorithm. */
- if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0)
- return BUFFER_ERROR;
- ato16(input, &len);
- input += OPAQUE16_LEN;
- /* Algorithm array must fill rest of data. */
- if (length != OPAQUE16_LEN + len)
- return BUFFER_ERROR;
- /* truncate hashSigAlgo list if too long */
- ssl->certHashSigAlgoSz = len;
- if (ssl->certHashSigAlgoSz > WOLFSSL_MAX_SIGALGO) {
- WOLFSSL_MSG("TLSX SigAlgo list exceeds max, truncating");
- ssl->certHashSigAlgoSz = WOLFSSL_MAX_SIGALGO;
- }
- XMEMCPY(ssl->certHashSigAlgo, input, ssl->certHashSigAlgoSz);
- return 0;
- }
- /* Sets a new SignatureAlgorithmsCert extension into the extension list.
- *
- * extensions The list of extensions.
- * data The extensions specific data.
- * heap The heap used for allocation.
- * returns 0 on success, otherwise failure.
- */
- static int TLSX_SetSignatureAlgorithmsCert(TLSX** extensions, const void* data,
- void* heap)
- {
- if (extensions == NULL)
- return BAD_FUNC_ARG;
- return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS_CERT, data, heap);
- }
- #define SAC_GET_SIZE TLSX_SignatureAlgorithmsCert_GetSize
- #define SAC_WRITE TLSX_SignatureAlgorithmsCert_Write
- #define SAC_PARSE TLSX_SignatureAlgorithmsCert_Parse
- #endif /* WOLFSSL_TLS13 */
- /******************************************************************************/
- /* Key Share */
- /******************************************************************************/
- #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
- /* Create a key share entry using named Diffie-Hellman parameters group.
- * Generates a key pair.
- *
- * ssl The SSL/TLS object.
- * kse The key share entry object.
- * returns 0 on success, otherwise failure.
- */
- static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
- {
- int ret = 0;
- #if !defined(NO_DH) && (!defined(NO_CERTS) || !defined(NO_PSK))
- word32 pSz = 0, pvtSz = 0;
- DhKey* dhKey = (DhKey*)kse->key;
- /* Pick the parameters from the named group. */
- #ifdef HAVE_PUBLIC_FFDHE
- const DhParams* params = NULL;
- switch (kse->group) {
- #ifdef HAVE_FFDHE_2048
- case WOLFSSL_FFDHE_2048:
- params = wc_Dh_ffdhe2048_Get();
- kse->keyLen = 29;
- break;
- #endif
- #ifdef HAVE_FFDHE_3072
- case WOLFSSL_FFDHE_3072:
- params = wc_Dh_ffdhe3072_Get();
- kse->keyLen = 34;
- break;
- #endif
- #ifdef HAVE_FFDHE_4096
- case WOLFSSL_FFDHE_4096:
- params = wc_Dh_ffdhe4096_Get();
- kse->keyLen = 39;
- break;
- #endif
- #ifdef HAVE_FFDHE_6144
- case WOLFSSL_FFDHE_6144:
- params = wc_Dh_ffdhe6144_Get();
- kse->keyLen = 46;
- break;
- #endif
- #ifdef HAVE_FFDHE_8192
- case WOLFSSL_FFDHE_8192:
- params = wc_Dh_ffdhe8192_Get();
- kse->keyLen = 52;
- break;
- #endif
- default:
- break;
- }
- if (params == NULL)
- return BAD_FUNC_ARG;
- pSz = params->p_len;
- pvtSz = kse->keyLen;
- #else
- kse->keyLen = wc_DhGetNamedKeyMinSize(kse->group);
- if (kse->keyLen == 0) {
- return BAD_FUNC_ARG;
- }
- ret = wc_DhGetNamedKeyParamSize(kse->group, &pSz, NULL, NULL);
- if (ret != 0) {
- return BAD_FUNC_ARG;
- }
- pvtSz = kse->keyLen;
- #endif
- kse->pubKeyLen = pSz;
- /* Trigger Key Generation */
- if (kse->pubKey == NULL || kse->privKey == NULL) {
- if (kse->key == NULL) {
- kse->key = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap,
- DYNAMIC_TYPE_DH);
- if (kse->key == NULL)
- return MEMORY_E;
- /* Setup Key */
- ret = wc_InitDhKey_ex((DhKey*)kse->key, ssl->heap, ssl->devId);
- if (ret == 0) {
- dhKey = (DhKey*)kse->key;
- #ifdef HAVE_PUBLIC_FFDHE
- ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g,
- params->g_len);
- #else
- ret = wc_DhSetNamedKey(dhKey, kse->group);
- #endif
- }
- }
- /* Allocate space for the private and public key */
- if (ret == 0 && kse->pubKey == NULL) {
- kse->pubKey = (byte*)XMALLOC(kse->pubKeyLen, ssl->heap,
- DYNAMIC_TYPE_PUBLIC_KEY);
- if (kse->pubKey == NULL)
- ret = MEMORY_E;
- }
- if (ret == 0 && kse->privKey == NULL) {
- kse->privKey = (byte*)XMALLOC(kse->keyLen, ssl->heap,
- DYNAMIC_TYPE_PRIVATE_KEY);
- if (kse->privKey == NULL)
- ret = MEMORY_E;
- }
- if (ret == 0) {
- #if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(WOLFSSL_DH_EXTRA)
- ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_DH, kse->key);
- if (ret == 0) {
- ret = wc_DhExportKeyPair(dhKey,
- (byte*)kse->privKey, &kse->keyLen, /* private */
- kse->pubKey, &kse->pubKeyLen /* public */
- );
- }
- else
- #endif
- {
- /* Generate a new key pair */
- /* For async this is called once and when event is done, the
- * provided buffers will be populated.
- * Final processing is zero pad below. */
- ret = DhGenKeyPair(ssl, dhKey,
- (byte*)kse->privKey, &kse->keyLen, /* private */
- kse->pubKey, &kse->pubKeyLen /* public */
- );
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (ret == WC_PENDING_E) {
- return ret;
- }
- #endif
- }
- }
- }
- if (ret == 0) {
- if (pSz != kse->pubKeyLen) {
- /* Zero pad the front of the public key to match prime "p" size */
- XMEMMOVE(kse->pubKey + pSz - kse->pubKeyLen, kse->pubKey,
- kse->pubKeyLen);
- XMEMSET(kse->pubKey, 0, pSz - kse->pubKeyLen);
- kse->pubKeyLen = pSz;
- }
- if (pvtSz != kse->keyLen) {
- /* Zero pad the front of the private key */
- XMEMMOVE(kse->privKey + pvtSz - kse->keyLen, kse->privKey,
- kse->keyLen);
- XMEMSET(kse->privKey, 0, pvtSz - kse->keyLen);
- kse->keyLen = pvtSz;
- }
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_MSG("Public DH Key");
- WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen);
- #endif
- }
- /* Always release the DH key to free up memory.
- * The DhKey will be setup again in TLSX_KeyShare_ProcessDh */
- if (dhKey != NULL)
- wc_FreeDhKey(dhKey);
- if (kse->key != NULL) {
- XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_DH);
- kse->key = NULL;
- }
- if (ret != 0) {
- /* Cleanup on error, otherwise data owned by key share entry */
- if (kse->privKey != NULL) {
- XFREE(kse->privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- kse->privKey = NULL;
- }
- if (kse->pubKey != NULL) {
- XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- kse->pubKey = NULL;
- }
- }
- #else
- (void)ssl;
- (void)kse;
- ret = NOT_COMPILED_IN;
- WOLFSSL_ERROR_VERBOSE(ret);
- #endif
- return ret;
- }
- /* Create a key share entry using X25519 parameters group.
- * Generates a key pair.
- *
- * ssl The SSL/TLS object.
- * kse The key share entry object.
- * returns 0 on success, otherwise failure.
- */
- static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
- {
- int ret = 0;
- #ifdef HAVE_CURVE25519
- curve25519_key* key = (curve25519_key*)kse->key;
- if (kse->key == NULL) {
- /* Allocate a Curve25519 key to hold private key. */
- kse->key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), ssl->heap,
- DYNAMIC_TYPE_PRIVATE_KEY);
- if (kse->key == NULL) {
- WOLFSSL_MSG("GenX25519Key memory error");
- return MEMORY_E;
- }
- /* Make an Curve25519 key. */
- ret = wc_curve25519_init_ex((curve25519_key*)kse->key, ssl->heap,
- INVALID_DEVID);
- if (ret == 0) {
- /* setting "key" means okay to call wc_curve25519_free */
- key = (curve25519_key*)kse->key;
- #ifdef WOLFSSL_STATIC_EPHEMERAL
- ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE25519, kse->key);
- if (ret != 0)
- #endif
- {
- ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
- }
- }
- }
- if (ret == 0 && kse->pubKey == NULL) {
- /* Allocate space for the public key. */
- kse->pubKey = (byte*)XMALLOC(CURVE25519_KEYSIZE, ssl->heap,
- DYNAMIC_TYPE_PUBLIC_KEY);
- if (kse->pubKey == NULL) {
- WOLFSSL_MSG("GenX25519Key pub memory error");
- ret = MEMORY_E;
- }
- }
- if (ret == 0) {
- /* Export Curve25519 public key. */
- kse->pubKeyLen = CURVE25519_KEYSIZE;
- if (wc_curve25519_export_public_ex(key, kse->pubKey, &kse->pubKeyLen,
- EC25519_LITTLE_ENDIAN) != 0) {
- ret = ECC_EXPORT_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- kse->pubKeyLen = CURVE25519_KEYSIZE; /* always CURVE25519_KEYSIZE */
- }
- #ifdef WOLFSSL_DEBUG_TLS
- if (ret == 0) {
- WOLFSSL_MSG("Public Curve25519 Key");
- WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen);
- }
- #endif
- if (ret != 0) {
- /* Data owned by key share entry otherwise. */
- if (kse->pubKey != NULL) {
- XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- kse->pubKey = NULL;
- }
- if (key != NULL)
- wc_curve25519_free(key);
- if (kse->key != NULL) {
- XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- kse->key = NULL;
- }
- }
- #else
- (void)ssl;
- (void)kse;
- ret = NOT_COMPILED_IN;
- WOLFSSL_ERROR_VERBOSE(ret);
- #endif /* HAVE_CURVE25519 */
- return ret;
- }
- /* Create a key share entry using X448 parameters group.
- * Generates a key pair.
- *
- * ssl The SSL/TLS object.
- * kse The key share entry object.
- * returns 0 on success, otherwise failure.
- */
- static int TLSX_KeyShare_GenX448Key(WOLFSSL *ssl, KeyShareEntry* kse)
- {
- int ret = 0;
- #ifdef HAVE_CURVE448
- curve448_key* key = (curve448_key*)kse->key;
- if (kse->key == NULL) {
- /* Allocate a Curve448 key to hold private key. */
- kse->key = (curve448_key*)XMALLOC(sizeof(curve448_key), ssl->heap,
- DYNAMIC_TYPE_PRIVATE_KEY);
- if (kse->key == NULL) {
- WOLFSSL_MSG("GenX448Key memory error");
- return MEMORY_E;
- }
- /* Make an Curve448 key. */
- ret = wc_curve448_init((curve448_key*)kse->key);
- if (ret == 0) {
- key = (curve448_key*)kse->key;
- #ifdef WOLFSSL_STATIC_EPHEMERAL
- ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE448, kse->key);
- if (ret != 0)
- #endif
- {
- ret = wc_curve448_make_key(ssl->rng, CURVE448_KEY_SIZE, key);
- }
- }
- }
- if (ret == 0 && kse->pubKey == NULL) {
- /* Allocate space for the public key. */
- kse->pubKey = (byte*)XMALLOC(CURVE448_KEY_SIZE, ssl->heap,
- DYNAMIC_TYPE_PUBLIC_KEY);
- if (kse->pubKey == NULL) {
- WOLFSSL_MSG("GenX448Key pub memory error");
- ret = MEMORY_E;
- }
- }
- if (ret == 0) {
- /* Export Curve448 public key. */
- kse->pubKeyLen = CURVE448_KEY_SIZE;
- if (wc_curve448_export_public_ex(key, kse->pubKey, &kse->pubKeyLen,
- EC448_LITTLE_ENDIAN) != 0) {
- ret = ECC_EXPORT_ERROR;
- }
- kse->pubKeyLen = CURVE448_KEY_SIZE; /* always CURVE448_KEY_SIZE */
- }
- #ifdef WOLFSSL_DEBUG_TLS
- if (ret == 0) {
- WOLFSSL_MSG("Public Curve448 Key");
- WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen);
- }
- #endif
- if (ret != 0) {
- /* Data owned by key share entry otherwise. */
- if (kse->pubKey != NULL) {
- XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- kse->pubKey = NULL;
- }
- if (key != NULL)
- wc_curve448_free(key);
- if (kse->key != NULL) {
- XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- kse->key = NULL;
- }
- }
- #else
- (void)ssl;
- (void)kse;
- ret = NOT_COMPILED_IN;
- WOLFSSL_ERROR_VERBOSE(ret);
- #endif /* HAVE_CURVE448 */
- return ret;
- }
- /* Create a key share entry using named elliptic curve parameters group.
- * Generates a key pair.
- *
- * ssl The SSL/TLS object.
- * kse The key share entry object.
- * returns 0 on success, otherwise failure.
- */
- static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
- {
- int ret = 0;
- #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
- word32 keySize = 0;
- word16 curveId = (word16) ECC_CURVE_INVALID;
- ecc_key* eccKey = (ecc_key*)kse->key;
- /* TODO: [TLS13] The key sizes should come from wolfcrypt. */
- /* Translate named group to a curve id. */
- switch (kse->group) {
- #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP256R1:
- curveId = ECC_SECP256R1;
- keySize = 32;
- break;
- #endif /* !NO_ECC_SECP */
- #endif
- #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP384R1:
- curveId = ECC_SECP384R1;
- keySize = 48;
- break;
- #endif /* !NO_ECC_SECP */
- #endif
- #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP521R1:
- curveId = ECC_SECP521R1;
- keySize = 66;
- break;
- #endif /* !NO_ECC_SECP */
- #endif
- default:
- WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
- return BAD_FUNC_ARG;
- }
- if (kse->key == NULL) {
- kse->keyLen = keySize;
- kse->pubKeyLen = keySize * 2 + 1;
- #if defined(WOLFSSL_RENESAS_TSIP_TLS) && (WOLFSSL_RENESAS_TSIP_VER >= 115)
- ret = tsip_Tls13GenEccKeyPair(ssl, kse);
- if (ret != CRYPTOCB_UNAVAILABLE) {
- return ret;
- }
- #endif
- /* Allocate an ECC key to hold private key. */
- kse->key = (byte*)XMALLOC(sizeof(ecc_key), ssl->heap, DYNAMIC_TYPE_ECC);
- if (kse->key == NULL) {
- WOLFSSL_MSG("EccTempKey Memory error");
- return MEMORY_E;
- }
- /* Make an ECC key */
- ret = wc_ecc_init_ex((ecc_key*)kse->key, ssl->heap, ssl->devId);
- if (ret == 0) {
- /* setting eccKey means okay to call wc_ecc_free */
- eccKey = (ecc_key*)kse->key;
- #ifdef WOLFSSL_STATIC_EPHEMERAL
- ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_ECDH, kse->key);
- if (ret != 0)
- #endif
- {
- /* set curve info for EccMakeKey "peer" info */
- ret = wc_ecc_set_curve(eccKey, kse->keyLen, curveId);
- if (ret == 0) {
- /* Generate ephemeral ECC key */
- /* For async this is called once and when event is done, the
- * provided buffers in key be populated.
- * Final processing is x963 key export below. */
- ret = EccMakeKey(ssl, eccKey, eccKey);
- }
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (ret == WC_PENDING_E)
- return ret;
- #endif
- }
- }
- }
- if (ret == 0 && kse->pubKey == NULL) {
- /* Allocate space for the public key */
- kse->pubKey = (byte*)XMALLOC(kse->pubKeyLen, ssl->heap,
- DYNAMIC_TYPE_PUBLIC_KEY);
- if (kse->pubKey == NULL) {
- WOLFSSL_MSG("Key data Memory error");
- ret = MEMORY_E;
- }
- }
- if (ret == 0) {
- XMEMSET(kse->pubKey, 0, kse->pubKeyLen);
- /* Export public key. */
- PRIVATE_KEY_UNLOCK();
- if (wc_ecc_export_x963(eccKey, kse->pubKey, &kse->pubKeyLen) != 0) {
- ret = ECC_EXPORT_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- PRIVATE_KEY_LOCK();
- }
- #ifdef WOLFSSL_DEBUG_TLS
- if (ret == 0) {
- WOLFSSL_MSG("Public ECC Key");
- WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen);
- }
- #endif
- if (ret != 0) {
- /* Cleanup on error, otherwise data owned by key share entry */
- if (kse->pubKey != NULL) {
- XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- kse->pubKey = NULL;
- }
- if (eccKey != NULL)
- wc_ecc_free(eccKey);
- if (kse->key != NULL) {
- XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- kse->key = NULL;
- }
- }
- #else
- (void)ssl;
- (void)kse;
- ret = NOT_COMPILED_IN;
- WOLFSSL_ERROR_VERBOSE(ret);
- #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
- return ret;
- }
- #ifdef HAVE_PQC
- #ifdef WOLFSSL_WC_KYBER
- static int kyber_id2type(int id, int *type)
- {
- int ret = 0;
- switch (id) {
- #ifdef WOLFSSL_KYBER512
- case WOLFSSL_KYBER_LEVEL1:
- *type = KYBER512;
- break;
- #endif
- #ifdef WOLFSSL_KYBER768
- case WOLFSSL_KYBER_LEVEL3:
- *type = KYBER768;
- break;
- #endif
- #ifdef WOLFSSL_KYBER1024
- case WOLFSSL_KYBER_LEVEL5:
- *type = KYBER1024;
- break;
- #endif
- default:
- ret = NOT_COMPILED_IN;
- break;
- }
- return ret;
- }
- #elif defined(HAVE_LIBOQS)
- /* Transform a group ID into an OQS Algorithm name as a string. */
- static const char* OQS_ID2name(int id)
- {
- switch (id) {
- case WOLFSSL_KYBER_LEVEL1: return OQS_KEM_alg_kyber_512;
- case WOLFSSL_KYBER_LEVEL3: return OQS_KEM_alg_kyber_768;
- case WOLFSSL_KYBER_LEVEL5: return OQS_KEM_alg_kyber_1024;
- case WOLFSSL_KYBER_90S_LEVEL1: return OQS_KEM_alg_kyber_512_90s;
- case WOLFSSL_KYBER_90S_LEVEL3: return OQS_KEM_alg_kyber_768_90s;
- case WOLFSSL_KYBER_90S_LEVEL5: return OQS_KEM_alg_kyber_1024_90s;
- default: break;
- }
- return NULL;
- }
- #endif /* HAVE_LIBOQS */
- typedef struct PqcHybridMapping {
- int hybrid;
- int ecc;
- int pqc;
- } PqcHybridMapping;
- static const PqcHybridMapping pqc_hybrid_mapping[] = {
- {.hybrid = WOLFSSL_P256_KYBER_LEVEL1, .ecc = WOLFSSL_ECC_SECP256R1,
- .pqc = WOLFSSL_KYBER_LEVEL1},
- {.hybrid = WOLFSSL_P384_KYBER_LEVEL3, .ecc = WOLFSSL_ECC_SECP384R1,
- .pqc = WOLFSSL_KYBER_LEVEL3},
- {.hybrid = WOLFSSL_P521_KYBER_LEVEL5, .ecc = WOLFSSL_ECC_SECP521R1,
- .pqc = WOLFSSL_KYBER_LEVEL5},
- {.hybrid = WOLFSSL_P256_KYBER_90S_LEVEL1, .ecc = WOLFSSL_ECC_SECP256R1,
- .pqc = WOLFSSL_KYBER_90S_LEVEL1},
- {.hybrid = WOLFSSL_P384_KYBER_90S_LEVEL3, .ecc = WOLFSSL_ECC_SECP384R1,
- .pqc = WOLFSSL_KYBER_90S_LEVEL3},
- {.hybrid = WOLFSSL_P521_KYBER_90S_LEVEL5, .ecc = WOLFSSL_ECC_SECP521R1,
- .pqc = WOLFSSL_KYBER_90S_LEVEL5},
- {.hybrid = 0, .ecc = 0, .pqc = 0}
- };
- /* This will map an ecc-pqs hybrid group into its ecc group and pqc kem group.
- * If it cannot find a mapping then *pqc is set to group. ecc is optional. */
- static void findEccPqc(int *ecc, int *pqc, int group)
- {
- int i;
- if (pqc == NULL) {
- return;
- }
- *pqc = 0;
- if (ecc != NULL) {
- *ecc = 0;
- }
- for (i = 0; pqc_hybrid_mapping[i].hybrid != 0; i++) {
- if (pqc_hybrid_mapping[i].hybrid == group) {
- *pqc = pqc_hybrid_mapping[i].pqc;
- if (ecc != NULL) {
- *ecc = pqc_hybrid_mapping[i].ecc;
- }
- break;
- }
- }
- if (*pqc == 0) {
- /* It is not a hybrid, so maybe its simple. */
- *pqc = group;
- }
- }
- /* Create a key share entry using liboqs parameters group.
- * Generates a key pair.
- *
- * ssl The SSL/TLS object.
- * kse The key share entry object.
- * returns 0 on success, otherwise failure.
- */
- #ifdef WOLFSSL_WC_KYBER
- static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse)
- {
- int ret = 0;
- int type = 0;
- KyberKey kem[1];
- byte* pubKey = NULL;
- byte* privKey = NULL;
- KeyShareEntry *ecc_kse = NULL;
- int oqs_group = 0;
- int ecc_group = 0;
- word32 privSz = 0;
- word32 pubSz = 0;
- findEccPqc(&ecc_group, &oqs_group, kse->group);
- ret = kyber_id2type(oqs_group, &type);
- if (ret == NOT_COMPILED_IN) {
- WOLFSSL_MSG("Invalid Kyber algorithm specified.");
- ret = BAD_FUNC_ARG;
- }
- if (ret == 0) {
- ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId);
- if (ret != 0) {
- WOLFSSL_MSG("Failed to intialize Kyber Key.");
- }
- }
- if (ret == 0) {
- ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (ecc_kse == NULL) {
- WOLFSSL_MSG("ecc_kse memory allocation failure");
- ret = MEMORY_ERROR;
- }
- }
- if (ret == 0) {
- XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
- ret = wc_KyberKey_PrivateKeySize(kem, &privSz);
- }
- if (ret == 0) {
- ret = wc_KyberKey_PublicKeySize(kem, &pubSz);
- }
- if (ret == 0 && ecc_group != 0) {
- ecc_kse->group = ecc_group;
- ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
- /* If fail, no error message, TLSX_KeyShare_GenEccKey will do it. */
- }
- if (ret == 0) {
- pubKey = (byte*)XMALLOC(ecc_kse->pubKeyLen + pubSz, ssl->heap,
- DYNAMIC_TYPE_PUBLIC_KEY);
- if (pubKey == NULL) {
- WOLFSSL_MSG("pubkey memory allocation failure");
- ret = MEMORY_ERROR;
- }
- }
- if (ret == 0) {
- privKey = (byte*)XMALLOC(privSz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- if (privKey == NULL) {
- WOLFSSL_MSG("privkey memory allocation failure");
- ret = MEMORY_ERROR;
- }
- }
- if (ret == 0) {
- ret = wc_KyberKey_MakeKey(kem, ssl->rng);
- if (ret != 0) {
- WOLFSSL_MSG("lKyber keygen failure");
- }
- }
- if (ret == 0) {
- ret = wc_KyberKey_EncodePublicKey(kem, pubKey + ecc_kse->pubKeyLen,
- pubSz);
- }
- if (ret == 0) {
- ret = wc_KyberKey_EncodePrivateKey(kem, privKey, privSz);
- }
- if (ret == 0) {
- XMEMCPY(pubKey, ecc_kse->pubKey, ecc_kse->pubKeyLen);
- kse->pubKey = pubKey;
- kse->pubKeyLen = ecc_kse->pubKeyLen + pubSz;
- pubKey = NULL;
- /* Note we are saving the OQS private key and ECC private key
- * separately. That's because the ECC private key is not simply a
- * buffer. Its is an ecc_key struct.
- */
- kse->privKey = privKey;
- privKey = NULL;
- kse->key = ecc_kse->key;
- ecc_kse->key = NULL;
- }
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_MSG("Public Kyber Key");
- WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen );
- #endif
- wc_KyberKey_Free(kem);
- TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
- if (pubKey != NULL)
- XFREE(pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- if (privKey != NULL)
- XFREE(privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- return ret;
- }
- #elif defined(HAVE_LIBOQS)
- static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse)
- {
- int ret = 0;
- const char* algName = NULL;
- OQS_KEM* kem = NULL;
- byte* pubKey = NULL;
- byte* privKey = NULL;
- KeyShareEntry *ecc_kse = NULL;
- int oqs_group = 0;
- int ecc_group = 0;
- findEccPqc(&ecc_group, &oqs_group, kse->group);
- algName = OQS_ID2name(oqs_group);
- if (algName == NULL) {
- WOLFSSL_MSG("Invalid OQS algorithm specified.");
- return BAD_FUNC_ARG;
- }
- kem = OQS_KEM_new(algName);
- if (kem == NULL) {
- WOLFSSL_MSG("Error creating OQS KEM, ensure algorithm support"
- "was enabled in liboqs.");
- return BAD_FUNC_ARG;
- }
- ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (ecc_kse == NULL) {
- WOLFSSL_MSG("ecc_kse memory allocation failure");
- ret = MEMORY_ERROR;
- }
- if (ret == 0) {
- XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
- }
- if (ret == 0 && ecc_group != 0) {
- ecc_kse->group = ecc_group;
- ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
- /* If fail, no error message, TLSX_KeyShare_GenEccKey will do it. */
- }
- if (ret == 0) {
- pubKey = (byte*)XMALLOC(ecc_kse->pubKeyLen + kem->length_public_key,
- ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- if (pubKey == NULL) {
- WOLFSSL_MSG("pubkey memory allocation failure");
- ret = MEMORY_ERROR;
- }
- }
- if (ret == 0) {
- privKey = (byte*)XMALLOC(kem->length_secret_key,
- ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- if (privKey == NULL) {
- WOLFSSL_MSG("privkey memory allocation failure");
- ret = MEMORY_ERROR;
- }
- }
- if (ret == 0) {
- if (OQS_KEM_keypair(kem, pubKey + ecc_kse->pubKeyLen, privKey) ==
- OQS_SUCCESS) {
- XMEMCPY(pubKey, ecc_kse->pubKey, ecc_kse->pubKeyLen);
- kse->pubKey = pubKey;
- kse->pubKeyLen = ecc_kse->pubKeyLen +
- (word32) kem->length_public_key;
- pubKey = NULL;
- /* Note we are saving the OQS private key and ECC private key
- * separately. That's because the ECC private key is not simply a
- * buffer. Its is an ecc_key struct.
- */
- kse->privKey = privKey;
- privKey = NULL;
- kse->key = ecc_kse->key;
- ecc_kse->key = NULL;
- ret = 0;
- }
- else {
- WOLFSSL_MSG("liboqs keygen failure");
- ret = BAD_FUNC_ARG;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- }
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_MSG("Public liboqs Key");
- WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen);
- #endif
- OQS_KEM_free(kem);
- TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
- if (pubKey != NULL)
- XFREE(pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- if (privKey != NULL)
- XFREE(privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- return ret;
- }
- #elif defined(HAVE_PQM4)
- static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse)
- {
- /* This assumes KYBER LEVEL 1 (512) implementation is compiled in. */
- int ret = 0;
- byte* pubKey = NULL;
- byte* privKey = NULL;
- KeyShareEntry *ecc_kse = NULL;
- int oqs_group = 0;
- int ecc_group = 0;
- findEccPqc(&ecc_group, &oqs_group, kse->group);
- ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (ecc_kse == NULL) {
- WOLFSSL_MSG("ecc_kse memory allocation failure");
- ret = MEMORY_ERROR;
- }
- if (ret == 0) {
- XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
- }
- if (ret == 0 && ecc_group != 0) {
- ecc_kse->group = ecc_group;
- ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
- /* If fail, no error message, TLSX_KeyShare_GenEccKey will do it. */
- }
- if (ret == 0) {
- pubKey = (byte*)XMALLOC(ecc_kse->pubKeyLen + PQM4_PUBLIC_KEY_LENGTH,
- ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- if (pubKey == NULL) {
- WOLFSSL_MSG("pubkey memory allocation failure");
- ret = MEMORY_ERROR;
- }
- }
- if (ret == 0) {
- privKey = (byte*)XMALLOC(PQM4_PRIVATE_KEY_LENGTH,
- ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- if (privKey == NULL) {
- WOLFSSL_MSG("privkey memory allocation failure");
- ret = MEMORY_ERROR;
- }
- }
- if (ret == 0) {
- if (crypto_kem_keypair(pubKey + ecc_kse->pubKeyLen, privKey) == 0) {
- XMEMCPY(pubKey, ecc_kse->pubKey, ecc_kse->pubKeyLen);
- kse->pubKey = pubKey;
- kse->pubKeyLen = ecc_kse->pubKeyLen +
- (word32) PQM4_PUBLIC_KEY_LENGTH;
- pubKey = NULL;
- /* Note we are saving the PQ private key and ECC private key
- * separately. That's because the ECC private key is not simply a
- * buffer. Its is an ecc_key struct.
- */
- kse->privKey = privKey;
- privKey = NULL;
- kse->key = ecc_kse->key;
- ecc_kse->key = NULL;
- ret = 0;
- }
- else {
- WOLFSSL_MSG("liboqs keygen failure");
- ret = BAD_FUNC_ARG;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- }
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_MSG("Public PQM4 Key");
- WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen );
- #endif
- TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
- if (pubKey != NULL)
- XFREE(pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- if (privKey != NULL)
- XFREE(privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- return ret;
- }
- #endif /* HAVE_PQM4 */
- #endif /* HAVE_PQC */
- /* Generate a secret/key using the key share entry.
- *
- * ssl The SSL/TLS object.
- * kse The key share entry holding peer data.
- */
- static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse)
- {
- int ret;
- /* Named FFDHE groups have a bit set to identify them. */
- if (WOLFSSL_NAMED_GROUP_IS_FFHDE(kse->group))
- ret = TLSX_KeyShare_GenDhKey(ssl, kse);
- else if (kse->group == WOLFSSL_ECC_X25519)
- ret = TLSX_KeyShare_GenX25519Key(ssl, kse);
- else if (kse->group == WOLFSSL_ECC_X448)
- ret = TLSX_KeyShare_GenX448Key(ssl, kse);
- #ifdef HAVE_PQC
- else if (WOLFSSL_NAMED_GROUP_IS_PQC(kse->group))
- ret = TLSX_KeyShare_GenPqcKey(ssl, kse);
- #endif
- else
- ret = TLSX_KeyShare_GenEccKey(ssl, kse);
- #ifdef WOLFSSL_ASYNC_CRYPT
- kse->lastRet = ret;
- #endif
- return ret;
- }
- /* Free the key share dynamic data.
- *
- * list The linked list of key share entry objects.
- * heap The heap used for allocation.
- */
- static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
- {
- KeyShareEntry* current;
- while ((current = list) != NULL) {
- list = current->next;
- if (WOLFSSL_NAMED_GROUP_IS_FFHDE(current->group)) {
- #ifndef NO_DH
- wc_FreeDhKey((DhKey*)current->key);
- #endif
- }
- else if (current->group == WOLFSSL_ECC_X25519) {
- #ifdef HAVE_CURVE25519
- wc_curve25519_free((curve25519_key*)current->key);
- #endif
- }
- else if (current->group == WOLFSSL_ECC_X448) {
- #ifdef HAVE_CURVE448
- wc_curve448_free((curve448_key*)current->key);
- #endif
- }
- #ifdef HAVE_PQC
- else if (WOLFSSL_NAMED_GROUP_IS_PQC(current->group) &&
- current->key != NULL) {
- ForceZero((byte*)current->key, current->keyLen);
- }
- #endif
- else {
- #ifdef HAVE_ECC
- wc_ecc_free((ecc_key*)current->key);
- #endif
- }
- XFREE(current->key, heap, DYNAMIC_TYPE_PRIVATE_KEY);
- #if !defined(NO_DH) && (!defined(NO_CERTS) || !defined(NO_PSK))
- XFREE(current->privKey, heap, DYNAMIC_TYPE_PRIVATE_KEY);
- #endif
- XFREE(current->pubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
- XFREE(current->ke, heap, DYNAMIC_TYPE_PUBLIC_KEY);
- XFREE(current, heap, DYNAMIC_TYPE_TLSX);
- }
- (void)heap;
- }
- /* Get the size of the encoded key share extension.
- *
- * list The linked list of key share extensions.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes of the encoded key share extension.
- */
- static word16 TLSX_KeyShare_GetSize(KeyShareEntry* list, byte msgType)
- {
- word16 len = 0;
- byte isRequest = (msgType == client_hello);
- KeyShareEntry* current;
- /* The named group the server wants to use. */
- if (msgType == hello_retry_request)
- return OPAQUE16_LEN;
- /* List of key exchange groups. */
- if (isRequest)
- len += OPAQUE16_LEN;
- while ((current = list) != NULL) {
- list = current->next;
- if (!isRequest && current->pubKey == NULL)
- continue;
- len += (word16)(KE_GROUP_LEN + OPAQUE16_LEN + current->pubKeyLen);
- }
- return len;
- }
- /* Writes the key share extension into the output buffer.
- * Assumes that the the output buffer is big enough to hold data.
- *
- * list The linked list of key share entries.
- * output The buffer to write into.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes written into the buffer.
- */
- static word16 TLSX_KeyShare_Write(KeyShareEntry* list, byte* output,
- byte msgType)
- {
- word16 i = 0;
- byte isRequest = (msgType == client_hello);
- KeyShareEntry* current;
- if (msgType == hello_retry_request) {
- c16toa(list->group, output);
- return OPAQUE16_LEN;
- }
- /* ClientHello has a list but ServerHello is only the chosen. */
- if (isRequest)
- i += OPAQUE16_LEN;
- /* Write out all in the list. */
- while ((current = list) != NULL) {
- list = current->next;
- if (!isRequest && current->pubKey == NULL)
- continue;
- c16toa(current->group, &output[i]);
- i += KE_GROUP_LEN;
- c16toa((word16)(current->pubKeyLen), &output[i]);
- i += OPAQUE16_LEN;
- XMEMCPY(&output[i], current->pubKey, current->pubKeyLen);
- i += (word16)current->pubKeyLen;
- }
- /* Write the length of the list if required. */
- if (isRequest)
- c16toa(i - OPAQUE16_LEN, output);
- return i;
- }
- /* Process the DH key share extension on the client side.
- *
- * ssl The SSL/TLS object.
- * keyShareEntry The key share entry object to use to calculate shared secret.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
- {
- int ret = 0;
- #if !defined(NO_DH) && (!defined(NO_CERTS) || !defined(NO_PSK))
- word32 pSz = 0;
- DhKey* dhKey = (DhKey*)keyShareEntry->key;
- #ifdef HAVE_PUBLIC_FFDHE
- const DhParams* params = NULL;
- switch (keyShareEntry->group) {
- #ifdef HAVE_FFDHE_2048
- case WOLFSSL_FFDHE_2048:
- params = wc_Dh_ffdhe2048_Get();
- break;
- #endif
- #ifdef HAVE_FFDHE_3072
- case WOLFSSL_FFDHE_3072:
- params = wc_Dh_ffdhe3072_Get();
- break;
- #endif
- #ifdef HAVE_FFDHE_4096
- case WOLFSSL_FFDHE_4096:
- params = wc_Dh_ffdhe4096_Get();
- break;
- #endif
- #ifdef HAVE_FFDHE_6144
- case WOLFSSL_FFDHE_6144:
- params = wc_Dh_ffdhe6144_Get();
- break;
- #endif
- #ifdef HAVE_FFDHE_8192
- case WOLFSSL_FFDHE_8192:
- params = wc_Dh_ffdhe8192_Get();
- break;
- #endif
- default:
- break;
- }
- if (params == NULL) {
- WOLFSSL_ERROR_VERBOSE(PEER_KEY_ERROR);
- return PEER_KEY_ERROR;
- }
- pSz = params->p_len;
- #else
- ret = wc_DhGetNamedKeyParamSize(keyShareEntry->group, &pSz, NULL, NULL);
- if (ret != 0 || pSz == 0) {
- WOLFSSL_ERROR_VERBOSE(PEER_KEY_ERROR);
- return PEER_KEY_ERROR;
- }
- #endif
- /* if DhKey is not setup, do it now */
- if (keyShareEntry->key == NULL) {
- keyShareEntry->key = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap,
- DYNAMIC_TYPE_DH);
- if (keyShareEntry->key == NULL)
- return MEMORY_E;
- /* Setup Key */
- ret = wc_InitDhKey_ex((DhKey*)keyShareEntry->key, ssl->heap, ssl->devId);
- if (ret == 0) {
- dhKey = (DhKey*)keyShareEntry->key;
- /* Set key */
- #ifdef HAVE_PUBLIC_FFDHE
- ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g,
- params->g_len);
- #else
- ret = wc_DhSetNamedKey(dhKey, keyShareEntry->group);
- #endif
- }
- }
- if (ret == 0
- #ifdef WOLFSSL_ASYNC_CRYPT
- && keyShareEntry->lastRet == 0 /* don't enter here if WC_PENDING_E */
- #endif
- ) {
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_MSG("Peer DH Key");
- WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
- #endif
- ssl->options.dhKeySz = (word16)pSz;
- /* Derive secret from private key and peer's public key. */
- ret = DhAgree(ssl, dhKey,
- (const byte*)keyShareEntry->privKey, keyShareEntry->keyLen, /* our private */
- keyShareEntry->ke, keyShareEntry->keLen, /* peer's public key */
- ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, /* secret */
- NULL, 0
- );
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (ret == WC_PENDING_E) {
- return ret;
- }
- #endif
- }
- /* RFC 8446 Section 7.4.1:
- * ... left-padded with zeros up to the size of the prime. ...
- */
- if (ret == 0 && (word32)ssl->options.dhKeySz > ssl->arrays->preMasterSz) {
- word32 diff = (word32)ssl->options.dhKeySz - ssl->arrays->preMasterSz;
- XMEMMOVE(ssl->arrays->preMasterSecret + diff,
- ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
- XMEMSET(ssl->arrays->preMasterSecret, 0, diff);
- ssl->arrays->preMasterSz = ssl->options.dhKeySz;
- }
- /* done with key share, release resources */
- if (dhKey)
- wc_FreeDhKey(dhKey);
- if (keyShareEntry->key) {
- XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_DH);
- keyShareEntry->key = NULL;
- }
- if (keyShareEntry->privKey != NULL) {
- XFREE(keyShareEntry->privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- keyShareEntry->privKey = NULL;
- }
- if (keyShareEntry->pubKey != NULL) {
- XFREE(keyShareEntry->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- keyShareEntry->pubKey = NULL;
- }
- XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- keyShareEntry->ke = NULL;
- #else
- (void)ssl;
- (void)keyShareEntry;
- ret = PEER_KEY_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- #endif
- return ret;
- }
- /* Process the X25519 key share extension on the client side.
- *
- * ssl The SSL/TLS object.
- * keyShareEntry The key share entry object to use to calculate shared secret.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl,
- KeyShareEntry* keyShareEntry)
- {
- int ret;
- #ifdef HAVE_CURVE25519
- curve25519_key* key = (curve25519_key*)keyShareEntry->key;
- curve25519_key* peerX25519Key;
- #ifdef HAVE_ECC
- if (ssl->peerEccKey != NULL) {
- wc_ecc_free(ssl->peerEccKey);
- ssl->peerEccKey = NULL;
- ssl->peerEccKeyPresent = 0;
- }
- #endif
- peerX25519Key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (peerX25519Key == NULL) {
- WOLFSSL_MSG("PeerEccKey Memory error");
- return MEMORY_ERROR;
- }
- ret = wc_curve25519_init(peerX25519Key);
- if (ret != 0) {
- XFREE(peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
- return ret;
- }
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_MSG("Peer Curve25519 Key");
- WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
- #endif
- if (wc_curve25519_check_public(keyShareEntry->ke, keyShareEntry->keLen,
- EC25519_LITTLE_ENDIAN) != 0) {
- ret = ECC_PEERKEY_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- if (ret == 0) {
- if (wc_curve25519_import_public_ex(keyShareEntry->ke,
- keyShareEntry->keLen, peerX25519Key,
- EC25519_LITTLE_ENDIAN) != 0) {
- ret = ECC_PEERKEY_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- }
- if (ret == 0) {
- ssl->ecdhCurveOID = ECC_X25519_OID;
- ret = wc_curve25519_shared_secret_ex(key, peerX25519Key,
- ssl->arrays->preMasterSecret,
- &ssl->arrays->preMasterSz,
- EC25519_LITTLE_ENDIAN);
- }
- wc_curve25519_free(peerX25519Key);
- XFREE(peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
- wc_curve25519_free((curve25519_key*)keyShareEntry->key);
- if (keyShareEntry->key != NULL) {
- XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- keyShareEntry->key = NULL;
- }
- #else
- (void)ssl;
- (void)keyShareEntry;
- ret = PEER_KEY_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- #endif /* HAVE_CURVE25519 */
- return ret;
- }
- /* Process the X448 key share extension on the client side.
- *
- * ssl The SSL/TLS object.
- * keyShareEntry The key share entry object to use to calculate shared secret.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
- {
- int ret;
- #ifdef HAVE_CURVE448
- curve448_key* key = (curve448_key*)keyShareEntry->key;
- curve448_key* peerX448Key;
- #ifdef HAVE_ECC
- if (ssl->peerEccKey != NULL) {
- wc_ecc_free(ssl->peerEccKey);
- ssl->peerEccKey = NULL;
- ssl->peerEccKeyPresent = 0;
- }
- #endif
- peerX448Key = (curve448_key*)XMALLOC(sizeof(curve448_key), ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (peerX448Key == NULL) {
- WOLFSSL_MSG("PeerEccKey Memory error");
- return MEMORY_ERROR;
- }
- ret = wc_curve448_init(peerX448Key);
- if (ret != 0) {
- XFREE(peerX448Key, ssl->heap, DYNAMIC_TYPE_TLSX);
- return ret;
- }
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_MSG("Peer Curve448 Key");
- WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
- #endif
- if (wc_curve448_check_public(keyShareEntry->ke, keyShareEntry->keLen,
- EC448_LITTLE_ENDIAN) != 0) {
- ret = ECC_PEERKEY_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- if (ret == 0) {
- if (wc_curve448_import_public_ex(keyShareEntry->ke,
- keyShareEntry->keLen, peerX448Key,
- EC448_LITTLE_ENDIAN) != 0) {
- ret = ECC_PEERKEY_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- }
- if (ret == 0) {
- ssl->ecdhCurveOID = ECC_X448_OID;
- ret = wc_curve448_shared_secret_ex(key, peerX448Key,
- ssl->arrays->preMasterSecret,
- &ssl->arrays->preMasterSz,
- EC448_LITTLE_ENDIAN);
- }
- wc_curve448_free(peerX448Key);
- XFREE(peerX448Key, ssl->heap, DYNAMIC_TYPE_TLSX);
- wc_curve448_free((curve448_key*)keyShareEntry->key);
- if (keyShareEntry->key != NULL) {
- XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
- keyShareEntry->key = NULL;
- }
- #else
- (void)ssl;
- (void)keyShareEntry;
- ret = PEER_KEY_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- #endif /* HAVE_CURVE448 */
- return ret;
- }
- /* Process the ECC key share extension on the client side.
- *
- * ssl The SSL/TLS object.
- * keyShareEntry The key share entry object to use to calculate shared secret.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
- {
- int ret = 0;
- #ifdef HAVE_ECC
- int curveId = ECC_CURVE_INVALID;
- ecc_key* eccKey = (ecc_key*)keyShareEntry->key;
- /* find supported curve */
- switch (keyShareEntry->group) {
- #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP256R1:
- curveId = ECC_SECP256R1;
- break;
- #endif /* !NO_ECC_SECP */
- #endif
- #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP384R1:
- curveId = ECC_SECP384R1;
- break;
- #endif /* !NO_ECC_SECP */
- #endif
- #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP521R1:
- curveId = ECC_SECP521R1;
- break;
- #endif /* !NO_ECC_SECP */
- #endif
- #if defined(HAVE_X448) && ECC_MIN_KEY_SZ <= 448
- case WOLFSSL_ECC_X448:
- curveId = ECC_X448;
- break;
- #endif
- default:
- /* unsupported curve */
- WOLFSSL_ERROR_VERBOSE(ECC_PEERKEY_ERROR);
- return ECC_PEERKEY_ERROR;
- }
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (keyShareEntry->lastRet == 0) /* don't enter here if WC_PENDING_E */
- #endif
- {
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_MSG("Peer ECC Key");
- WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
- #endif
- if (ssl->peerEccKey != NULL) {
- wc_ecc_free(ssl->peerEccKey);
- XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
- ssl->peerEccKeyPresent = 0;
- }
- #if defined(WOLFSSL_RENESAS_TSIP_TLS) && (WOLFSSL_RENESAS_TSIP_VER >= 115)
- ret = tsip_Tls13GenSharedSecret(ssl, keyShareEntry);
- if (ret != CRYPTOCB_UNAVAILABLE) {
- return ret;
- }
- ret = 0;
- #endif
- ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap,
- DYNAMIC_TYPE_ECC);
- if (ssl->peerEccKey == NULL) {
- WOLFSSL_MSG("PeerEccKey Memory error");
- ret = MEMORY_ERROR;
- }
- if (ret == 0) {
- ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, ssl->devId);
- }
- /* Point is validated by import function. */
- if (ret == 0) {
- ret = wc_ecc_import_x963_ex(keyShareEntry->ke, keyShareEntry->keLen,
- ssl->peerEccKey, curveId);
- if (ret != 0) {
- ret = ECC_PEERKEY_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- }
- if (ret == 0) {
- ssl->ecdhCurveOID = ssl->peerEccKey->dp->oidSum;
- ssl->peerEccKeyPresent = 1;
- }
- }
- if (ret == 0 && eccKey == NULL)
- ret = BAD_FUNC_ARG;
- if (ret == 0) {
- ret = EccSharedSecret(ssl, eccKey, ssl->peerEccKey,
- keyShareEntry->ke, &keyShareEntry->keLen,
- ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz,
- ssl->options.side
- );
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (ret == WC_PENDING_E)
- return ret;
- #endif
- }
- /* done with key share, release resources */
- if (ssl->peerEccKey != NULL
- #ifdef HAVE_PK_CALLBACKS
- && ssl->ctx->EccSharedSecretCb == NULL
- #endif
- ) {
- wc_ecc_free(ssl->peerEccKey);
- XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
- ssl->peerEccKey = NULL;
- ssl->peerEccKeyPresent = 0;
- }
- if (keyShareEntry->key) {
- wc_ecc_free((ecc_key*)keyShareEntry->key);
- XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_ECC);
- keyShareEntry->key = NULL;
- }
- XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- keyShareEntry->ke = NULL;
- #else
- (void)ssl;
- (void)keyShareEntry;
- ret = PEER_KEY_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- #endif /* HAVE_ECC */
- return ret;
- }
- #ifdef HAVE_PQC
- #ifdef WOLFSSL_WC_KYBER
- /* Process the Kyber key share extension on the client side.
- *
- * ssl The SSL/TLS object.
- * keyShareEntry The key share entry object to use to calculate shared secret.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_KeyShare_ProcessPqc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
- {
- int ret = 0;
- int type;
- KyberKey kem[1];
- byte* sharedSecret = NULL;
- word32 sharedSecretLen = 0;
- int oqs_group = 0;
- int ecc_group = 0;
- ecc_key eccpubkey;
- word32 outlen = 0;
- word32 privSz = 0;
- word32 ctSz = 0;
- word32 ssSz = 0;
- if (keyShareEntry->ke == NULL) {
- WOLFSSL_MSG("Invalid OQS algorithm specified.");
- return BAD_FUNC_ARG;
- }
- if (ssl->options.side == WOLFSSL_SERVER_END) {
- /* I am the server, the shared secret has already been generated and
- * is in keyShareEntry->ke; copy it to the pre-master secret
- * pre-allocated buffer. */
- if (keyShareEntry->keLen > ENCRYPT_LEN) {
- WOLFSSL_MSG("shared secret is too long.");
- return LENGTH_ERROR;
- }
- XMEMCPY(ssl->arrays->preMasterSecret, keyShareEntry->ke,
- keyShareEntry->keLen);
- ssl->arrays->preMasterSz = keyShareEntry->keLen;
- XFREE(keyShareEntry->ke, sl->heap, DYNAMIC_TYPE_SECRET)
- keyShareEntry->ke = NULL;
- keyShareEntry->keLen = 0;
- return 0;
- }
- /* I am the client, the ciphertext is in keyShareEntry->ke */
- findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group);
- ret = kyber_id2type(oqs_group, &type);
- if (ret != 0) {
- WOLFSSL_MSG("Invalid OQS algorithm specified.");
- ret = BAD_FUNC_ARG;
- }
- if (ret == 0) {
- ret = wc_KyberKey_Init(type, kem, ssl->heap, INVALID_DEVID);
- if (ret != 0) {
- WOLFSSL_MSG("Error creating Kyber KEM");
- }
- }
- if (ret == 0) {
- ret = wc_KyberKey_SharedSecretSize(kem, &ssSz);
- }
- if (ret == 0) {
- sharedSecretLen = ssSz;
- switch (ecc_group) {
- case WOLFSSL_ECC_SECP256R1:
- sharedSecretLen += 32;
- outlen = 32;
- break;
- case WOLFSSL_ECC_SECP384R1:
- sharedSecretLen += 48;
- outlen = 48;
- break;
- case WOLFSSL_ECC_SECP521R1:
- sharedSecretLen += 66;
- outlen = 66;
- break;
- default:
- break;
- }
- ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId);
- if (ret != 0) {
- WOLFSSL_MSG("Memory allocation error.");
- ret = MEMORY_E;
- }
- }
- if (ret == 0) {
- sharedSecret = (byte*)XMALLOC(sharedSecretLen, ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (sharedSecret == NULL) {
- WOLFSSL_MSG("Memory allocation error.");
- ret = MEMORY_E;
- }
- }
- if (ret == 0) {
- ret = wc_KyberKey_CipherTextSize(kem, &ctSz);
- }
- if (ret == 0) {
- ret = wc_KyberKey_PrivateKeySize(kem, &privSz);
- }
- if (ret == 0) {
- ret = wc_KyberKey_DecodePrivateKey(kem, keyShareEntry->privKey, privSz);
- }
- if (ret == 0) {
- ret = wc_KyberKey_Decapsulate(kem, sharedSecret + outlen,
- keyShareEntry->ke + keyShareEntry->keLen - ctSz, ctSz);
- if (ret != 0) {
- WOLFSSL_MSG("wc_KyberKey decapsulation failure.");
- ret = BAD_FUNC_ARG;
- }
- }
- if (ecc_group != 0) {
- if (ret == 0) {
- /* Point is validated by import function. */
- ret = wc_ecc_import_x963(keyShareEntry->ke,
- keyShareEntry->keLen - ctSz,
- &eccpubkey);
- if (ret != 0) {
- WOLFSSL_MSG("ECC Public key import error.");
- }
- }
- #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
- (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
- !defined(HAVE_SELFTEST)
- if (ret == 0) {
- ret = wc_ecc_set_rng(keyShareEntry->key, ssl->rng);
- if (ret != 0) {
- WOLFSSL_MSG("Failure to set the ECC private key RNG.");
- }
- }
- #endif
- if (ret == 0) {
- PRIVATE_KEY_UNLOCK();
- ret = wc_ecc_shared_secret(keyShareEntry->key, &eccpubkey,
- sharedSecret, &outlen);
- PRIVATE_KEY_LOCK();
- if (outlen != sharedSecretLen - ssSz) {
- WOLFSSL_MSG("ECC shared secret derivation error.");
- ret = BAD_FUNC_ARG;
- }
- }
- }
- if ((ret == 0) && (sharedSecretLen > ENCRYPT_LEN)) {
- WOLFSSL_MSG("shared secret is too long.");
- ret = LENGTH_ERROR;
- }
- if (ret == 0) {
- /* Copy the shared secret to the pre-master secret pre-allocated
- * buffer. */
- XMEMCPY(ssl->arrays->preMasterSecret, sharedSecret, sharedSecretLen);
- ssl->arrays->preMasterSz = (word32) sharedSecretLen;
- }
- if (sharedSecret != NULL) {
- XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_SECRET);
- }
- wc_ecc_free(&eccpubkey);
- wc_KyberKey_Free(kem);
- return ret;
- }
- #elif defined(HAVE_LIBOQS)
- /* Process the liboqs key share extension on the client side.
- *
- * ssl The SSL/TLS object.
- * keyShareEntry The key share entry object to use to calculate shared secret.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_KeyShare_ProcessPqc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
- {
- int ret = 0;
- const char* algName = NULL;
- OQS_KEM* kem = NULL;
- byte* sharedSecret = NULL;
- word32 sharedSecretLen = 0;
- int oqs_group = 0;
- int ecc_group = 0;
- ecc_key eccpubkey;
- word32 outlen = 0;
- if (keyShareEntry->ke == NULL) {
- WOLFSSL_MSG("Invalid OQS algorithm specified.");
- return BAD_FUNC_ARG;
- }
- if (ssl->options.side == WOLFSSL_SERVER_END) {
- /* I am the server, the shared secret has already been generated and
- * is in keyShareEntry->ke; copy it to the pre-master secret
- * pre-allocated buffer. */
- if (keyShareEntry->keLen > ENCRYPT_LEN) {
- WOLFSSL_MSG("shared secret is too long.");
- WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
- return LENGTH_ERROR;
- }
- XMEMCPY(ssl->arrays->preMasterSecret, keyShareEntry->ke, keyShareEntry->keLen);
- ssl->arrays->preMasterSz = keyShareEntry->keLen;
- XFREE(keyShareEntry->ke, sl->heap, DYNAMIC_TYPE_SECRET)
- keyShareEntry->ke = NULL;
- keyShareEntry->keLen = 0;
- return 0;
- }
- /* I am the client, the ciphertext is in keyShareEntry->ke */
- findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group);
- algName = OQS_ID2name(oqs_group);
- if (algName == NULL) {
- WOLFSSL_MSG("Invalid OQS algorithm specified.");
- WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
- return BAD_FUNC_ARG;
- }
- kem = OQS_KEM_new(algName);
- if (kem == NULL) {
- WOLFSSL_MSG("Error creating OQS KEM, ensure algorithm support"
- "was enabled in liboqs.");
- return MEMORY_E;
- }
- sharedSecretLen = (word32)kem->length_shared_secret;
- switch (ecc_group) {
- case WOLFSSL_ECC_SECP256R1:
- sharedSecretLen += 32;
- outlen = 32;
- break;
- case WOLFSSL_ECC_SECP384R1:
- sharedSecretLen += 48;
- outlen = 48;
- break;
- case WOLFSSL_ECC_SECP521R1:
- sharedSecretLen += 66;
- outlen = 66;
- break;
- default:
- break;
- }
- ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId);
- if (ret != 0) {
- WOLFSSL_MSG("Memory allocation error.");
- return MEMORY_E;
- }
- sharedSecret = (byte*)XMALLOC(sharedSecretLen, ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (sharedSecret == NULL) {
- WOLFSSL_MSG("Memory allocation error.");
- ret = MEMORY_E;
- }
- if (ret == 0 && OQS_KEM_decaps(kem, sharedSecret + outlen,
- keyShareEntry->ke + keyShareEntry->keLen -
- kem->length_ciphertext,
- keyShareEntry->privKey) != OQS_SUCCESS) {
- WOLFSSL_MSG("Liboqs decapsulation failure.");
- ret = BAD_FUNC_ARG;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- if (ecc_group != 0) {
- if (ret == 0) {
- /* Point is validated by import function. */
- ret = wc_ecc_import_x963(keyShareEntry->ke,
- keyShareEntry->keLen -
- (word32)kem->length_ciphertext,
- &eccpubkey);
- if (ret != 0) {
- WOLFSSL_ERROR_VERBOSE(ret);
- WOLFSSL_MSG("ECC Public key import error.");
- }
- }
- #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
- (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
- !defined(HAVE_SELFTEST)
- if (ret == 0) {
- ret = wc_ecc_set_rng(keyShareEntry->key, ssl->rng);
- if (ret != 0) {
- WOLFSSL_MSG("Failure to set the ECC private key RNG.");
- }
- }
- #endif
- if (ret == 0) {
- PRIVATE_KEY_UNLOCK();
- ret = wc_ecc_shared_secret(keyShareEntry->key, &eccpubkey, sharedSecret, &outlen);
- PRIVATE_KEY_LOCK();
- if (outlen != sharedSecretLen - kem->length_shared_secret) {
- WOLFSSL_MSG("ECC shared secret derivation error.");
- ret = BAD_FUNC_ARG;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- }
- }
- if (sharedSecretLen > ENCRYPT_LEN) {
- WOLFSSL_MSG("shared secret is too long.");
- ret = LENGTH_ERROR;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- if (ret == 0) {
- /* Copy the shared secret to the pre-master secret pre-allocated
- * buffer. */
- XMEMCPY(ssl->arrays->preMasterSecret, sharedSecret, sharedSecretLen);
- ssl->arrays->preMasterSz = (word32) sharedSecretLen;
- }
- if (sharedSecret != NULL) {
- XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_SECRET);
- }
- wc_ecc_free(&eccpubkey);
- OQS_KEM_free(kem);
- return ret;
- }
- #elif defined(HAVE_PQM4)
- static int TLSX_KeyShare_ProcessPqc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
- {
- int ret = 0;
- byte* sharedSecret = NULL;
- word32 sharedSecretLen = 0;
- int oqs_group = 0;
- int ecc_group = 0;
- ecc_key eccpubkey;
- word32 outlen = 0;
- if (keyShareEntry->ke == NULL) {
- WOLFSSL_MSG("Invalid OQS algorithm specified.");
- return BAD_FUNC_ARG;
- }
- if (ssl->options.side == WOLFSSL_SERVER_END) {
- /* I am the server, the shared secret has already been generated and
- * is in keyShareEntry->ke; copy it to the pre-master secret
- * pre-allocated buffer. */
- if (keyShareEntry->keLen > ENCRYPT_LEN) {
- WOLFSSL_MSG("shared secret is too long.");
- WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
- return LENGTH_ERROR;
- }
- XMEMCPY(ssl->arrays->preMasterSecret, keyShareEntry->ke, keyShareEntry->keLen);
- ssl->arrays->preMasterSz = keyShareEntry->keLen;
- XFREE(keyShareEntry->ke, sl->heap, DYNAMIC_TYPE_SECRET);
- keyShareEntry->ke = NULL;
- keyShareEntry->keLen = 0;
- return 0;
- }
- /* I am the client, the ciphertext is in keyShareEntry->ke */
- findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group);
- sharedSecretLen = (word32)PQM4_SHARED_SECRET_LENGTH;
- switch (ecc_group) {
- case WOLFSSL_ECC_SECP256R1:
- sharedSecretLen += 32;
- outlen = 32;
- break;
- case WOLFSSL_ECC_SECP384R1:
- sharedSecretLen += 48;
- outlen = 48;
- break;
- case WOLFSSL_ECC_SECP521R1:
- sharedSecretLen += 66;
- outlen = 66;
- break;
- default:
- break;
- }
- ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId);
- if (ret != 0) {
- WOLFSSL_MSG("Memory allocation error.");
- return MEMORY_E;
- }
- sharedSecret = (byte*)XMALLOC(sharedSecretLen, ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (sharedSecret == NULL) {
- WOLFSSL_MSG("Memory allocation error.");
- ret = MEMORY_E;
- }
- if (ret == 0 && crypto_kem_dec(sharedSecret + outlen,
- keyShareEntry->ke + keyShareEntry->keLen -
- PQM4_CIPHERTEXT_LENGTH,
- keyShareEntry->privKey) != 0) {
- WOLFSSL_MSG("PQM4 decapsulation failure.");
- ret = BAD_FUNC_ARG;
- } else {
- WOLFSSL_MSG("PQM4 decapsulation SUCCESS!!!!!");
- }
- if (ecc_group != 0) {
- if (ret == 0) {
- /* Point is validated by import function. */
- ret = wc_ecc_import_x963(keyShareEntry->ke,
- keyShareEntry->keLen -
- (word32)PQM4_CIPHERTEXT_LENGTH,
- &eccpubkey);
- if (ret != 0) {
- WOLFSSL_MSG("ECC Public key import error.");
- }
- }
- #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
- (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
- !defined(HAVE_SELFTEST)
- if (ret == 0) {
- ret = wc_ecc_set_rng(keyShareEntry->key, ssl->rng);
- if (ret != 0) {
- WOLFSSL_MSG("Failure to set the ECC private key RNG.");
- }
- }
- #endif
- if (ret == 0) {
- PRIVATE_KEY_UNLOCK();
- ret = wc_ecc_shared_secret(keyShareEntry->key, &eccpubkey, sharedSecret, &outlen);
- PRIVATE_KEY_LOCK();
- if (outlen != sharedSecretLen - PQM4_SHARED_SECRET_LENGTH) {
- WOLFSSL_MSG("ECC shared secret derivation error.");
- ret = BAD_FUNC_ARG;
- }
- }
- }
- if (sharedSecretLen > ENCRYPT_LEN) {
- WOLFSSL_MSG("shared secret is too long.\n");
- ret = LENGTH_ERROR;
- }
- if (ret == 0) {
- /* Copy the shared secret to the pre-master secret pre-allocated
- * buffer. */
- XMEMCPY(ssl->arrays->preMasterSecret, sharedSecret, sharedSecretLen);
- ssl->arrays->preMasterSz = (word32) sharedSecretLen;
- }
- if (sharedSecret != NULL) {
- XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_SECRET);
- }
- wc_ecc_free(&eccpubkey);
- return ret;
- }
- #endif /* HAVE_PQM4 */
- #endif /* HAVE_PQC */
- /* Process the key share extension on the client side.
- *
- * ssl The SSL/TLS object.
- * keyShareEntry The key share entry object to use to calculate shared secret.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
- {
- int ret;
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- ssl->session->namedGroup = (byte)keyShareEntry->group;
- #endif
- /* reset the pre master secret size */
- if (ssl->arrays->preMasterSz == 0)
- ssl->arrays->preMasterSz = ENCRYPT_LEN;
- /* Use Key Share Data from server. */
- if (WOLFSSL_NAMED_GROUP_IS_FFHDE(keyShareEntry->group))
- ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry);
- else if (keyShareEntry->group == WOLFSSL_ECC_X25519)
- ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry);
- else if (keyShareEntry->group == WOLFSSL_ECC_X448)
- ret = TLSX_KeyShare_ProcessX448(ssl, keyShareEntry);
- #ifdef HAVE_PQC
- else if (WOLFSSL_NAMED_GROUP_IS_PQC(keyShareEntry->group))
- ret = TLSX_KeyShare_ProcessPqc(ssl, keyShareEntry);
- #endif
- else
- ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry);
- #ifdef WOLFSSL_DEBUG_TLS
- if (ret == 0) {
- WOLFSSL_MSG("KE Secret");
- WOLFSSL_BUFFER(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
- }
- #endif
- #ifdef WOLFSSL_ASYNC_CRYPT
- keyShareEntry->lastRet = ret;
- #endif
- return ret;
- }
- /* Parse an entry of the KeyShare extension.
- *
- * ssl The SSL/TLS object.
- * input The extension data.
- * length The length of the extension data.
- * kse The new key share entry object.
- * returns a positive number to indicate amount of data parsed and a negative
- * number on error.
- */
- static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, const byte* input,
- word16 length, KeyShareEntry **kse)
- {
- int ret;
- word16 group;
- word16 keLen;
- int offset = 0;
- byte* ke;
- if (length < OPAQUE16_LEN + OPAQUE16_LEN)
- return BUFFER_ERROR;
- /* Named group */
- ato16(&input[offset], &group);
- offset += OPAQUE16_LEN;
- /* Key exchange data - public key. */
- ato16(&input[offset], &keLen);
- offset += OPAQUE16_LEN;
- if (keLen == 0)
- return INVALID_PARAMETER;
- if (keLen > length - offset)
- return BUFFER_ERROR;
- #ifdef HAVE_PQC
- if (WOLFSSL_NAMED_GROUP_IS_PQC(group) &&
- ssl->options.side == WOLFSSL_SERVER_END) {
- /* For KEMs, the public key is not stored. Casting away const because
- * we know for KEMs, it will be read-only.*/
- ke = (byte *)&input[offset];
- } else
- #endif
- {
- /* Store a copy in the key share object. */
- ke = (byte*)XMALLOC(keLen, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- if (ke == NULL)
- return MEMORY_E;
- XMEMCPY(ke, &input[offset], keLen);
- }
- /* Populate a key share object in the extension. */
- ret = TLSX_KeyShare_Use(ssl, group, keLen, ke, kse);
- if (ret != 0) {
- if (ke != &input[offset]) {
- XFREE(ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- }
- return ret;
- }
- /* Total length of the parsed data. */
- return offset + keLen;
- }
- /* Searches the groups sent for the specified named group.
- *
- * ssl SSL/TLS object.
- * name Group name to match.
- * returns 1 when the extension has the group name and 0 otherwise.
- */
- static int TLSX_KeyShare_Find(WOLFSSL* ssl, word16 group)
- {
- TLSX* extension;
- KeyShareEntry* list;
- extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
- if (extension == NULL) {
- extension = TLSX_Find(ssl->ctx->extensions, TLSX_KEY_SHARE);
- if (extension == NULL)
- return 0;
- }
- list = (KeyShareEntry*)extension->data;
- while (list != NULL) {
- if (list->group == group)
- return 1;
- list = list->next;
- }
- return 0;
- }
- /* Searches the supported groups extension for the specified named group.
- *
- * ssl The SSL/TLS object.
- * name The group name to match.
- * returns 1 when the extension has the group name and 0 otherwise.
- */
- static int TLSX_SupportedGroups_Find(WOLFSSL* ssl, word16 name)
- {
- #ifdef HAVE_SUPPORTED_CURVES
- TLSX* extension;
- SupportedCurve* curve = NULL;
- if ((extension = TLSX_Find(ssl->extensions,
- TLSX_SUPPORTED_GROUPS)) == NULL) {
- if ((extension = TLSX_Find(ssl->ctx->extensions,
- TLSX_SUPPORTED_GROUPS)) == NULL) {
- return 0;
- }
- }
- for (curve = (SupportedCurve*)extension->data; curve; curve = curve->next) {
- if (curve->name == name)
- return 1;
- }
- #endif
- (void)ssl;
- (void)name;
- return 0;
- }
- /* Parse the KeyShare extension.
- * Different formats in different messages.
- *
- * ssl The SSL/TLS object.
- * input The extension data.
- * length The length of the extension data.
- * msgType The type of the message this extension is being parsed from.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte msgType)
- {
- int ret;
- KeyShareEntry *keyShareEntry = NULL;
- word16 group;
- if (msgType == client_hello) {
- int offset = 0;
- word16 len;
- TLSX* extension;
- /* Add a KeyShare extension if it doesn't exist. */
- extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
- if (extension == NULL) {
- /* Push new KeyShare extension. */
- ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
- if (ret != 0)
- return ret;
- }
- if (length < OPAQUE16_LEN)
- return BUFFER_ERROR;
- /* ClientHello contains zero or more key share entries. */
- ato16(input, &len);
- if (len != length - OPAQUE16_LEN)
- return BUFFER_ERROR;
- offset += OPAQUE16_LEN;
- while (offset < (int)length) {
- ret = TLSX_KeyShareEntry_Parse(ssl, &input[offset],
- length - (word16)offset,
- &keyShareEntry);
- if (ret < 0)
- return ret;
- offset += ret;
- }
- ret = 0;
- }
- else if (msgType == server_hello) {
- int len;
- if (length < OPAQUE16_LEN)
- return BUFFER_ERROR;
- /* The data is the named group the server wants to use. */
- ato16(input, &group);
- /* Check the selected group was supported by ClientHello extensions. */
- if (!TLSX_SupportedGroups_Find(ssl, group)) {
- WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
- return BAD_KEY_SHARE_DATA;
- }
- /* Check if the group was sent. */
- if (!TLSX_KeyShare_Find(ssl, group)) {
- WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
- return BAD_KEY_SHARE_DATA;
- }
- /* ServerHello contains one key share entry. */
- len = TLSX_KeyShareEntry_Parse(ssl, input, length, &keyShareEntry);
- if (len != (int)length)
- return BUFFER_ERROR;
- /* Not in list sent if there isn't a private key. */
- if (keyShareEntry == NULL || (keyShareEntry->key == NULL
- #if !defined(NO_DH) || defined(HAVE_PQC)
- && keyShareEntry->privKey == NULL
- #endif
- )) {
- WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
- return BAD_KEY_SHARE_DATA;
- }
- /* Process the entry to calculate the secret. */
- ret = TLSX_KeyShare_Process(ssl, keyShareEntry);
- if (ret == 0)
- ssl->session->namedGroup = ssl->namedGroup = group;
- }
- else if (msgType == hello_retry_request) {
- if (length != OPAQUE16_LEN)
- return BUFFER_ERROR;
- /* The data is the named group the server wants to use. */
- ato16(input, &group);
- #ifdef WOLFSSL_ASYNC_CRYPT
- /* only perform find and clear TLSX if not returning from async */
- if (ssl->error != WC_PENDING_E)
- #endif
- {
- /* Check the selected group was supported by ClientHello extensions. */
- if (!TLSX_SupportedGroups_Find(ssl, group)) {
- WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
- return BAD_KEY_SHARE_DATA;
- }
- /* Check if the group was sent. */
- if (TLSX_KeyShare_Find(ssl, group)) {
- WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
- return BAD_KEY_SHARE_DATA;
- }
- /* Clear out unusable key shares. */
- ret = TLSX_KeyShare_Empty(ssl);
- if (ret != 0)
- return ret;
- }
- #ifdef HAVE_PQC
- /* For post-quantum groups, do this in TLSX_PopulateExtensions(). */
- if (!WOLFSSL_NAMED_GROUP_IS_PQC(group))
- #endif
- ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);
- }
- else {
- /* Not a message type that is allowed to have this extension. */
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- return ret;
- }
- /* Create a new key share entry and put it into the list.
- *
- * list The linked list of key share entries.
- * group The named group.
- * heap The memory to allocate with.
- * keyShareEntry The new key share entry object.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap,
- KeyShareEntry** keyShareEntry)
- {
- KeyShareEntry* kse;
- KeyShareEntry** next;
- kse = (KeyShareEntry*)XMALLOC(sizeof(KeyShareEntry), heap,
- DYNAMIC_TYPE_TLSX);
- if (kse == NULL)
- return MEMORY_E;
- XMEMSET(kse, 0, sizeof(*kse));
- kse->group = (word16)group;
- /* Add it to the back and maintain the links. */
- while (*list != NULL) {
- /* Assign to temporary to work around compiler bug found by customer. */
- next = &((*list)->next);
- list = next;
- }
- *list = kse;
- *keyShareEntry = kse;
- (void)heap;
- return 0;
- }
- #ifdef HAVE_PQC
- #ifdef WOLFSSL_WC_KYBER
- static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
- KeyShareEntry* keyShareEntry, byte* data, word16 len)
- {
- /* I am the server. The data parameter is the client's public key. I need
- * to generate the public information (AKA ciphertext) and shared secret
- * here. Note the "public information" is equivalent to a the public key in
- * key exchange parlance. That's why it is being assigned to pubKey.
- */
- int type;
- KyberKey kem[1];
- byte* sharedSecret = NULL;
- byte* ciphertext = NULL;
- int ret = 0;
- int oqs_group = 0;
- int ecc_group = 0;
- KeyShareEntry *ecc_kse = NULL;
- ecc_key eccpubkey;
- word32 outlen = 0;
- word32 pubSz = 0;
- word32 ctSz = 0;
- word32 ssSz = 0;
- findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group);
- ret = kyber_id2type(oqs_group, &type);
- if (ret != 0) {
- WOLFSSL_MSG("Invalid Kyber algorithm specified.");
- ret = BAD_FUNC_ARG;
- }
- if (ret == 0) {
- ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId);
- if (ret != 0) {
- WOLFSSL_MSG("Could not do ECC public key initialization.");
- ret = MEMORY_E;
- }
- }
- if (ret == 0) {
- ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (ecc_kse == NULL) {
- WOLFSSL_MSG("ecc_kse memory allocation failure");
- ret = MEMORY_ERROR;
- }
- }
- if (ret == 0) {
- XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
- }
- if (ret == 0 && ecc_group != 0) {
- ecc_kse->group = ecc_group;
- ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
- if (ret != 0) {
- /* No message, TLSX_KeyShare_GenEccKey() will do it. */
- return ret;
- }
- ret = 0;
- }
- if (ret == 0) {
- ret = wc_KyberKey_Init(type, kem, ssl->heap, INVALID_DEVID);
- if (ret == 0) {
- WOLFSSL_MSG("Error creating Kyber KEM");
- }
- }
- if (ret == 0) {
- ret = wc_KyberKey_PublicKeySize(kem, &pubSz);
- }
- if (ret == 0) {
- ret = wc_KyberKey_CipherTextSize(kem, &ctSz);
- }
- if (ret == 0) {
- ret = wc_KyberKey_SharedSecretSize(kem, &ssSz);
- }
- if (ret == 0 && len != pubSz + ecc_kse->pubKeyLen) {
- WOLFSSL_MSG("Invalid public key.");
- ret = BAD_FUNC_ARG;
- }
- if (ret == 0) {
- sharedSecret = (byte*)XMALLOC(ecc_kse->keyLen + ssSz, ssl->heap,
- DYNAMIC_TYPE_TLSX);
- ciphertext = (byte*)XMALLOC(ecc_kse->pubKeyLen + ctSz, ssl->heap,
- DYNAMIC_TYPE_TLSX);
- if (sharedSecret == NULL || ciphertext == NULL) {
- WOLFSSL_MSG("Ciphertext/shared secret memory allocation failure.");
- ret = MEMORY_E;
- }
- }
- if (ecc_group != 0) {
- if (ret == 0) {
- /* Point is validated by import function. */
- ret = wc_ecc_import_x963(data, len - pubSz, &eccpubkey);
- if (ret != 0) {
- WOLFSSL_MSG("Bad ECC public key.");
- }
- }
- #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
- (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
- !defined(HAVE_SELFTEST)
- if (ret == 0) {
- ret = wc_ecc_set_rng(ecc_kse->key, ssl->rng);
- }
- #endif
- if (ret == 0) {
- outlen = ecc_kse->keyLen;
- PRIVATE_KEY_UNLOCK();
- ret = wc_ecc_shared_secret(ecc_kse->key, &eccpubkey,
- sharedSecret,
- &outlen);
- PRIVATE_KEY_LOCK();
- if (outlen != ecc_kse->keyLen) {
- WOLFSSL_MSG("Data length mismatch.");
- ret = BAD_FUNC_ARG;
- }
- }
- }
- if (ret == 0) {
- ret = wc_KyberKey_DecodePublicKey(kem, data + ecc_kse->pubKeyLen,
- pubSz);
- }
- if (ret == 0) {
- ret = wc_KyberKey_Encapsulate(kem, ciphertext + ecc_kse->pubKeyLen,
- sharedSecret + outlen, ssl->rng);
- if (ret != 0) {
- WOLFSSL_MSG("wc_KyberKey encapsulation failure.");
- }
- }
- if (ret == 0) {
- if (keyShareEntry->ke != NULL) {
- XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- }
- keyShareEntry->ke = sharedSecret;
- keyShareEntry->keLen = outlen + ssSz;
- sharedSecret = NULL;
- XMEMCPY(ciphertext, ecc_kse->pubKey, ecc_kse->pubKeyLen);
- keyShareEntry->pubKey = ciphertext;
- keyShareEntry->pubKeyLen = (word32)(ecc_kse->pubKeyLen + ctSz);
- ciphertext = NULL;
- }
- TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
- if (sharedSecret != NULL)
- XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_TLSX);
- if (ciphertext != NULL)
- XFREE(ciphertext, ssl->heap, DYNAMIC_TYPE_TLSX);
- wc_ecc_free(&eccpubkey);
- wc_KyberKey_Free(kem);
- return ret;
- }
- #elif defined(HAVE_LIBOQS)
- static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
- KeyShareEntry* keyShareEntry,
- byte* data, word16 len)
- {
- /* I am the server. The data parameter is the client's public key. I need
- * to generate the public information (AKA ciphertext) and shared secret
- * here. Note the "public information" is equivalent to a the public key in
- * key exchange parlance. That's why it is being assigned to pubKey.
- */
- const char* algName = NULL;
- OQS_KEM* kem = NULL;
- byte* sharedSecret = NULL;
- byte* ciphertext = NULL;
- int ret = 0;
- int oqs_group = 0;
- int ecc_group = 0;
- KeyShareEntry *ecc_kse = NULL;
- ecc_key eccpubkey;
- word32 outlen = 0;
- findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group);
- algName = OQS_ID2name(oqs_group);
- if (algName == NULL) {
- WOLFSSL_MSG("Invalid OQS algorithm specified.");
- return BAD_FUNC_ARG;
- }
- ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId);
- if (ret != 0) {
- WOLFSSL_MSG("Could not do ECC public key initialization.");
- return MEMORY_E;
- }
- ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap, DYNAMIC_TYPE_TLSX);
- if (ecc_kse == NULL) {
- WOLFSSL_MSG("ecc_kse memory allocation failure");
- ret = MEMORY_ERROR;
- }
- if (ret == 0) {
- XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
- }
- if (ret == 0 && ecc_group != 0) {
- ecc_kse->group = ecc_group;
- ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
- if (ret != 0) {
- /* No message, TLSX_KeyShare_GenEccKey() will do it. */
- return ret;
- }
- ret = 0;
- }
- if (ret == 0) {
- kem = OQS_KEM_new(algName);
- if (kem == NULL) {
- WOLFSSL_MSG("Error creating OQS KEM, ensure algorithm support "
- "was enabled in liboqs.");
- ret = MEMORY_E;
- }
- }
- if (ret == 0 && len != kem->length_public_key + ecc_kse->pubKeyLen) {
- WOLFSSL_MSG("Invalid public key.");
- WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
- ret = BAD_FUNC_ARG;
- }
- if (ret == 0) {
- sharedSecret = (byte*)XMALLOC(ecc_kse->keyLen +
- kem->length_shared_secret,
- ssl->heap, DYNAMIC_TYPE_TLSX);
- ciphertext = (byte*)XMALLOC(ecc_kse->pubKeyLen + kem->length_ciphertext,
- ssl->heap, DYNAMIC_TYPE_TLSX);
- if (sharedSecret == NULL || ciphertext == NULL) {
- WOLFSSL_MSG("Ciphertext/shared secret memory allocation failure.");
- ret = MEMORY_E;
- }
- }
- if (ecc_group != 0) {
- if (ret == 0) {
- /* Point is validated by import function. */
- ret = wc_ecc_import_x963(data, len - (word32)kem->length_public_key,
- &eccpubkey);
- if (ret != 0) {
- WOLFSSL_MSG("Bad ECC public key.");
- }
- }
- #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
- (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
- !defined(HAVE_SELFTEST)
- if (ret == 0) {
- ret = wc_ecc_set_rng(ecc_kse->key, ssl->rng);
- }
- #endif
- if (ret == 0) {
- outlen = ecc_kse->keyLen;
- PRIVATE_KEY_UNLOCK();
- ret = wc_ecc_shared_secret(ecc_kse->key, &eccpubkey,
- sharedSecret,
- &outlen);
- PRIVATE_KEY_LOCK();
- if (outlen != ecc_kse->keyLen) {
- WOLFSSL_MSG("Data length mismatch.");
- ret = BAD_FUNC_ARG;
- }
- }
- }
- if (ret == 0 &&
- OQS_KEM_encaps(kem, ciphertext + ecc_kse->pubKeyLen,
- sharedSecret + outlen,
- data + ecc_kse->pubKeyLen) != OQS_SUCCESS) {
- WOLFSSL_MSG("OQS Encapsulation failure.");
- ret = BAD_FUNC_ARG;
- }
- if (ret == 0) {
- if (keyShareEntry->ke != NULL) {
- XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- }
- keyShareEntry->ke = sharedSecret;
- keyShareEntry->keLen = outlen + (word32)kem->length_shared_secret;
- sharedSecret = NULL;
- XMEMCPY(ciphertext, ecc_kse->pubKey, ecc_kse->pubKeyLen);
- keyShareEntry->pubKey = ciphertext;
- keyShareEntry->pubKeyLen = (word32)(ecc_kse->pubKeyLen +
- kem->length_ciphertext);
- ciphertext = NULL;
- /* Set namedGroup so wolfSSL_get_curve_name() can function properly on
- * the server side. */
- ssl->namedGroup = keyShareEntry->group;
- }
- TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
- if (sharedSecret != NULL)
- XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_TLSX);
- if (ciphertext != NULL)
- XFREE(ciphertext, ssl->heap, DYNAMIC_TYPE_TLSX);
- wc_ecc_free(&eccpubkey);
- OQS_KEM_free(kem);
- return ret;
- }
- #elif defined(HAVE_PQM4)
- static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
- KeyShareEntry* keyShareEntry,
- byte* data, word16 len)
- {
- /* I am the server. The data parameter is the client's public key. I need
- * to generate the public information (AKA ciphertext) and shared secret
- * here. Note the "public information" is equivalent to a the public key in
- * key exchange parlance. That's why it is being assigned to pubKey.
- */
- byte* sharedSecret = NULL;
- byte* ciphertext = NULL;
- int ret = 0;
- int oqs_group = 0;
- int ecc_group = 0;
- KeyShareEntry *ecc_kse = NULL;
- ecc_key eccpubkey;
- word32 outlen = 0;
- findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group);
- ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId);
- if (ret != 0) {
- WOLFSSL_MSG("Could not do ECC public key initialization.");
- return MEMORY_E;
- }
- ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap, DYNAMIC_TYPE_TLSX);
- if (ecc_kse == NULL) {
- WOLFSSL_MSG("ecc_kse memory allocation failure");
- ret = MEMORY_ERROR;
- }
- if (ret == 0) {
- XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
- }
- if (ret == 0 && ecc_group != 0) {
- ecc_kse->group = ecc_group;
- ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
- if (ret != 0) {
- /* No message, TLSX_KeyShare_GenEccKey() will do it. */
- return ret;
- }
- ret = 0;
- }
- if (ret == 0 && len != PQM4_PUBLIC_KEY_LENGTH + ecc_kse->pubKeyLen) {
- WOLFSSL_MSG("Invalid public key.");
- ret = BAD_FUNC_ARG;
- }
- if (ret == 0) {
- sharedSecret = (byte*)XMALLOC(ecc_kse->keyLen + PQM4_SHARED_SECRET_LENGTH,
- ssl->heap, DYNAMIC_TYPE_TLSX);
- ciphertext = (byte*)XMALLOC(ecc_kse->pubKeyLen + PQM4_CIPHERTEXT_LENGTH,
- ssl->heap, DYNAMIC_TYPE_TLSX);
- if (sharedSecret == NULL || ciphertext == NULL) {
- WOLFSSL_MSG("Ciphertext/shared secret memory allocation failure.");
- ret = MEMORY_E;
- }
- }
- if (ecc_group != 0) {
- if (ret == 0) {
- /* Point is validated by import function. */
- ret = wc_ecc_import_x963(data, len - PQM4_PUBLIC_KEY_LENGTH,
- &eccpubkey);
- if (ret != 0) {
- WOLFSSL_MSG("Bad ECC public key.");
- }
- }
- #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
- (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
- !defined(HAVE_SELFTEST)
- if (ret == 0) {
- ret = wc_ecc_set_rng(ecc_kse->key, ssl->rng);
- }
- #endif
- if (ret == 0) {
- outlen = ecc_kse->keyLen;
- PRIVATE_KEY_UNLOCK();
- ret = wc_ecc_shared_secret(ecc_kse->key, &eccpubkey,
- sharedSecret,
- &outlen);
- PRIVATE_KEY_LOCK();
- if (outlen != ecc_kse->keyLen) {
- WOLFSSL_MSG("Data length mismatch.");
- ret = BAD_FUNC_ARG;
- }
- }
- }
- if (ret == 0 &&
- crypto_kem_enc(ciphertext + ecc_kse->pubKeyLen,
- sharedSecret + outlen,
- data + ecc_kse->pubKeyLen) != 0) {
- WOLFSSL_MSG("PQM4 Encapsulation failure.");
- ret = BAD_FUNC_ARG;
- }
- if (ret == 0) {
- if (keyShareEntry->ke != NULL) {
- XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- }
- keyShareEntry->ke = sharedSecret;
- keyShareEntry->keLen = outlen + (word32)PQM4_SHARED_SECRET_LENGTH;
- sharedSecret = NULL;
- XMEMCPY(ciphertext, ecc_kse->pubKey, ecc_kse->pubKeyLen);
- keyShareEntry->pubKey = ciphertext;
- keyShareEntry->pubKeyLen = (word32)(ecc_kse->pubKeyLen +
- PQM4_CIPHERTEXT_LENGTH);
- ciphertext = NULL;
- /* Set namedGroup so wolfSSL_get_curve_name() can function properly on
- * the server side. */
- ssl->namedGroup = keyShareEntry->group;
- }
- TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
- if (sharedSecret != NULL)
- XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_TLSX);
- if (ciphertext != NULL)
- XFREE(ciphertext, ssl->heap, DYNAMIC_TYPE_TLSX);
- wc_ecc_free(&eccpubkey);
- return ret;
- }
- #endif /* HAVE_PQM4 */
- #endif /* HAVE_PQC */
- /* Use the data to create a new key share object in the extensions.
- *
- * ssl The SSL/TLS object.
- * group The named group.
- * len The length of the public key data.
- * data The public key data.
- * kse The new key share entry object.
- * returns 0 on success and other values indicate failure.
- */
- int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data,
- KeyShareEntry **kse)
- {
- int ret = 0;
- TLSX* extension;
- KeyShareEntry* keyShareEntry = NULL;
- /* Find the KeyShare extension if it exists. */
- extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
- if (extension == NULL) {
- /* Push new KeyShare extension. */
- ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
- if (ret != 0)
- return ret;
- extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
- if (extension == NULL)
- return MEMORY_E;
- }
- extension->resp = 0;
- /* Try to find the key share entry with this group. */
- keyShareEntry = (KeyShareEntry*)extension->data;
- while (keyShareEntry != NULL) {
- if (keyShareEntry->group == group)
- break;
- keyShareEntry = keyShareEntry->next;
- }
- /* Create a new key share entry if not found. */
- if (keyShareEntry == NULL) {
- ret = TLSX_KeyShare_New((KeyShareEntry**)&extension->data, group,
- ssl->heap, &keyShareEntry);
- if (ret != 0)
- return ret;
- }
- #ifdef HAVE_PQC
- if (WOLFSSL_NAMED_GROUP_IS_PQC(group) &&
- ssl->options.side == WOLFSSL_SERVER_END) {
- ret = server_generate_pqc_ciphertext(ssl, keyShareEntry, data,
- len);
- if (ret != 0)
- return ret;
- }
- else
- #endif
- if (data != NULL) {
- if (keyShareEntry->ke != NULL) {
- XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- }
- keyShareEntry->ke = data;
- keyShareEntry->keLen = len;
- }
- else {
- /* Generate a key pair. */
- ret = TLSX_KeyShare_GenKey(ssl, keyShareEntry);
- if (ret != 0)
- return ret;
- }
- if (kse != NULL)
- *kse = keyShareEntry;
- return 0;
- }
- /* Set an empty Key Share extension.
- *
- * ssl The SSL/TLS object.
- * returns 0 on success and other values indicate failure.
- */
- int TLSX_KeyShare_Empty(WOLFSSL* ssl)
- {
- int ret = 0;
- TLSX* extension;
- /* Find the KeyShare extension if it exists. */
- extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
- if (extension == NULL) {
- /* Push new KeyShare extension. */
- ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
- }
- else if (extension->data != NULL) {
- TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap);
- extension->data = NULL;
- }
- return ret;
- }
- /* Returns whether this group is supported.
- *
- * namedGroup The named group to check.
- * returns 1 when supported or 0 otherwise.
- */
- static int TLSX_KeyShare_IsSupported(int namedGroup)
- {
- switch (namedGroup) {
- #ifdef HAVE_FFDHE_2048
- case WOLFSSL_FFDHE_2048:
- break;
- #endif
- #ifdef HAVE_FFDHE_3072
- case WOLFSSL_FFDHE_3072:
- break;
- #endif
- #ifdef HAVE_FFDHE_4096
- case WOLFSSL_FFDHE_4096:
- break;
- #endif
- #ifdef HAVE_FFDHE_6144
- case WOLFSSL_FFDHE_6144:
- break;
- #endif
- #ifdef HAVE_FFDHE_8192
- case WOLFSSL_FFDHE_8192:
- break;
- #endif
- #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
- #ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP256K1:
- break;
- #endif
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP256R1:
- break;
- #endif /* !NO_ECC_SECP */
- #ifdef HAVE_ECC_BRAINPOOL
- case WOLFSSL_ECC_BRAINPOOLP256R1:
- break;
- #endif
- #endif
- #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
- case WOLFSSL_ECC_X25519:
- break;
- #endif
- #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
- case WOLFSSL_ECC_X448:
- break;
- #endif
- #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP384R1:
- break;
- #endif /* !NO_ECC_SECP */
- #ifdef HAVE_ECC_BRAINPOOL
- case WOLFSSL_ECC_BRAINPOOLP384R1:
- break;
- #endif
- #endif
- #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP521R1:
- break;
- #endif /* !NO_ECC_SECP */
- #endif
- #if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
- #ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP160K1:
- break;
- #endif
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP160R1:
- break;
- #endif
- #ifdef HAVE_ECC_SECPR2
- case WOLFSSL_ECC_SECP160R2:
- break;
- #endif
- #endif
- #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
- #ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP192K1:
- break;
- #endif
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP192R1:
- break;
- #endif
- #endif
- #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
- #ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP224K1:
- break;
- #endif
- #ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP224R1:
- break;
- #endif
- #endif
- #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
- #ifdef HAVE_ECC_BRAINPOOL
- case WOLFSSL_ECC_BRAINPOOLP512R1:
- break;
- #endif
- #endif
- #ifdef HAVE_PQC
- #ifdef WOLFSSL_WC_KYBER
- #ifdef WOLFSSL_KYBER512
- case WOLFSSL_KYBER_LEVEL1:
- #endif
- #ifdef WOLFSSL_KYBER768
- case WOLFSSL_KYBER_LEVEL3:
- #endif
- #ifdef WOLFSSL_KYBER1024
- case WOLFSSL_KYBER_LEVEL5:
- #endif
- break;
- #elif defined(HAVE_LIBOQS)
- case WOLFSSL_KYBER_LEVEL1:
- case WOLFSSL_KYBER_LEVEL3:
- case WOLFSSL_KYBER_LEVEL5:
- case WOLFSSL_KYBER_90S_LEVEL1:
- case WOLFSSL_KYBER_90S_LEVEL3:
- case WOLFSSL_KYBER_90S_LEVEL5:
- case WOLFSSL_P256_KYBER_LEVEL1:
- case WOLFSSL_P384_KYBER_LEVEL3:
- case WOLFSSL_P521_KYBER_LEVEL5:
- case WOLFSSL_P256_KYBER_90S_LEVEL1:
- case WOLFSSL_P384_KYBER_90S_LEVEL3:
- case WOLFSSL_P521_KYBER_90S_LEVEL5:
- findEccPqc(NULL, &namedGroup, namedGroup);
- if (! OQS_KEM_alg_is_enabled(OQS_ID2name(namedGroup))) {
- return 0;
- }
- break;
- #elif defined(HAVE_PQM4)
- case WOLFSSL_KYBER_LEVEL1:
- break;
- #endif
- #endif /* HAVE_PQC */
- default:
- return 0;
- }
- return 1;
- }
- /* Examines the application specified group ranking and returns the rank of the
- * group.
- * If no group ranking set then all groups are rank 0 (highest).
- *
- * ssl The SSL/TLS object.
- * group The group to check ranking for.
- * returns ranking from 0 to MAX_GROUP_COUNT-1 or -1 when group not in list.
- */
- static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group)
- {
- byte i;
- if (ssl->numGroups == 0) {
- #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
- #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
- #ifndef NO_ECC_SECP
- ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP256R1;
- #endif
- #endif
- #endif
- #ifndef HAVE_FIPS
- #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
- ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X25519;
- #endif
- #endif
- #ifndef HAVE_FIPS
- #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
- ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X448;
- #endif
- #endif
- #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
- #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
- #ifndef NO_ECC_SECP
- ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP384R1;
- #endif
- #endif
- #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
- #ifndef NO_ECC_SECP
- ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP521R1;
- #endif
- #endif
- #endif
- /* Add FFDHE supported groups. */
- #ifdef HAVE_FFDHE_2048
- ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_2048;
- #endif
- #ifdef HAVE_FFDHE_3072
- ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_3072;
- #endif
- #ifdef HAVE_FFDHE_4096
- ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_4096;
- #endif
- #ifdef HAVE_FFDHE_6144
- ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_6144;
- #endif
- #ifdef HAVE_FFDHE_8192
- ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_8192;
- #endif
- #ifdef HAVE_PQC
- /* For the liboqs groups we need to do a runtime check because
- * liboqs could be compiled to make an algorithm unavailable.
- */
- #ifdef WOLFSSL_WC_KYBER
- #ifdef WOLFSSL_KYBER512
- if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL1))
- ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL1;
- #endif
- #ifdef WOLFSSL_KYBER768
- if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL3))
- ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL3;
- #endif
- #ifdef WOLFSSL_KYBER1024
- if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL5))
- ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL5;
- #endif
- #elif defined(HAVE_LIBOQS)
- if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL1))
- ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL1;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL3))
- ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL3;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL5))
- ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL5;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_90S_LEVEL1))
- ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_90S_LEVEL1;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_90S_LEVEL3))
- ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_90S_LEVEL3;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_90S_LEVEL5))
- ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_90S_LEVEL5;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_P256_KYBER_LEVEL1))
- ssl->group[ssl->numGroups++] = WOLFSSL_P256_KYBER_LEVEL1;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_P384_KYBER_LEVEL3))
- ssl->group[ssl->numGroups++] = WOLFSSL_P384_KYBER_LEVEL3;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_P521_KYBER_LEVEL5))
- ssl->group[ssl->numGroups++] = WOLFSSL_P521_KYBER_LEVEL5;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_P256_KYBER_90S_LEVEL1))
- ssl->group[ssl->numGroups++] = WOLFSSL_P256_KYBER_90S_LEVEL1;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_P384_KYBER_90S_LEVEL3))
- ssl->group[ssl->numGroups++] = WOLFSSL_P384_KYBER_90S_LEVEL3;
- if (TLSX_KeyShare_IsSupported(WOLFSSL_P521_KYBER_90S_LEVEL5))
- ssl->group[ssl->numGroups++] = WOLFSSL_P521_KYBER_90S_LEVEL5;
- #elif defined(HAVE_PQM4)
- if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL1))
- ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL1;
- #endif /* HAVE_LIBOQS */
- #endif /* HAVE_PQC */
- }
- for (i = 0; i < ssl->numGroups; i++)
- if (ssl->group[i] == (word16)group)
- return i;
- return -1;
- }
- /* Set a key share that is supported by the client into extensions.
- *
- * ssl The SSL/TLS object.
- * returns BAD_KEY_SHARE_DATA if no supported group has a key share,
- * 0 if a supported group has a key share and other values indicate an error.
- */
- static int TLSX_KeyShare_SetSupported(WOLFSSL* ssl)
- {
- int ret;
- #ifdef HAVE_SUPPORTED_CURVES
- TLSX* extension;
- SupportedCurve* curve = NULL;
- SupportedCurve* preferredCurve = NULL;
- int preferredRank = WOLFSSL_MAX_GROUP_COUNT;
- int rank;
- extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
- if (extension != NULL)
- curve = (SupportedCurve*)extension->data;
- /* Use server's preference order. */
- for (; curve != NULL; curve = curve->next) {
- if (!TLSX_KeyShare_IsSupported(curve->name))
- continue;
- if (wolfSSL_curve_is_disabled(ssl, curve->name))
- continue;
- rank = TLSX_KeyShare_GroupRank(ssl, curve->name);
- if (rank == -1)
- continue;
- if (rank < preferredRank) {
- preferredCurve = curve;
- preferredRank = rank;
- }
- }
- curve = preferredCurve;
- if (curve == NULL) {
- WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
- return BAD_KEY_SHARE_DATA;
- }
- /* Delete the old key share data list. */
- extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
- if (extension != NULL) {
- KeyShareEntry* kse = (KeyShareEntry*)extension->data;
- #ifdef WOLFSSL_ASYNC_CRYPT
- /* for async don't free, call `TLSX_KeyShare_Use` again */
- if (kse && kse->lastRet != WC_PENDING_E)
- #endif
- {
- TLSX_KeyShare_FreeAll(kse, ssl->heap);
- extension->data = NULL;
- }
- }
- /* Add in the chosen group. */
- ret = TLSX_KeyShare_Use(ssl, curve->name, 0, NULL, NULL);
- if (ret != 0 && ret != WC_PENDING_E)
- return ret;
- /* Set extension to be in response. */
- extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
- extension->resp = 1;
- #else
- (void)ssl;
- WOLFSSL_ERROR_VERBOSE(NOT_COMPILED_IN);
- ret = NOT_COMPILED_IN;
- #endif
- return ret;
- }
- /* Ensure there is a key pair that can be used for key exchange.
- *
- * ssl The SSL/TLS object.
- * doHelloRetry If set to non-zero will do hello_retry
- * returns 0 on success and other values indicate failure.
- */
- int TLSX_KeyShare_Establish(WOLFSSL *ssl, int* doHelloRetry)
- {
- int ret;
- TLSX* extension;
- KeyShareEntry* clientKSE = NULL;
- KeyShareEntry* serverKSE;
- KeyShareEntry* list = NULL;
- KeyShareEntry* preferredKSE = NULL;
- int preferredRank = WOLFSSL_MAX_GROUP_COUNT;
- int rank;
- /* Find the KeyShare extension if it exists. */
- extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
- if (extension != NULL)
- list = (KeyShareEntry*)extension->data;
- if (extension && extension->resp == 1) {
- ret = 0;
- #ifdef WOLFSSL_ASYNC_CRYPT
- /* in async case make sure key generation is finalized */
- serverKSE = (KeyShareEntry*)extension->data;
- if (serverKSE->lastRet == WC_PENDING_E) {
- if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE)
- *doHelloRetry = 1;
- ret = TLSX_KeyShare_GenKey(ssl, serverKSE);
- }
- #endif
- return ret;
- }
- /* Use server's preference order. */
- for (clientKSE = list; clientKSE != NULL; clientKSE = clientKSE->next) {
- if (clientKSE->ke == NULL)
- continue;
- /* Check consistency now - extensions in any order. */
- if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group))
- continue;
- if (!WOLFSSL_NAMED_GROUP_IS_FFHDE(clientKSE->group)) {
- /* Check max value supported. */
- if (clientKSE->group > WOLFSSL_ECC_MAX) {
- #ifdef HAVE_PQC
- if (!WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group))
- #endif
- continue;
- }
- if (wolfSSL_curve_is_disabled(ssl, clientKSE->group))
- continue;
- }
- if (!TLSX_KeyShare_IsSupported(clientKSE->group))
- continue;
- rank = TLSX_KeyShare_GroupRank(ssl, clientKSE->group);
- if (rank == -1)
- continue;
- if (rank < preferredRank) {
- preferredKSE = clientKSE;
- preferredRank = rank;
- }
- }
- clientKSE = preferredKSE;
- /* No supported group found - send HelloRetryRequest. */
- if (clientKSE == NULL) {
- /* Set KEY_SHARE_ERROR to indicate HelloRetryRequest required. */
- *doHelloRetry = 1;
- return TLSX_KeyShare_SetSupported(ssl);
- }
- list = NULL;
- /* Generate a new key pair except in the case of OQS KEM because we
- * are going to encapsulate and that does not require us to generate a
- * key pair.
- */
- ret = TLSX_KeyShare_New(&list, clientKSE->group, ssl->heap, &serverKSE);
- if (ret != 0)
- return ret;
- if (clientKSE->key == NULL) {
- #ifdef HAVE_PQC
- if (WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group)) {
- /* Going to need the public key (AKA ciphertext). */
- serverKSE->pubKey = clientKSE->pubKey;
- clientKSE->pubKey = NULL;
- serverKSE->pubKeyLen = clientKSE->pubKeyLen;
- clientKSE->pubKeyLen = 0;
- }
- else
- #endif
- {
- ret = TLSX_KeyShare_GenKey(ssl, serverKSE);
- }
- /* for async do setup of serverKSE below, but return WC_PENDING_E */
- if (ret != 0
- #ifdef WOLFSSL_ASYNC_CRYPT
- && ret != WC_PENDING_E
- #endif
- ) {
- return ret;
- }
- }
- else {
- /* transfer buffers to serverKSE */
- serverKSE->key = clientKSE->key;
- clientKSE->key = NULL;
- serverKSE->keyLen = clientKSE->keyLen;
- serverKSE->pubKey = clientKSE->pubKey;
- clientKSE->pubKey = NULL;
- serverKSE->pubKeyLen = clientKSE->pubKeyLen;
- #ifndef NO_DH
- serverKSE->privKey = clientKSE->privKey;
- clientKSE->privKey = NULL;
- #endif
- }
- serverKSE->ke = clientKSE->ke;
- serverKSE->keLen = clientKSE->keLen;
- clientKSE->ke = NULL;
- clientKSE->keLen = 0;
- TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap);
- extension->data = (void *)serverKSE;
- extension->resp = 1;
- return ret;
- }
- /* Derive the shared secret of the key exchange.
- *
- * ssl The SSL/TLS object.
- * returns 0 on success and other values indicate failure.
- */
- int TLSX_KeyShare_DeriveSecret(WOLFSSL *ssl)
- {
- int ret;
- TLSX* extension;
- KeyShareEntry* list = NULL;
- #ifdef WOLFSSL_ASYNC_CRYPT
- ret = wolfSSL_AsyncPop(ssl, NULL);
- /* Check for error */
- if (ret != WC_NOT_PENDING_E && ret < 0) {
- return ret;
- }
- #endif
- /* Find the KeyShare extension if it exists. */
- extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
- if (extension != NULL)
- list = (KeyShareEntry*)extension->data;
- if (list == NULL)
- return KEY_SHARE_ERROR;
- /* Calculate secret. */
- ret = TLSX_KeyShare_Process(ssl, list);
- return ret;
- }
- #define KS_FREE_ALL TLSX_KeyShare_FreeAll
- #define KS_GET_SIZE TLSX_KeyShare_GetSize
- #define KS_WRITE TLSX_KeyShare_Write
- #define KS_PARSE TLSX_KeyShare_Parse
- #else
- #define KS_FREE_ALL(a, b)
- #define KS_GET_SIZE(a, b) 0
- #define KS_WRITE(a, b, c) 0
- #define KS_PARSE(a, b, c, d) 0
- #endif /* WOLFSSL_TLS13 */
- /******************************************************************************/
- /* Pre-Shared Key */
- /******************************************************************************/
- #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
- /* Free the pre-shared key dynamic data.
- *
- * list The linked list of key share entry objects.
- * heap The heap used for allocation.
- */
- static void TLSX_PreSharedKey_FreeAll(PreSharedKey* list, void* heap)
- {
- PreSharedKey* current;
- while ((current = list) != NULL) {
- list = current->next;
- XFREE(current->identity, heap, DYNAMIC_TYPE_TLSX);
- XFREE(current, heap, DYNAMIC_TYPE_TLSX);
- }
- (void)heap;
- }
- /* Get the size of the encoded pre shared key extension.
- *
- * list The linked list of pre-shared key extensions.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes of the encoded pre-shared key extension or
- * SANITY_MSG_E to indicate invalid message type.
- */
- static int TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType,
- word16* pSz)
- {
- if (msgType == client_hello) {
- /* Length of identities + Length of binders. */
- word16 len = OPAQUE16_LEN + OPAQUE16_LEN;
- while (list != NULL) {
- /* Each entry has: identity, ticket age and binder. */
- len += OPAQUE16_LEN + list->identityLen + OPAQUE32_LEN +
- OPAQUE8_LEN + (word16)list->binderLen;
- list = list->next;
- }
- *pSz += len;
- return 0;
- }
- if (msgType == server_hello) {
- *pSz += OPAQUE16_LEN;
- return 0;
- }
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* The number of bytes to be written for the binders.
- *
- * list The linked list of pre-shared key extensions.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes of the encoded pre-shared key extension or
- * SANITY_MSG_E to indicate invalid message type.
- */
- int TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType,
- word16* pSz)
- {
- word16 len;
- if (msgType != client_hello) {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Length of all binders. */
- len = OPAQUE16_LEN;
- while (list != NULL) {
- len += OPAQUE8_LEN + (word16)list->binderLen;
- list = list->next;
- }
- *pSz = len;
- return 0;
- }
- /* Writes the pre-shared key extension into the output buffer - binders only.
- * Assumes that the the output buffer is big enough to hold data.
- *
- * list The linked list of key share entries.
- * output The buffer to write into.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes written into the buffer.
- */
- int TLSX_PreSharedKey_WriteBinders(PreSharedKey* list, byte* output,
- byte msgType, word16* pSz)
- {
- PreSharedKey* current = list;
- word16 idx = 0;
- word16 lenIdx;
- word16 len;
- if (msgType != client_hello) {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Skip length of all binders. */
- lenIdx = idx;
- idx += OPAQUE16_LEN;
- while (current != NULL) {
- /* Binder data length. */
- output[idx++] = (byte)current->binderLen;
- /* Binder data. */
- XMEMCPY(output + idx, current->binder, current->binderLen);
- idx += (word16)current->binderLen;
- current = current->next;
- }
- /* Length of the binders. */
- len = idx - lenIdx - OPAQUE16_LEN;
- c16toa(len, output + lenIdx);
- *pSz = idx;
- return 0;
- }
- /* Writes the pre-shared key extension into the output buffer.
- * Assumes that the the output buffer is big enough to hold data.
- *
- * list The linked list of key share entries.
- * output The buffer to write into.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes written into the buffer.
- */
- static int TLSX_PreSharedKey_Write(PreSharedKey* list, byte* output,
- byte msgType, word16* pSz)
- {
- if (msgType == client_hello) {
- PreSharedKey* current = list;
- word16 idx = 0;
- word16 lenIdx;
- word16 len;
- int ret;
- /* Write identites only. Binders after HMACing over this. */
- lenIdx = idx;
- idx += OPAQUE16_LEN;
- while (current != NULL) {
- /* Identity length */
- c16toa(current->identityLen, output + idx);
- idx += OPAQUE16_LEN;
- /* Identity data */
- XMEMCPY(output + idx, current->identity, current->identityLen);
- idx += current->identityLen;
- /* Obfuscated ticket age. */
- c32toa(current->ticketAge, output + idx);
- idx += OPAQUE32_LEN;
- current = current->next;
- }
- /* Length of the identites. */
- len = idx - lenIdx - OPAQUE16_LEN;
- c16toa(len, output + lenIdx);
- /* Don't include binders here.
- * The binders are based on the hash of all the ClientHello data up to
- * and include the identities written above.
- */
- ret = TLSX_PreSharedKey_GetSizeBinders(list, msgType, &len);
- if (ret < 0)
- return ret;
- *pSz += idx + len;
- }
- else if (msgType == server_hello) {
- word16 i;
- /* Find the index of the chosen identity. */
- for (i=0; list != NULL && !list->chosen; i++)
- list = list->next;
- if (list == NULL) {
- WOLFSSL_ERROR_VERBOSE(BUILD_MSG_ERROR);
- return BUILD_MSG_ERROR;
- }
- /* The index of the identity chosen by the server from the list supplied
- * by the client.
- */
- c16toa(i, output);
- *pSz += OPAQUE16_LEN;
- }
- else {
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- return 0;
- }
- /* Parse the pre-shared key extension.
- * Different formats in different messages.
- *
- * ssl The SSL/TLS object.
- * input The extension data.
- * length The length of the extension data.
- * msgType The type of the message this extension is being parsed from.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, const byte* input,
- word16 length, byte msgType)
- {
- TLSX* extension;
- PreSharedKey* list;
- if (msgType == client_hello) {
- int ret;
- word16 len;
- word16 idx = 0;
- TLSX_Remove(&ssl->extensions, TLSX_PRE_SHARED_KEY, ssl->heap);
- /* Length of identities and of binders. */
- if ((int)(length - idx) < OPAQUE16_LEN + OPAQUE16_LEN)
- return BUFFER_E;
- /* Length of identities. */
- ato16(input + idx, &len);
- idx += OPAQUE16_LEN;
- if (len < MIN_PSK_ID_LEN || length - idx < len)
- return BUFFER_E;
- /* Create a pre-shared key object for each identity. */
- while (len > 0) {
- const byte* identity;
- word16 identityLen;
- word32 age;
- if (len < OPAQUE16_LEN)
- return BUFFER_E;
- /* Length of identity. */
- ato16(input + idx, &identityLen);
- idx += OPAQUE16_LEN;
- if (len < OPAQUE16_LEN + identityLen + OPAQUE32_LEN ||
- identityLen > MAX_PSK_ID_LEN)
- return BUFFER_E;
- /* Cache identity pointer. */
- identity = input + idx;
- idx += identityLen;
- /* Ticket age. */
- ato32(input + idx, &age);
- idx += OPAQUE32_LEN;
- ret = TLSX_PreSharedKey_Use(ssl, identity, identityLen, age, no_mac,
- 0, 0, 1, NULL);
- if (ret != 0)
- return ret;
- /* Done with this identity. */
- len -= OPAQUE16_LEN + identityLen + OPAQUE32_LEN;
- }
- /* Find the list of identities sent to server. */
- extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
- if (extension == NULL)
- return PSK_KEY_ERROR;
- list = (PreSharedKey*)extension->data;
- /* Length of binders. */
- if (idx + OPAQUE16_LEN > length)
- return BUFFER_E;
- ato16(input + idx, &len);
- idx += OPAQUE16_LEN;
- if (len < MIN_PSK_BINDERS_LEN || length - idx < len)
- return BUFFER_E;
- /* Set binder for each identity. */
- while (list != NULL && len > 0) {
- /* Length of binder */
- list->binderLen = input[idx++];
- if (list->binderLen < WC_SHA256_DIGEST_SIZE ||
- list->binderLen > WC_MAX_DIGEST_SIZE)
- return BUFFER_E;
- if (len < OPAQUE8_LEN + list->binderLen)
- return BUFFER_E;
- /* Copy binder into static buffer. */
- XMEMCPY(list->binder, input + idx, list->binderLen);
- idx += (word16)list->binderLen;
- /* Done with binder entry. */
- len -= OPAQUE8_LEN + (word16)list->binderLen;
- /* Next identity. */
- list = list->next;
- }
- if (list != NULL || len != 0)
- return BUFFER_E;
- return 0;
- }
- if (msgType == server_hello) {
- word16 idx;
- /* Index of identity chosen by server. */
- if (length != OPAQUE16_LEN)
- return BUFFER_E;
- ato16(input, &idx);
- #ifdef WOLFSSL_EARLY_DATA
- ssl->options.pskIdIndex = idx + 1;
- #endif
- /* Find the list of identities sent to server. */
- extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
- if (extension == NULL)
- return PSK_KEY_ERROR;
- list = (PreSharedKey*)extension->data;
- /* Mark the identity as chosen. */
- for (; list != NULL && idx > 0; idx--)
- list = list->next;
- if (list == NULL) {
- WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
- return PSK_KEY_ERROR;
- }
- list->chosen = 1;
- #ifdef HAVE_SESSION_TICKET
- if (list->resumption) {
- /* Check that the session's details are the same as the server's. */
- if (ssl->options.cipherSuite0 != ssl->session->cipherSuite0 ||
- ssl->options.cipherSuite != ssl->session->cipherSuite ||
- ssl->session->version.major != ssl->ctx->method->version.major ||
- ssl->session->version.minor != ssl->ctx->method->version.minor) {
- WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
- return PSK_KEY_ERROR;
- }
- }
- #endif
- return 0;
- }
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Create a new pre-shared key and put it into the list.
- *
- * list The linked list of pre-shared key.
- * identity The identity.
- * len The length of the identity data.
- * heap The memory to allocate with.
- * preSharedKey The new pre-shared key object.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_PreSharedKey_New(PreSharedKey** list, const byte* identity,
- word16 len, void *heap,
- PreSharedKey** preSharedKey)
- {
- PreSharedKey* psk;
- PreSharedKey** next;
- psk = (PreSharedKey*)XMALLOC(sizeof(PreSharedKey), heap, DYNAMIC_TYPE_TLSX);
- if (psk == NULL)
- return MEMORY_E;
- XMEMSET(psk, 0, sizeof(*psk));
- /* Make a copy of the identity data. */
- psk->identity = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TLSX);
- if (psk->identity == NULL) {
- XFREE(psk, heap, DYNAMIC_TYPE_TLSX);
- return MEMORY_E;
- }
- XMEMCPY(psk->identity, identity, len);
- psk->identityLen = len;
- /* Add it to the end and maintain the links. */
- while (*list != NULL) {
- /* Assign to temporary to work around compiler bug found by customer. */
- next = &((*list)->next);
- list = next;
- }
- *list = psk;
- *preSharedKey = psk;
- (void)heap;
- return 0;
- }
- static WC_INLINE byte GetHmacLength(int hmac)
- {
- switch (hmac) {
- #ifndef NO_SHA256
- case sha256_mac:
- return WC_SHA256_DIGEST_SIZE;
- #endif
- #ifdef WOLFSSL_SHA384
- case sha384_mac:
- return WC_SHA384_DIGEST_SIZE;
- #endif
- #ifdef WOLFSSL_SHA512
- case sha512_mac:
- return WC_SHA512_DIGEST_SIZE;
- #endif
- }
- return 0;
- }
- /* Use the data to create a new pre-shared key object in the extensions.
- *
- * ssl The SSL/TLS object.
- * identity The identity.
- * len The length of the identity data.
- * age The age of the identity.
- * hmac The HMAC algorithm.
- * ciphersuite0 The first byte of the ciphersuite to use.
- * ciphersuite The second byte of the ciphersuite to use.
- * resumption The PSK is for resumption of a session.
- * preSharedKey The new pre-shared key object.
- * returns 0 on success and other values indicate failure.
- */
- int TLSX_PreSharedKey_Use(WOLFSSL* ssl, const byte* identity, word16 len,
- word32 age, byte hmac, byte cipherSuite0,
- byte cipherSuite, byte resumption,
- PreSharedKey **preSharedKey)
- {
- int ret = 0;
- TLSX* extension;
- PreSharedKey* psk = NULL;
- /* Find the pre-shared key extension if it exists. */
- extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
- if (extension == NULL) {
- /* Push new pre-shared key extension. */
- ret = TLSX_Push(&ssl->extensions, TLSX_PRE_SHARED_KEY, NULL, ssl->heap);
- if (ret != 0)
- return ret;
- extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
- if (extension == NULL)
- return MEMORY_E;
- }
- /* Try to find the pre-shared key with this identity. */
- psk = (PreSharedKey*)extension->data;
- while (psk != NULL) {
- if ((psk->identityLen == len) &&
- (XMEMCMP(psk->identity, identity, len) == 0)) {
- break;
- }
- psk = psk->next;
- }
- /* Create a new pre-shared key object if not found. */
- if (psk == NULL) {
- ret = TLSX_PreSharedKey_New((PreSharedKey**)&extension->data, identity,
- len, ssl->heap, &psk);
- if (ret != 0)
- return ret;
- }
- /* Update/set age and HMAC algorithm. */
- psk->ticketAge = age;
- psk->hmac = hmac;
- psk->cipherSuite0 = cipherSuite0;
- psk->cipherSuite = cipherSuite;
- psk->resumption = resumption;
- psk->binderLen = GetHmacLength(psk->hmac);
- if (preSharedKey != NULL)
- *preSharedKey = psk;
- return 0;
- }
- #define PSK_FREE_ALL TLSX_PreSharedKey_FreeAll
- #define PSK_GET_SIZE TLSX_PreSharedKey_GetSize
- #define PSK_WRITE TLSX_PreSharedKey_Write
- #define PSK_PARSE TLSX_PreSharedKey_Parse
- #else
- #define PSK_FREE_ALL(a, b)
- #define PSK_GET_SIZE(a, b, c) 0
- #define PSK_WRITE(a, b, c, d) 0
- #define PSK_PARSE(a, b, c, d) 0
- #endif
- /******************************************************************************/
- /* PSK Key Exchange Modes */
- /******************************************************************************/
- #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
- /* Get the size of the encoded PSK KE modes extension.
- * Only in ClientHello.
- *
- * modes The PSK KE mode bit string.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes of the encoded PSK KE mode extension.
- */
- static int TLSX_PskKeModes_GetSize(byte modes, byte msgType, word16* pSz)
- {
- if (msgType == client_hello) {
- /* Format: Len | Modes* */
- word16 len = OPAQUE8_LEN;
- /* Check whether each possible mode is to be written. */
- if (modes & (1 << PSK_KE))
- len += OPAQUE8_LEN;
- if (modes & (1 << PSK_DHE_KE))
- len += OPAQUE8_LEN;
- *pSz += len;
- return 0;
- }
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Writes the PSK KE modes extension into the output buffer.
- * Assumes that the the output buffer is big enough to hold data.
- * Only in ClientHello.
- *
- * modes The PSK KE mode bit string.
- * output The buffer to write into.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes written into the buffer.
- */
- static int TLSX_PskKeModes_Write(byte modes, byte* output, byte msgType,
- word16* pSz)
- {
- if (msgType == client_hello) {
- /* Format: Len | Modes* */
- word16 idx = OPAQUE8_LEN;
- /* Write out each possible mode. */
- if (modes & (1 << PSK_KE))
- output[idx++] = PSK_KE;
- if (modes & (1 << PSK_DHE_KE))
- output[idx++] = PSK_DHE_KE;
- /* Write out length of mode list. */
- output[0] = (byte)(idx - OPAQUE8_LEN);
- *pSz += idx;
- return 0;
- }
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Parse the PSK KE modes extension.
- * Only in ClientHello.
- *
- * ssl The SSL/TLS object.
- * input The extension data.
- * length The length of the extension data.
- * msgType The type of the message this extension is being parsed from.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_PskKeModes_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte msgType)
- {
- int ret;
- if (msgType == client_hello) {
- /* Format: Len | Modes* */
- int idx = 0;
- word16 len;
- byte modes = 0;
- /* Ensure length byte exists. */
- if (length < OPAQUE8_LEN)
- return BUFFER_E;
- /* Get length of mode list and ensure that is the only data. */
- len = input[0];
- if (length - OPAQUE8_LEN != len)
- return BUFFER_E;
- idx = OPAQUE8_LEN;
- /* Set a bit for each recognized modes. */
- while (len > 0) {
- /* Ignore unrecognized modes. */
- if (input[idx] <= PSK_DHE_KE)
- modes |= 1 << input[idx];
- idx++;
- len--;
- }
- ret = TLSX_PskKeModes_Use(ssl, modes);
- if (ret != 0)
- return ret;
- return 0;
- }
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Use the data to create a new PSK Key Exchange Modes object in the extensions.
- *
- * ssl The SSL/TLS object.
- * modes The PSK key exchange modes.
- * returns 0 on success and other values indicate failure.
- */
- int TLSX_PskKeModes_Use(WOLFSSL* ssl, byte modes)
- {
- int ret = 0;
- TLSX* extension;
- /* Find the PSK key exchange modes extension if it exists. */
- extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
- if (extension == NULL) {
- /* Push new PSK key exchange modes extension. */
- ret = TLSX_Push(&ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES, NULL,
- ssl->heap);
- if (ret != 0)
- return ret;
- extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
- if (extension == NULL)
- return MEMORY_E;
- }
- extension->val = modes;
- return 0;
- }
- #define PKM_GET_SIZE TLSX_PskKeModes_GetSize
- #define PKM_WRITE TLSX_PskKeModes_Write
- #define PKM_PARSE TLSX_PskKeModes_Parse
- #else
- #define PKM_GET_SIZE(a, b, c) 0
- #define PKM_WRITE(a, b, c, d) 0
- #define PKM_PARSE(a, b, c, d) 0
- #endif
- /******************************************************************************/
- /* Post-Handshake Authentication */
- /******************************************************************************/
- #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
- /* Get the size of the encoded Post-Handshake Authentication extension.
- * Only in ClientHello.
- *
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes of the encoded Post-Handshake Authentication
- * extension.
- */
- static int TLSX_PostHandAuth_GetSize(byte msgType, word16* pSz)
- {
- if (msgType == client_hello) {
- *pSz += 0;
- return 0;
- }
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Writes the Post-Handshake Authentication extension into the output buffer.
- * Assumes that the the output buffer is big enough to hold data.
- * Only in ClientHello.
- *
- * output The buffer to write into.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes written into the buffer.
- */
- static int TLSX_PostHandAuth_Write(byte* output, byte msgType, word16* pSz)
- {
- (void)output;
- if (msgType == client_hello) {
- *pSz += 0;
- return 0;
- }
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Parse the Post-Handshake Authentication extension.
- * Only in ClientHello.
- *
- * ssl The SSL/TLS object.
- * input The extension data.
- * length The length of the extension data.
- * msgType The type of the message this extension is being parsed from.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_PostHandAuth_Parse(WOLFSSL* ssl, const byte* input,
- word16 length, byte msgType)
- {
- (void)input;
- if (msgType == client_hello) {
- /* Ensure extension is empty. */
- if (length != 0)
- return BUFFER_E;
- ssl->options.postHandshakeAuth = 1;
- return 0;
- }
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Create a new Post-handshake authentication object in the extensions.
- *
- * ssl The SSL/TLS object.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_PostHandAuth_Use(WOLFSSL* ssl)
- {
- int ret = 0;
- TLSX* extension;
- /* Find the PSK key exchange modes extension if it exists. */
- extension = TLSX_Find(ssl->extensions, TLSX_POST_HANDSHAKE_AUTH);
- if (extension == NULL) {
- /* Push new Post-handshake Authentication extension. */
- ret = TLSX_Push(&ssl->extensions, TLSX_POST_HANDSHAKE_AUTH, NULL,
- ssl->heap);
- if (ret != 0)
- return ret;
- }
- return 0;
- }
- #define PHA_GET_SIZE TLSX_PostHandAuth_GetSize
- #define PHA_WRITE TLSX_PostHandAuth_Write
- #define PHA_PARSE TLSX_PostHandAuth_Parse
- #else
- #define PHA_GET_SIZE(a, b) 0
- #define PHA_WRITE(a, b, c) 0
- #define PHA_PARSE(a, b, c, d) 0
- #endif
- /******************************************************************************/
- /* Early Data Indication */
- /******************************************************************************/
- #ifdef WOLFSSL_EARLY_DATA
- /* Get the size of the encoded Early Data Indication extension.
- * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
- *
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes of the encoded Early Data Indication extension.
- */
- static int TLSX_EarlyData_GetSize(byte msgType, word16* pSz)
- {
- int ret = 0;
- if (msgType == client_hello || msgType == encrypted_extensions)
- *pSz += 0;
- else if (msgType == session_ticket)
- *pSz += OPAQUE32_LEN;
- else {
- ret = SANITY_MSG_E;
- WOLFSSL_ERROR_VERBOSE(ret);
- }
- return ret;
- }
- /* Writes the Early Data Indicator extension into the output buffer.
- * Assumes that the the output buffer is big enough to hold data.
- * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
- *
- * maxSz The maximum early data size.
- * output The buffer to write into.
- * msgType The type of the message this extension is being written into.
- * returns the number of bytes written into the buffer.
- */
- static int TLSX_EarlyData_Write(word32 maxSz, byte* output, byte msgType,
- word16* pSz)
- {
- if (msgType == client_hello || msgType == encrypted_extensions)
- return 0;
- else if (msgType == session_ticket) {
- c32toa(maxSz, output);
- *pSz += OPAQUE32_LEN;
- return 0;
- }
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Parse the Early Data Indicator extension.
- * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
- *
- * ssl The SSL/TLS object.
- * input The extension data.
- * length The length of the extension data.
- * msgType The type of the message this extension is being parsed from.
- * returns 0 on success and other values indicate failure.
- */
- static int TLSX_EarlyData_Parse(WOLFSSL* ssl, const byte* input, word16 length,
- byte msgType)
- {
- if (msgType == client_hello) {
- if (length != 0)
- return BUFFER_E;
- if (ssl->earlyData == expecting_early_data) {
- if (ssl->options.maxEarlyDataSz != 0)
- ssl->earlyDataStatus = WOLFSSL_EARLY_DATA_ACCEPTED;
- else
- ssl->earlyDataStatus = WOLFSSL_EARLY_DATA_REJECTED;
- return TLSX_EarlyData_Use(ssl, 0, 0);
- }
- ssl->earlyData = early_data_ext;
- return 0;
- }
- if (msgType == encrypted_extensions) {
- if (length != 0)
- return BUFFER_E;
- /* Ensure the index of PSK identity chosen by server is 0.
- * Index is plus one to handle 'not set' value of 0.
- */
- if (ssl->options.pskIdIndex != 1) {
- WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
- return PSK_KEY_ERROR;
- }
- if (ssl->options.side == WOLFSSL_CLIENT_END) {
- /* the extension from server comes in */
- ssl->earlyDataStatus = WOLFSSL_EARLY_DATA_ACCEPTED;
- }
- return TLSX_EarlyData_Use(ssl, 1, 1);
- }
- if (msgType == session_ticket) {
- word32 maxSz;
- if (length != OPAQUE32_LEN)
- return BUFFER_E;
- ato32(input, &maxSz);
- ssl->session->maxEarlyDataSz = maxSz;
- return 0;
- }
- WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
- return SANITY_MSG_E;
- }
- /* Use the data to create a new Early Data object in the extensions.
- *
- * ssl The SSL/TLS object.
- * maxSz The maximum early data size.
- * is_response if this extension is part of a response
- * returns 0 on success and other values indicate failure.
- */
- int TLSX_EarlyData_Use(WOLFSSL* ssl, word32 maxSz, int is_response)
- {
- int ret = 0;
- TLSX* extension;
- /* Find the early data extension if it exists. */
- extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
- if (extension == NULL) {
- /* Push new early data extension. */
- ret = TLSX_Push(&ssl->extensions, TLSX_EARLY_DATA, NULL, ssl->heap);
- if (ret != 0)
- return ret;
- extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
- if (extension == NULL)
- return MEMORY_E;
- }
- extension->resp = is_response;
- extension->val = maxSz;
- return 0;
- }
- #define EDI_GET_SIZE TLSX_EarlyData_GetSize
- #define EDI_WRITE TLSX_EarlyData_Write
- #define EDI_PARSE TLSX_EarlyData_Parse
- #else
- #define EDI_GET_SIZE(a, b) 0
- #define EDI_WRITE(a, b, c, d) 0
- #define EDI_PARSE(a, b, c, d) 0
- #endif
- /******************************************************************************/
- /* QUIC transport parameter extension */
- /******************************************************************************/
- #ifdef WOLFSSL_QUIC
- static word16 TLSX_QuicTP_GetSize(TLSX* extension)
- {
- const QuicTransportParam *tp = (QuicTransportParam*)extension->data;
- return tp ? tp->len : 0;
- }
- int TLSX_QuicTP_Use(WOLFSSL* ssl, TLSX_Type ext_type, int is_response)
- {
- int ret = 0;
- TLSX* extension;
- WOLFSSL_ENTER("TLSX_QuicTP_Use");
- if (ssl->quic.transport_local == NULL) {
- /* RFC9000, ch 7.3: "An endpoint MUST treat the absence of [...]
- * from either endpoint [...] as a connection error of type
- * TRANSPORT_PARAMETER_ERROR."
- */
- ret = QUIC_TP_MISSING_E;
- goto cleanup;
- }
- extension = TLSX_Find(ssl->extensions, ext_type);
- if (extension == NULL) {
- ret = TLSX_Push(&ssl->extensions, ext_type, NULL, ssl->heap);
- if (ret != 0)
- goto cleanup;
- extension = TLSX_Find(ssl->extensions, ext_type);
- if (extension == NULL) {
- ret = MEMORY_E;
- goto cleanup;
- }
- }
- if (extension->data) {
- QuicTransportParam_free((QuicTransportParam*)extension->data, ssl->heap);
- extension->data = NULL;
- }
- extension->resp = is_response;
- extension->data = (void*)QuicTransportParam_dup(ssl->quic.transport_local, ssl->heap);
- if (!extension->data) {
- ret = MEMORY_E;
- goto cleanup;
- }
- cleanup:
- WOLFSSL_LEAVE("TLSX_QuicTP_Use", ret);
- return ret;
- }
- static word16 TLSX_QuicTP_Write(QuicTransportParam *tp, byte* output)
- {
- word16 len = 0;
- WOLFSSL_ENTER("TLSX_QuicTP_Write");
- if (tp && tp->len) {
- XMEMCPY(output, tp->data, tp->len);
- len = tp->len;
- }
- WOLFSSL_LEAVE("TLSX_QuicTP_Write", len);
- return len;
- }
- static int TLSX_QuicTP_Parse(WOLFSSL *ssl, const byte *input, size_t len, int ext_type, int msgType)
- {
- const QuicTransportParam *tp, **ptp;
- (void)msgType;
- tp = QuicTransportParam_new(input, len, ssl->heap);
- if (!tp) {
- return MEMORY_E;
- }
- ptp = (ext_type == TLSX_KEY_QUIC_TP_PARAMS_DRAFT) ?
- &ssl->quic.transport_peer_draft : &ssl->quic.transport_peer;
- if (*ptp) {
- QTP_FREE(*ptp, ssl->heap);
- }
- *ptp = tp;
- return 0;
- }
- #define QTP_GET_SIZE TLSX_QuicTP_GetSize
- #define QTP_USE TLSX_QuicTP_Use
- #define QTP_WRITE TLSX_QuicTP_Write
- #define QTP_PARSE TLSX_QuicTP_Parse
- #endif /* WOLFSSL_QUIC */
- #if defined(WOLFSSL_DTLS_CID)
- #define CID_GET_SIZE TLSX_ConnectionID_GetSize
- #define CID_WRITE TLSX_ConnectionID_Write
- #define CID_PARSE TLSX_ConnectionID_Parse
- #define CID_FREE TLSX_ConnectionID_Free
- #else
- #define CID_GET_SIZE(a) 0
- #define CID_WRITE(a, b) 0
- #define CID_PARSE(a, b, c, d) 0
- #define CID_FREE(a, b) 0
- #endif /* defined(WOLFSSL_DTLS_CID) */
- /******************************************************************************/
- /* TLS Extensions Framework */
- /******************************************************************************/
- /** Finds an extension in the provided list. */
- TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
- {
- TLSX* extension = list;
- while (extension && extension->type != type)
- extension = extension->next;
- return extension;
- }
- /** Remove an extension. */
- void TLSX_Remove(TLSX** list, TLSX_Type type, void* heap)
- {
- TLSX* extension = *list;
- TLSX** next = list;
- while (extension && extension->type != type) {
- next = &extension->next;
- extension = extension->next;
- }
- if (extension) {
- *next = extension->next;
- extension->next = NULL;
- TLSX_FreeAll(extension, heap);
- }
- }
- /** Releases all extensions in the provided list. */
- void TLSX_FreeAll(TLSX* list, void* heap)
- {
- TLSX* extension;
- while ((extension = list)) {
- list = extension->next;
- switch (extension->type) {
- #ifdef HAVE_SNI
- case TLSX_SERVER_NAME:
- SNI_FREE_ALL((SNI*)extension->data, heap);
- break;
- #endif
- case TLSX_TRUSTED_CA_KEYS:
- TCA_FREE_ALL((TCA*)extension->data, heap);
- break;
- case TLSX_MAX_FRAGMENT_LENGTH:
- MFL_FREE_ALL(extension->data, heap);
- break;
- case TLSX_EXTENDED_MASTER_SECRET:
- case TLSX_TRUNCATED_HMAC:
- /* Nothing to do. */
- break;
- case TLSX_SUPPORTED_GROUPS:
- EC_FREE_ALL((SupportedCurve*)extension->data, heap);
- break;
- case TLSX_EC_POINT_FORMATS:
- PF_FREE_ALL((PointFormat*)extension->data, heap);
- break;
- case TLSX_STATUS_REQUEST:
- CSR_FREE_ALL((CertificateStatusRequest*)extension->data, heap);
- break;
- case TLSX_STATUS_REQUEST_V2:
- CSR2_FREE_ALL((CertificateStatusRequestItemV2*)extension->data,
- heap);
- break;
- case TLSX_RENEGOTIATION_INFO:
- SCR_FREE_ALL(extension->data, heap);
- break;
- case TLSX_SESSION_TICKET:
- WOLF_STK_FREE(extension->data, heap);
- break;
- case TLSX_APPLICATION_LAYER_PROTOCOL:
- ALPN_FREE_ALL((ALPN*)extension->data, heap);
- break;
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- case TLSX_SIGNATURE_ALGORITHMS:
- break;
- #endif
- #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
- case TLSX_ENCRYPT_THEN_MAC:
- break;
- #endif
- #ifdef WOLFSSL_TLS13
- case TLSX_SUPPORTED_VERSIONS:
- break;
- #ifdef WOLFSSL_SEND_HRR_COOKIE
- case TLSX_COOKIE:
- CKE_FREE_ALL((Cookie*)extension->data, heap);
- break;
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- case TLSX_PRE_SHARED_KEY:
- PSK_FREE_ALL((PreSharedKey*)extension->data, heap);
- break;
- case TLSX_PSK_KEY_EXCHANGE_MODES:
- break;
- #endif
- #ifdef WOLFSSL_EARLY_DATA
- case TLSX_EARLY_DATA:
- break;
- #endif
- #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
- case TLSX_POST_HANDSHAKE_AUTH:
- break;
- #endif
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- case TLSX_SIGNATURE_ALGORITHMS_CERT:
- break;
- #endif
- case TLSX_KEY_SHARE:
- KS_FREE_ALL((KeyShareEntry*)extension->data, heap);
- break;
- #endif
- #ifdef WOLFSSL_SRTP
- case TLSX_USE_SRTP:
- SRTP_FREE((TlsxSrtp*)extension->data, heap);
- break;
- #endif
- #ifdef WOLFSSL_QUIC
- case TLSX_KEY_QUIC_TP_PARAMS:
- FALL_THROUGH;
- case TLSX_KEY_QUIC_TP_PARAMS_DRAFT:
- QTP_FREE((QuicTransportParam*)extension->data, heap);
- break;
- #endif
- #ifdef WOLFSSL_DTLS_CID
- case TLSX_CONNECTION_ID:
- CID_FREE((byte*)extension->data, heap);
- break;
- #endif /* WOLFSSL_DTLS_CID */
- default:
- break;
- }
- XFREE(extension, heap, DYNAMIC_TYPE_TLSX);
- }
- (void)heap;
- }
- /** Checks if the tls extensions are supported based on the protocol version. */
- int TLSX_SupportExtensions(WOLFSSL* ssl) {
- return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR);
- }
- /** Tells the buffered size of the extensions in a list. */
- static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
- word16* pLength)
- {
- int ret = 0;
- TLSX* extension;
- word16 length = 0;
- byte isRequest = (msgType == client_hello ||
- msgType == certificate_request);
- while ((extension = list)) {
- list = extension->next;
- /* only extensions marked as response are sent back to the client. */
- if (!isRequest && !extension->resp)
- continue; /* skip! */
- /* ssl level extensions are expected to override ctx level ones. */
- if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
- continue; /* skip! */
- /* extension type + extension data length. */
- length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
- switch (extension->type) {
- #ifdef HAVE_SNI
- case TLSX_SERVER_NAME:
- /* SNI only sends the name on the request. */
- if (isRequest)
- length += SNI_GET_SIZE((SNI*)extension->data);
- break;
- #endif
- case TLSX_TRUSTED_CA_KEYS:
- /* TCA only sends the list on the request. */
- if (isRequest)
- length += TCA_GET_SIZE((TCA*)extension->data);
- break;
- case TLSX_MAX_FRAGMENT_LENGTH:
- length += MFL_GET_SIZE(extension->data);
- break;
- case TLSX_EXTENDED_MASTER_SECRET:
- case TLSX_TRUNCATED_HMAC:
- /* always empty. */
- break;
- case TLSX_SUPPORTED_GROUPS:
- length += EC_GET_SIZE((SupportedCurve*)extension->data);
- break;
- case TLSX_EC_POINT_FORMATS:
- length += PF_GET_SIZE((PointFormat*)extension->data);
- break;
- case TLSX_STATUS_REQUEST:
- length += CSR_GET_SIZE(
- (CertificateStatusRequest*)extension->data, isRequest);
- break;
- case TLSX_STATUS_REQUEST_V2:
- length += CSR2_GET_SIZE(
- (CertificateStatusRequestItemV2*)extension->data,
- isRequest);
- break;
- case TLSX_RENEGOTIATION_INFO:
- length += SCR_GET_SIZE((SecureRenegotiation*)extension->data,
- isRequest);
- break;
- case TLSX_SESSION_TICKET:
- length += WOLF_STK_GET_SIZE((SessionTicket*)extension->data,
- isRequest);
- break;
- case TLSX_APPLICATION_LAYER_PROTOCOL:
- length += ALPN_GET_SIZE((ALPN*)extension->data);
- break;
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- case TLSX_SIGNATURE_ALGORITHMS:
- length += SA_GET_SIZE(extension->data);
- break;
- #endif
- #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
- case TLSX_ENCRYPT_THEN_MAC:
- ret = ETM_GET_SIZE(msgType, &length);
- break;
- #endif /* HAVE_ENCRYPT_THEN_MAC */
- #ifdef WOLFSSL_TLS13
- case TLSX_SUPPORTED_VERSIONS:
- ret = SV_GET_SIZE(extension->data, msgType, &length);
- break;
- #ifdef WOLFSSL_SEND_HRR_COOKIE
- case TLSX_COOKIE:
- ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &length);
- break;
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- case TLSX_PRE_SHARED_KEY:
- ret = PSK_GET_SIZE((PreSharedKey*)extension->data, msgType,
- &length);
- break;
- case TLSX_PSK_KEY_EXCHANGE_MODES:
- ret = PKM_GET_SIZE((byte)extension->val, msgType, &length);
- break;
- #endif
- #ifdef WOLFSSL_EARLY_DATA
- case TLSX_EARLY_DATA:
- ret = EDI_GET_SIZE(msgType, &length);
- break;
- #endif
- #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
- case TLSX_POST_HANDSHAKE_AUTH:
- ret = PHA_GET_SIZE(msgType, &length);
- break;
- #endif
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- case TLSX_SIGNATURE_ALGORITHMS_CERT:
- length += SAC_GET_SIZE(extension->data);
- break;
- #endif
- case TLSX_KEY_SHARE:
- length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType);
- break;
- #endif
- #ifdef WOLFSSL_SRTP
- case TLSX_USE_SRTP:
- length += SRTP_GET_SIZE((TlsxSrtp*)extension->data);
- break;
- #endif
- #ifdef WOLFSSL_QUIC
- case TLSX_KEY_QUIC_TP_PARAMS:
- FALL_THROUGH; /* followed by */
- case TLSX_KEY_QUIC_TP_PARAMS_DRAFT:
- length += QTP_GET_SIZE(extension);
- break;
- #endif
- #ifdef WOLFSSL_DTLS_CID
- case TLSX_CONNECTION_ID:
- length += CID_GET_SIZE((byte*)extension->data);
- break;
- #endif /* WOLFSSL_DTLS_CID */
- default:
- break;
- }
- /* marks the extension as processed so ctx level */
- /* extensions don't overlap with ssl level ones. */
- TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
- }
- *pLength += length;
- return ret;
- }
- /** Writes the extensions of a list in a buffer. */
- static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
- byte msgType, word16* pOffset)
- {
- int ret = 0;
- TLSX* extension;
- word16 offset = 0;
- word16 length_offset = 0;
- byte isRequest = (msgType == client_hello ||
- msgType == certificate_request);
- while ((extension = list)) {
- list = extension->next;
- /* only extensions marked as response are written in a response. */
- if (!isRequest && !extension->resp)
- continue; /* skip! */
- /* ssl level extensions are expected to override ctx level ones. */
- if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
- continue; /* skip! */
- /* writes extension type. */
- c16toa(extension->type, output + offset);
- offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
- length_offset = offset;
- /* extension data should be written internally. */
- switch (extension->type) {
- #ifdef HAVE_SNI
- case TLSX_SERVER_NAME:
- if (isRequest) {
- WOLFSSL_MSG("SNI extension to write");
- offset += SNI_WRITE((SNI*)extension->data, output + offset);
- }
- break;
- #endif
- case TLSX_TRUSTED_CA_KEYS:
- WOLFSSL_MSG("Trusted CA Indication extension to write");
- if (isRequest) {
- offset += TCA_WRITE((TCA*)extension->data, output + offset);
- }
- break;
- case TLSX_MAX_FRAGMENT_LENGTH:
- WOLFSSL_MSG("Max Fragment Length extension to write");
- offset += MFL_WRITE((byte*)extension->data, output + offset);
- break;
- case TLSX_EXTENDED_MASTER_SECRET:
- WOLFSSL_MSG("Extended Master Secret");
- /* always empty. */
- break;
- case TLSX_TRUNCATED_HMAC:
- WOLFSSL_MSG("Truncated HMAC extension to write");
- /* always empty. */
- break;
- case TLSX_SUPPORTED_GROUPS:
- WOLFSSL_MSG("Supported Groups extension to write");
- offset += EC_WRITE((SupportedCurve*)extension->data,
- output + offset);
- break;
- case TLSX_EC_POINT_FORMATS:
- WOLFSSL_MSG("Point Formats extension to write");
- offset += PF_WRITE((PointFormat*)extension->data,
- output + offset);
- break;
- case TLSX_STATUS_REQUEST:
- WOLFSSL_MSG("Certificate Status Request extension to write");
- offset += CSR_WRITE((CertificateStatusRequest*)extension->data,
- output + offset, isRequest);
- break;
- case TLSX_STATUS_REQUEST_V2:
- WOLFSSL_MSG("Certificate Status Request v2 extension to write");
- offset += CSR2_WRITE(
- (CertificateStatusRequestItemV2*)extension->data,
- output + offset, isRequest);
- break;
- case TLSX_RENEGOTIATION_INFO:
- WOLFSSL_MSG("Secure Renegotiation extension to write");
- offset += SCR_WRITE((SecureRenegotiation*)extension->data,
- output + offset, isRequest);
- break;
- case TLSX_SESSION_TICKET:
- WOLFSSL_MSG("Session Ticket extension to write");
- offset += WOLF_STK_WRITE((SessionTicket*)extension->data,
- output + offset, isRequest);
- break;
- case TLSX_APPLICATION_LAYER_PROTOCOL:
- WOLFSSL_MSG("ALPN extension to write");
- offset += ALPN_WRITE((ALPN*)extension->data, output + offset);
- break;
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- case TLSX_SIGNATURE_ALGORITHMS:
- WOLFSSL_MSG("Signature Algorithms extension to write");
- offset += SA_WRITE(extension->data, output + offset);
- break;
- #endif
- #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
- case TLSX_ENCRYPT_THEN_MAC:
- WOLFSSL_MSG("Encrypt-Then-Mac extension to write");
- ret = ETM_WRITE(extension->data, output, msgType, &offset);
- break;
- #endif /* HAVE_ENCRYPT_THEN_MAC */
- #ifdef WOLFSSL_TLS13
- case TLSX_SUPPORTED_VERSIONS:
- WOLFSSL_MSG("Supported Versions extension to write");
- ret = SV_WRITE(extension->data, output + offset, msgType, &offset);
- break;
- #ifdef WOLFSSL_SEND_HRR_COOKIE
- case TLSX_COOKIE:
- WOLFSSL_MSG("Cookie extension to write");
- ret = CKE_WRITE((Cookie*)extension->data, output + offset,
- msgType, &offset);
- break;
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- case TLSX_PRE_SHARED_KEY:
- WOLFSSL_MSG("Pre-Shared Key extension to write");
- ret = PSK_WRITE((PreSharedKey*)extension->data, output + offset,
- msgType, &offset);
- break;
- case TLSX_PSK_KEY_EXCHANGE_MODES:
- WOLFSSL_MSG("PSK Key Exchange Modes extension to write");
- ret = PKM_WRITE((byte)extension->val, output + offset, msgType,
- &offset);
- break;
- #endif
- #ifdef WOLFSSL_EARLY_DATA
- case TLSX_EARLY_DATA:
- WOLFSSL_MSG("Early Data extension to write");
- ret = EDI_WRITE(extension->val, output + offset, msgType,
- &offset);
- break;
- #endif
- #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
- case TLSX_POST_HANDSHAKE_AUTH:
- WOLFSSL_MSG("Post-Handshake Authentication extension to write");
- ret = PHA_WRITE(output + offset, msgType, &offset);
- break;
- #endif
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- case TLSX_SIGNATURE_ALGORITHMS_CERT:
- WOLFSSL_MSG("Signature Algorithms extension to write");
- offset += SAC_WRITE(extension->data, output + offset);
- break;
- #endif
- case TLSX_KEY_SHARE:
- WOLFSSL_MSG("Key Share extension to write");
- offset += KS_WRITE((KeyShareEntry*)extension->data,
- output + offset, msgType);
- break;
- #endif
- #ifdef WOLFSSL_SRTP
- case TLSX_USE_SRTP:
- offset += SRTP_WRITE((TlsxSrtp*)extension->data, output+offset);
- break;
- #endif
- #ifdef WOLFSSL_QUIC
- case TLSX_KEY_QUIC_TP_PARAMS:
- FALL_THROUGH;
- case TLSX_KEY_QUIC_TP_PARAMS_DRAFT:
- WOLFSSL_MSG("QUIC transport parameter to write");
- offset += QTP_WRITE((QuicTransportParam*)extension->data,
- output + offset);
- break;
- #endif
- #ifdef WOLFSSL_DTLS_CID
- case TLSX_CONNECTION_ID:
- offset += CID_WRITE((byte*)extension->data, output+offset);
- break;
- #endif /* WOLFSSL_DTLS_CID */
- default:
- break;
- }
- /* writes extension data length. */
- c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN);
- /* marks the extension as processed so ctx level */
- /* extensions don't overlap with ssl level ones. */
- TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
- }
- *pOffset += offset;
- return ret;
- }
- #ifdef HAVE_SUPPORTED_CURVES
- /* Populates the default supported groups / curves */
- static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
- {
- int ret = WOLFSSL_SUCCESS;
- #ifdef WOLFSSL_TLS13
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- if (ssl->options.resuming && ssl->session->namedGroup != 0) {
- return TLSX_UseSupportedCurve(extensions, ssl->session->namedGroup,
- ssl->heap);
- }
- #endif
- if (ssl->numGroups != 0) {
- int i;
- for (i = 0; i < ssl->numGroups; i++) {
- ret = TLSX_UseSupportedCurve(extensions, ssl->group[i], ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- return WOLFSSL_SUCCESS;
- }
- #endif /* WOLFSSL_TLS13 */
- #if defined(HAVE_ECC)
- /* list in order by strength, since not all servers choose by strength */
- #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
- #ifndef NO_ECC_SECP
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP521R1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #endif
- #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
- #ifdef HAVE_ECC_BRAINPOOL
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #endif
- #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
- #ifndef NO_ECC_SECP
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP384R1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #ifdef HAVE_ECC_BRAINPOOL
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #endif
- #endif /* HAVE_ECC */
- #ifndef HAVE_FIPS
- #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_X448, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #endif /* HAVE_FIPS */
- #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
- #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
- #ifndef NO_ECC_SECP
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP256R1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #ifdef HAVE_ECC_KOBLITZ
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP256K1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #ifdef HAVE_ECC_BRAINPOOL
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #endif
- #endif /* HAVE_ECC */
- #ifndef HAVE_FIPS
- #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_X25519, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #endif /* HAVE_FIPS */
- #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
- #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
- #ifndef NO_ECC_SECP
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP224R1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #ifdef HAVE_ECC_KOBLITZ
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP224K1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #endif
- #ifndef HAVE_FIPS
- #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
- #ifndef NO_ECC_SECP
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP192R1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #ifdef HAVE_ECC_KOBLITZ
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP192K1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #endif
- #if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
- #ifndef NO_ECC_SECP
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP160R1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #ifdef HAVE_ECC_SECPR2
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP160R2, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #ifdef HAVE_ECC_KOBLITZ
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_ECC_SECP160K1, ssl->heap);
- if (ret != WOLFSSL_SUCCESS) return ret;
- #endif
- #endif
- #endif /* HAVE_FIPS */
- #endif /* HAVE_ECC */
- #ifndef NO_DH
- /* Add FFDHE supported groups. */
- #ifdef HAVE_FFDHE_8192
- if (8192/8 >= ssl->options.minDhKeySz &&
- 8192/8 <= ssl->options.maxDhKeySz) {
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_FFDHE_8192, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif
- #ifdef HAVE_FFDHE_6144
- if (6144/8 >= ssl->options.minDhKeySz &&
- 6144/8 <= ssl->options.maxDhKeySz) {
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_FFDHE_6144, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif
- #ifdef HAVE_FFDHE_4096
- if (4096/8 >= ssl->options.minDhKeySz &&
- 4096/8 <= ssl->options.maxDhKeySz) {
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_FFDHE_4096, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif
- #ifdef HAVE_FFDHE_3072
- if (3072/8 >= ssl->options.minDhKeySz &&
- 3072/8 <= ssl->options.maxDhKeySz) {
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_FFDHE_3072, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif
- #ifdef HAVE_FFDHE_2048
- if (2048/8 >= ssl->options.minDhKeySz &&
- 2048/8 <= ssl->options.maxDhKeySz) {
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_FFDHE_2048, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif
- #endif
- #ifdef HAVE_PQC
- #ifdef WOLFSSL_WC_KYBER
- #ifdef WOLFSSL_KYBER512
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1,
- ssl->heap);
- #endif
- #ifdef WOLFSSL_KYBER768
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL3,
- ssl->heap);
- #endif
- #ifdef WOLFSSL_KYBER768
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL5,
- ssl->heap);
- #endif
- #elif defined(HAVE_LIBOQS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1, ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL3,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL5,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_90S_LEVEL1,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_90S_LEVEL3,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_90S_LEVEL5,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_LEVEL1,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P384_KYBER_LEVEL3,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_LEVEL5,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_90S_LEVEL1,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P384_KYBER_90S_LEVEL3,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_90S_LEVEL5,
- ssl->heap);
- #elif defined(HAVE_PQM4)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1, ssl->heap);
- #endif /* HAVE_LIBOQS */
- #endif /* HAVE_PQC */
- (void)ssl;
- (void)extensions;
- return ret;
- }
- #endif /* HAVE_SUPPORTED_CURVES */
- #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
- static const word16 preferredGroup[] = {
- #if defined(HAVE_ECC) && (!defined(NO_ECC256) || \
- defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 256
- WOLFSSL_ECC_SECP256R1,
- #endif
- #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
- WOLFSSL_ECC_X25519,
- #endif
- #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
- WOLFSSL_ECC_X448,
- #endif
- #if defined(HAVE_ECC) && (!defined(NO_ECC384) || \
- defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 384
- WOLFSSL_ECC_SECP384R1,
- #endif
- #if defined(HAVE_ECC) && (!defined(NO_ECC521) || \
- defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 521
- WOLFSSL_ECC_SECP521R1,
- #endif
- #if defined(HAVE_FFDHE_2048)
- WOLFSSL_FFDHE_2048,
- #endif
- #if defined(HAVE_FFDHE_3072)
- WOLFSSL_FFDHE_3072,
- #endif
- #if defined(HAVE_FFDHE_4096)
- WOLFSSL_FFDHE_4096,
- #endif
- #if defined(HAVE_FFDHE_6144)
- WOLFSSL_FFDHE_6144,
- #endif
- #if defined(HAVE_FFDHE_8192)
- WOLFSSL_FFDHE_8192,
- #endif
- WOLFSSL_NAMED_GROUP_INVALID
- };
- #endif /* WOLFSSL_TLS13 && HAVE_SUPPORTED_CURVES */
- int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
- {
- int ret = 0;
- byte* public_key = NULL;
- word16 public_key_len = 0;
- #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
- int usingPSK = 0;
- #endif
- #if defined(HAVE_SUPPORTED_CURVES) && defined(WOLFSSL_TLS13)
- TLSX* extension = NULL;
- word16 namedGroup = WOLFSSL_NAMED_GROUP_INVALID;
- #endif
- /* server will add extension depending on what is parsed from client */
- if (!isServer) {
- #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
- if (!ssl->options.disallowEncThenMac) {
- ret = TLSX_EncryptThenMac_Use(ssl);
- if (ret != 0)
- return ret;
- }
- #endif
- #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
- defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES)
- if (!ssl->options.userCurves && !ssl->ctx->userCurves) {
- if (TLSX_Find(ssl->ctx->extensions,
- TLSX_SUPPORTED_GROUPS) == NULL) {
- ret = TLSX_PopulateSupportedGroups(ssl, &ssl->extensions);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- }
- if ((!IsAtLeastTLSv1_3(ssl->version) || ssl->options.downgrade) &&
- TLSX_Find(ssl->ctx->extensions, TLSX_EC_POINT_FORMATS) == NULL &&
- TLSX_Find(ssl->extensions, TLSX_EC_POINT_FORMATS) == NULL) {
- ret = TLSX_UsePointFormat(&ssl->extensions,
- WOLFSSL_EC_PF_UNCOMPRESSED, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */
- #ifdef WOLFSSL_SRTP
- if (ssl->options.dtls && ssl->dtlsSrtpProfiles != 0) {
- WOLFSSL_MSG("Adding DTLS SRTP extension");
- if ((ret = TLSX_UseSRTP(&ssl->extensions, ssl->dtlsSrtpProfiles,
- ssl->heap)) != 0) {
- return ret;
- }
- }
- #endif
- } /* is not server */
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- WOLFSSL_MSG("Adding signature algorithms extension");
- if ((ret = TLSX_SetSignatureAlgorithms(&ssl->extensions, ssl, ssl->heap))
- != 0) {
- return ret;
- }
- #else
- ret = 0;
- #endif
- #ifdef WOLFSSL_TLS13
- if (!isServer && IsAtLeastTLSv1_3(ssl->version)) {
- /* Add mandatory TLS v1.3 extension: supported version */
- WOLFSSL_MSG("Adding supported versions extension");
- if ((ret = TLSX_SetSupportedVersions(&ssl->extensions, ssl,
- ssl->heap)) != 0) {
- return ret;
- }
- #if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && \
- !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)
- if (TLSX_Find(ssl->ctx->extensions, TLSX_SUPPORTED_GROUPS) == NULL) {
- /* Put in DH groups for TLS 1.3 only. */
- ret = TLSX_PopulateSupportedGroups(ssl, &ssl->extensions);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- /* ret value will be overwritten in !NO_PSK case */
- #ifdef NO_PSK
- ret = 0;
- #endif
- }
- #endif /* !(HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- if (ssl->certHashSigAlgoSz > 0) {
- WOLFSSL_MSG("Adding signature algorithms cert extension");
- if ((ret = TLSX_SetSignatureAlgorithmsCert(&ssl->extensions,
- ssl, ssl->heap)) != 0) {
- return ret;
- }
- }
- #endif
- #if defined(HAVE_SUPPORTED_CURVES)
- extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
- if (extension == NULL) {
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- if (ssl->options.resuming && ssl->session->namedGroup != 0)
- namedGroup = ssl->session->namedGroup;
- else
- #endif
- if (ssl->numGroups > 0) {
- int set = 0;
- int i, j;
- /* try to find the highest element in ssl->group[]
- * that is contained in preferredGroup[].
- */
- namedGroup = preferredGroup[0];
- for (i = 0; i < ssl->numGroups && !set; i++) {
- for (j = 0; preferredGroup[j] != WOLFSSL_NAMED_GROUP_INVALID; j++) {
- if (preferredGroup[j] == ssl->group[i]) {
- namedGroup = ssl->group[i];
- set = 1;
- break;
- }
- }
- }
- }
- else {
- /* Choose the most preferred group. */
- namedGroup = preferredGroup[0];
- }
- }
- else {
- KeyShareEntry* kse = (KeyShareEntry*)extension->data;
- if (kse)
- namedGroup = kse->group;
- }
- if (namedGroup > 0) {
- #ifdef HAVE_PQC
- /* For KEMs, the key share has already been generated. */
- if (!WOLFSSL_NAMED_GROUP_IS_PQC(namedGroup))
- #endif
- ret = TLSX_KeyShare_Use(ssl, namedGroup, 0, NULL, NULL);
- if (ret != 0)
- return ret;
- }
- #endif /* HAVE_SUPPORTED_CURVES */
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- TLSX_Remove(&ssl->extensions, TLSX_PRE_SHARED_KEY, ssl->heap);
- #endif
- #if defined(HAVE_SESSION_TICKET)
- if (ssl->options.resuming && ssl->session->ticketLen > 0) {
- WOLFSSL_SESSION* sess = ssl->session;
- #ifdef WOLFSSL_32BIT_MILLI_TIME
- word32 now, milli;
- #else
- word64 now, milli;
- #endif
- if (sess->ticketLen > MAX_PSK_ID_LEN) {
- WOLFSSL_MSG("Session ticket length for PSK ext is too large");
- return BUFFER_ERROR;
- }
- /* Determine the MAC algorithm for the cipher suite used. */
- ssl->options.cipherSuite0 = sess->cipherSuite0;
- ssl->options.cipherSuite = sess->cipherSuite;
- ret = SetCipherSpecs(ssl);
- if (ret != 0)
- return ret;
- now = TimeNowInMilliseconds();
- if (now == 0)
- return GETTIME_ERROR;
- #ifdef WOLFSSL_32BIT_MILLI_TIME
- if (now < sess->ticketSeen)
- milli = (0xFFFFFFFFU - sess->ticketSeen) + 1 + now;
- else
- milli = now - sess->ticketSeen;
- milli += sess->ticketAdd;
- /* Pre-shared key is mandatory extension for resumption. */
- ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen,
- milli, ssl->specs.mac_algorithm, ssl->options.cipherSuite0,
- ssl->options.cipherSuite, 1, NULL);
- #else
- milli = now - sess->ticketSeen + sess->ticketAdd;
- /* Pre-shared key is mandatory extension for resumption. */
- ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen,
- (word32)milli, ssl->specs.mac_algorithm,
- ssl->options.cipherSuite0, ssl->options.cipherSuite, 1,
- NULL);
- #endif
- if (ret != 0)
- return ret;
- usingPSK = 1;
- }
- #endif
- #ifndef NO_PSK
- #ifndef WOLFSSL_PSK_ONE_ID
- if (ssl->options.client_psk_cs_cb != NULL) {
- int i;
- for (i = 0; i < ssl->suites->suiteSz; i += 2) {
- byte cipherSuite0 = ssl->suites->suites[i + 0];
- byte cipherSuite = ssl->suites->suites[i + 1];
- unsigned int keySz;
- #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS
- int cnt = 0;
- #endif
- #ifdef HAVE_NULL_CIPHER
- if (cipherSuite0 == ECC_BYTE ||
- cipherSuite0 == ECDHE_PSK_BYTE) {
- if (cipherSuite != TLS_SHA256_SHA256 &&
- cipherSuite != TLS_SHA384_SHA384) {
- continue;
- }
- }
- else
- #endif
- if (cipherSuite0 != TLS13_BYTE)
- continue;
- #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS
- do {
- ssl->arrays->client_identity[0] = cnt;
- #endif
- ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0';
- keySz = ssl->options.client_psk_cs_cb(
- ssl, ssl->arrays->server_hint,
- ssl->arrays->client_identity, MAX_PSK_ID_LEN,
- ssl->arrays->psk_key, MAX_PSK_KEY_LEN,
- GetCipherNameInternal(cipherSuite0, cipherSuite));
- if (keySz > 0) {
- ssl->arrays->psk_keySz = keySz;
- ret = TLSX_PreSharedKey_Use(ssl,
- (byte*)ssl->arrays->client_identity,
- (word16)XSTRLEN(ssl->arrays->client_identity),
- 0, SuiteMac(ssl->suites->suites + i),
- cipherSuite0, cipherSuite, 0, NULL);
- if (ret != 0)
- return ret;
- #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS
- cnt++;
- #endif
- }
- #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS
- }
- while (keySz > 0);
- #endif
- }
- usingPSK = 1;
- }
- else
- #endif
- if (ssl->options.client_psk_cb != NULL ||
- ssl->options.client_psk_tls13_cb != NULL) {
- /* Default ciphersuite. */
- byte cipherSuite0 = TLS13_BYTE;
- byte cipherSuite = WOLFSSL_DEF_PSK_CIPHER;
- int cipherSuiteFlags = WOLFSSL_CIPHER_SUITE_FLAG_NONE;
- const char* cipherName = NULL;
- if (ssl->options.client_psk_tls13_cb != NULL) {
- ssl->arrays->psk_keySz = ssl->options.client_psk_tls13_cb(
- ssl, ssl->arrays->server_hint,
- ssl->arrays->client_identity, MAX_PSK_ID_LEN,
- ssl->arrays->psk_key, MAX_PSK_KEY_LEN, &cipherName);
- if (GetCipherSuiteFromName(cipherName, &cipherSuite0,
- &cipherSuite, &cipherSuiteFlags) != 0) {
- return PSK_KEY_ERROR;
- }
- }
- else {
- ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
- ssl->arrays->server_hint, ssl->arrays->client_identity,
- MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
- }
- #if defined(OPENSSL_EXTRA)
- /* OpenSSL treats 0 as a PSK key length of 0
- * and meaning no PSK available.
- */
- if (ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
- return PSK_KEY_ERROR;
- }
- if (ssl->arrays->psk_keySz > 0) {
- #else
- if (ssl->arrays->psk_keySz == 0 ||
- ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
- return PSK_KEY_ERROR;
- }
- #endif
- ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0';
- ssl->options.cipherSuite0 = cipherSuite0;
- ssl->options.cipherSuite = cipherSuite;
- (void)cipherSuiteFlags;
- ret = SetCipherSpecs(ssl);
- if (ret != 0)
- return ret;
- ret = TLSX_PreSharedKey_Use(ssl,
- (byte*)ssl->arrays->client_identity,
- (word16)XSTRLEN(ssl->arrays->client_identity),
- 0, ssl->specs.mac_algorithm,
- cipherSuite0, cipherSuite, 0,
- NULL);
- if (ret != 0)
- return ret;
- usingPSK = 1;
- #if defined(OPENSSL_EXTRA)
- }
- #endif
- }
- #endif /* !NO_PSK */
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- /* Some servers do not generate session tickets unless
- * the extension is seen in a non-resume client hello.
- * We used to send it only if we were otherwise using PSK.
- * Now always send it. Define NO_TLSX_PSKKEM_PLAIN_ANNOUNCE
- * to revert to the old behaviour. */
- #ifdef NO_TLSX_PSKKEM_PLAIN_ANNOUNCE
- if (usingPSK)
- #endif
- {
- byte modes;
- (void)usingPSK;
- /* Pre-shared key modes: mandatory extension for resumption. */
- modes = 1 << PSK_KE;
- #if !defined(NO_DH) || defined(HAVE_ECC) || \
- defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
- if (!ssl->options.noPskDheKe)
- modes |= 1 << PSK_DHE_KE;
- #endif
- ret = TLSX_PskKeModes_Use(ssl, modes);
- if (ret != 0)
- return ret;
- }
- #endif
- #if defined(WOLFSSL_POST_HANDSHAKE_AUTH)
- if (!isServer && ssl->options.postHandshakeAuth) {
- ret = TLSX_PostHandAuth_Use(ssl);
- if (ret != 0)
- return ret;
- }
- #endif
- }
- #endif
- (void)isServer;
- (void)public_key;
- (void)public_key_len;
- (void)ssl;
- return ret;
- }
- #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
- /** Tells the buffered size of extensions to be sent into the client hello. */
- int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word16* pLength)
- {
- int ret = 0;
- word16 length = 0;
- byte semaphore[SEMAPHORE_SIZE] = {0};
- if (!TLSX_SupportExtensions(ssl))
- return 0;
- if (msgType == client_hello) {
- EC_VALIDATE_REQUEST(ssl, semaphore);
- PF_VALIDATE_REQUEST(ssl, semaphore);
- WOLF_STK_VALIDATE_REQUEST(ssl);
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- if (ssl->suites->hashSigAlgoSz == 0)
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
- #endif
- #if defined(WOLFSSL_TLS13)
- if (!IsAtLeastTLSv1_2(ssl))
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
- #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
- if (!IsAtLeastTLSv1_3(ssl->version)) {
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
- #endif
- #ifdef WOLFSSL_EARLY_DATA
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
- #endif
- #ifdef WOLFSSL_SEND_HRR_COOKIE
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
- #endif
- #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
- #endif
- }
- #endif
- #endif
- #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
- || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
- if (!SSL_CM(ssl)->ocspStaplingEnabled) {
- /* mark already sent, so it won't send it */
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
- }
- #endif
- }
- #ifdef WOLFSSL_TLS13
- #ifndef NO_CERTS
- else if (msgType == certificate_request) {
- /* Don't send out any extension except those that are turned off. */
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
- #endif
- /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
- * TLSX_CERTIFICATE_AUTHORITIES, OID_FILTERS
- * TLSX_STATUS_REQUEST
- */
- }
- #endif
- #endif
- if (ssl->extensions) {
- ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length);
- if (ret != 0)
- return ret;
- }
- if (ssl->ctx && ssl->ctx->extensions) {
- ret = TLSX_GetSize(ssl->ctx->extensions, semaphore, msgType, &length);
- if (ret != 0)
- return ret;
- }
- #ifdef HAVE_EXTENDED_MASTER
- if (msgType == client_hello && ssl->options.haveEMS &&
- (!IsAtLeastTLSv1_3(ssl->version) || ssl->options.downgrade)) {
- length += HELLO_EXT_SZ;
- }
- #endif
- if (length)
- length += OPAQUE16_LEN; /* for total length storage. */
- *pLength += length;
- return ret;
- }
- /** Writes the extensions to be sent into the client hello. */
- int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word16* pOffset)
- {
- int ret = 0;
- word16 offset = 0;
- byte semaphore[SEMAPHORE_SIZE] = {0};
- if (!TLSX_SupportExtensions(ssl) || output == NULL)
- return 0;
- offset += OPAQUE16_LEN; /* extensions length */
- if (msgType == client_hello) {
- EC_VALIDATE_REQUEST(ssl, semaphore);
- PF_VALIDATE_REQUEST(ssl, semaphore);
- WOLF_STK_VALIDATE_REQUEST(ssl);
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- if (ssl->suites->hashSigAlgoSz == 0)
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
- #endif
- #ifdef WOLFSSL_TLS13
- if (!IsAtLeastTLSv1_2(ssl))
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
- #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
- if (!IsAtLeastTLSv1_3(ssl->version)) {
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
- #endif
- #ifdef WOLFSSL_EARLY_DATA
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
- #endif
- #ifdef WOLFSSL_SEND_HRR_COOKIE
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
- #endif
- #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
- #endif
- }
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- /* Must write Pre-shared Key extension at the end in TLS v1.3.
- * Must not write out Pre-shared Key extension in earlier versions of
- * protocol.
- */
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
- #endif
- #endif
- #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
- || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
- /* mark already sent, so it won't send it */
- if (!SSL_CM(ssl)->ocspStaplingEnabled) {
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
- }
- #endif
- }
- #ifdef WOLFSSL_TLS13
- #ifndef NO_CERTS
- else if (msgType == certificate_request) {
- /* Don't send out any extension except those that are turned off. */
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
- #endif
- /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
- * TLSX_CERTIFICATE_AUTHORITIES, TLSX_OID_FILTERS
- * TLSX_STATUS_REQUEST
- */
- }
- #endif
- #endif
- if (ssl->extensions) {
- ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
- msgType, &offset);
- if (ret != 0)
- return ret;
- }
- if (ssl->ctx && ssl->ctx->extensions) {
- ret = TLSX_Write(ssl->ctx->extensions, output + offset, semaphore,
- msgType, &offset);
- if (ret != 0)
- return ret;
- }
- #ifdef HAVE_EXTENDED_MASTER
- if (msgType == client_hello && ssl->options.haveEMS &&
- (!IsAtLeastTLSv1_3(ssl->version) || ssl->options.downgrade)) {
- WOLFSSL_MSG("EMS extension to write");
- c16toa(HELLO_EXT_EXTMS, output + offset);
- offset += HELLO_EXT_TYPE_SZ;
- c16toa(0, output + offset);
- offset += HELLO_EXT_SZ_SZ;
- }
- #endif
- #ifdef WOLFSSL_TLS13
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- if (msgType == client_hello && IsAtLeastTLSv1_3(ssl->version)) {
- /* Write out what we can of Pre-shared key extension. */
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
- ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
- client_hello, &offset);
- if (ret != 0)
- return ret;
- }
- #endif
- #endif
- if (offset > OPAQUE16_LEN || msgType != client_hello)
- c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
- *pOffset += offset;
- return ret;
- }
- #endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
- #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_SERVER)
- /** Tells the buffered size of extensions to be sent into the server hello. */
- int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
- {
- int ret = 0;
- word16 length = 0;
- byte semaphore[SEMAPHORE_SIZE] = {0};
- switch (msgType) {
- #ifndef NO_WOLFSSL_SERVER
- case server_hello:
- PF_VALIDATE_RESPONSE(ssl, semaphore);
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version)) {
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- TURN_OFF(semaphore,
- TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
- #ifdef HAVE_SUPPORTED_CURVES
- if (!ssl->options.noPskDheKe)
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
- #endif
- #ifdef WOLFSSL_DTLS_CID
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
- #endif /* WOLFSSL_DTLS_CID */
- }
- #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
- else {
- #ifdef HAVE_SUPPORTED_CURVES
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
- #endif
- }
- #endif
- #endif
- break;
- #ifdef WOLFSSL_TLS13
- case hello_retry_request:
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
- #ifdef HAVE_SUPPORTED_CURVES
- if (!ssl->options.noPskDheKe)
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
- #endif
- #ifdef WOLFSSL_SEND_HRR_COOKIE
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
- #endif
- break;
- #endif
- #ifdef WOLFSSL_TLS13
- case encrypted_extensions:
- /* Send out all extension except those that are turned on. */
- #ifdef HAVE_ECC
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
- #endif
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
- #ifdef HAVE_SESSION_TICKET
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
- #endif
- #ifdef HAVE_SUPPORTED_CURVES
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
- #endif
- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
- #endif
- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
- #endif
- #if defined(HAVE_SERVER_RENEGOTIATION_INFO)
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_RENEGOTIATION_INFO));
- #endif
- #ifdef WOLFSSL_DTLS_CID
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
- #endif /* WOLFSSL_DTLS_CID */
- break;
- #ifdef WOLFSSL_EARLY_DATA
- case session_ticket:
- if (ssl->options.tls1_3) {
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
- }
- break;
- #endif
- #endif
- #endif
- #ifdef WOLFSSL_TLS13
- #ifndef NO_CERTS
- case certificate:
- /* Don't send out any extension except those that are turned off. */
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
- /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
- * TLSX_SERVER_CERTIFICATE_TYPE
- */
- break;
- #endif
- #endif
- }
- #ifdef HAVE_EXTENDED_MASTER
- if (ssl->options.haveEMS && msgType == server_hello &&
- !IsAtLeastTLSv1_3(ssl->version)) {
- length += HELLO_EXT_SZ;
- }
- #endif
- if (TLSX_SupportExtensions(ssl)) {
- ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length);
- if (ret != 0)
- return ret;
- }
- /* All the response data is set at the ssl object only, so no ctx here. */
- if (length || msgType != server_hello)
- length += OPAQUE16_LEN; /* for total length storage. */
- *pLength += length;
- return ret;
- }
- /** Writes the server hello extensions into a buffer. */
- int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset)
- {
- int ret = 0;
- word16 offset = 0;
- if (TLSX_SupportExtensions(ssl) && output) {
- byte semaphore[SEMAPHORE_SIZE] = {0};
- switch (msgType) {
- #ifndef NO_WOLFSSL_SERVER
- case server_hello:
- PF_VALIDATE_RESPONSE(ssl, semaphore);
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version)) {
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- TURN_OFF(semaphore,
- TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
- #ifdef HAVE_SUPPORTED_CURVES
- if (!ssl->options.noPskDheKe)
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
- #endif
- #ifdef WOLFSSL_DTLS_CID
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
- #endif /* WOLFSSL_DTLS_CID */
- }
- #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
- else {
- #ifdef HAVE_SUPPORTED_CURVES
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
- #endif
- }
- #endif
- #endif
- break;
- #ifdef WOLFSSL_TLS13
- case hello_retry_request:
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
- #ifdef HAVE_SUPPORTED_CURVES
- if (!ssl->options.noPskDheKe)
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
- #endif
- /* Cookie is written below as last extension. */
- break;
- #endif
- #ifdef WOLFSSL_TLS13
- case encrypted_extensions:
- /* Send out all extension except those that are turned on. */
- #ifdef HAVE_ECC
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
- #endif
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
- #ifdef HAVE_SESSION_TICKET
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
- #endif
- #ifdef HAVE_SUPPORTED_CURVES
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
- #endif
- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
- #endif
- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
- #endif
- #if defined(HAVE_SERVER_RENEGOTIATION_INFO)
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_RENEGOTIATION_INFO));
- #endif
- #ifdef WOLFSSL_DTLS_CID
- TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
- #endif /* WOLFSSL_DTLS_CID */
- break;
- #ifdef WOLFSSL_EARLY_DATA
- case session_ticket:
- if (ssl->options.tls1_3) {
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
- }
- break;
- #endif
- #endif
- #endif
- #ifdef WOLFSSL_TLS13
- #ifndef NO_CERTS
- case certificate:
- /* Don't send out any extension except those that are turned
- * off. */
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
- /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
- * TLSX_SERVER_CERTIFICATE_TYPE
- */
- break;
- #endif
- #endif
- default:
- break;
- }
- offset += OPAQUE16_LEN; /* extensions length */
- ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
- msgType, &offset);
- if (ret != 0)
- return ret;
- #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
- if (msgType == hello_retry_request) {
- XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
- TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
- ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
- msgType, &offset);
- if (ret != 0)
- return ret;
- }
- #endif
- #ifdef HAVE_EXTENDED_MASTER
- if (ssl->options.haveEMS && msgType == server_hello &&
- !IsAtLeastTLSv1_3(ssl->version)) {
- WOLFSSL_MSG("EMS extension to write");
- c16toa(HELLO_EXT_EXTMS, output + offset);
- offset += HELLO_EXT_TYPE_SZ;
- c16toa(0, output + offset);
- offset += HELLO_EXT_SZ_SZ;
- }
- #endif
- if (offset > OPAQUE16_LEN || msgType != server_hello)
- c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
- }
- if (pOffset)
- *pOffset += offset;
- return ret;
- }
- #endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_SERVER */
- #ifdef WOLFSSL_TLS13
- int TLSX_ParseVersion(WOLFSSL* ssl, const byte* input, word16 length,
- byte msgType, int* found)
- {
- int ret = 0;
- int offset = 0;
- *found = 0;
- while (offset < (int)length) {
- word16 type;
- word16 size;
- if (offset + (2 * OPAQUE16_LEN) > length) {
- ret = BUFFER_ERROR;
- break;
- }
- ato16(input + offset, &type);
- offset += HELLO_EXT_TYPE_SZ;
- ato16(input + offset, &size);
- offset += OPAQUE16_LEN;
- if (offset + size > length) {
- ret = BUFFER_ERROR;
- break;
- }
- if (type == TLSX_SUPPORTED_VERSIONS) {
- *found = 1;
- WOLFSSL_MSG("Supported Versions extension received");
- ret = SV_PARSE(ssl, input + offset, size, msgType);
- break;
- }
- offset += size;
- }
- return ret;
- }
- #endif
- /** Parses a buffer of TLS extensions. */
- int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
- Suites *suites)
- {
- int ret = 0;
- word16 offset = 0;
- byte isRequest = (msgType == client_hello ||
- msgType == certificate_request);
- #ifdef HAVE_EXTENDED_MASTER
- byte pendingEMS = 0;
- #endif
- #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
- int pskDone = 0;
- #endif
- if (!ssl || !input || (isRequest && !suites))
- return BAD_FUNC_ARG;
- while (ret == 0 && offset < length) {
- word16 type;
- word16 size;
- #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
- if (msgType == client_hello && pskDone) {
- WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
- return PSK_KEY_ERROR;
- }
- #endif
- if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN)
- return BUFFER_ERROR;
- ato16(input + offset, &type);
- offset += HELLO_EXT_TYPE_SZ;
- ato16(input + offset, &size);
- offset += OPAQUE16_LEN;
- if (length - offset < size)
- return BUFFER_ERROR;
- switch (type) {
- #ifdef HAVE_SNI
- case TLSX_SERVER_NAME:
- WOLFSSL_MSG("SNI extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version)) {
- if (msgType != client_hello &&
- msgType != encrypted_extensions)
- return EXT_NOT_ALLOWED;
- }
- else
- #endif
- {
- if (msgType != client_hello &&
- msgType != server_hello)
- return EXT_NOT_ALLOWED;
- }
- ret = SNI_PARSE(ssl, input + offset, size, isRequest);
- break;
- #endif
- case TLSX_TRUSTED_CA_KEYS:
- WOLFSSL_MSG("Trusted CA extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version)) {
- if (msgType != client_hello &&
- msgType != encrypted_extensions)
- return EXT_NOT_ALLOWED;
- }
- else
- #endif
- {
- if (msgType != client_hello)
- return EXT_NOT_ALLOWED;
- }
- ret = TCA_PARSE(ssl, input + offset, size, isRequest);
- break;
- case TLSX_MAX_FRAGMENT_LENGTH:
- WOLFSSL_MSG("Max Fragment Length extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version)) {
- if (msgType != client_hello &&
- msgType != encrypted_extensions) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- }
- else
- #endif
- {
- if (msgType != client_hello &&
- msgType != server_hello) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- }
- ret = MFL_PARSE(ssl, input + offset, size, isRequest);
- break;
- case TLSX_TRUNCATED_HMAC:
- WOLFSSL_MSG("Truncated HMAC extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version))
- break;
- #endif
- if (msgType != client_hello)
- return EXT_NOT_ALLOWED;
- ret = THM_PARSE(ssl, input + offset, size, isRequest);
- break;
- case TLSX_SUPPORTED_GROUPS:
- WOLFSSL_MSG("Supported Groups extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version)) {
- if (msgType != client_hello &&
- msgType != encrypted_extensions) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- }
- else
- #endif
- {
- if (msgType != client_hello) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- }
- ret = EC_PARSE(ssl, input + offset, size, isRequest);
- break;
- case TLSX_EC_POINT_FORMATS:
- WOLFSSL_MSG("Point Formats extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version))
- break;
- #endif
- if (msgType != client_hello &&
- msgType != server_hello) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- ret = PF_PARSE(ssl, input + offset, size, isRequest);
- break;
- case TLSX_STATUS_REQUEST:
- WOLFSSL_MSG("Certificate Status Request extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version)) {
- if (msgType != client_hello &&
- msgType != certificate_request &&
- msgType != certificate)
- return EXT_NOT_ALLOWED;
- }
- else
- #endif
- {
- if (msgType != client_hello &&
- msgType != server_hello)
- return EXT_NOT_ALLOWED;
- }
- ret = CSR_PARSE(ssl, input + offset, size, isRequest);
- break;
- case TLSX_STATUS_REQUEST_V2:
- WOLFSSL_MSG("Certificate Status Request v2 extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
- if (IsAtLeastTLSv1_3(ssl->version)) {
- if (msgType != client_hello &&
- msgType != certificate_request &&
- msgType != certificate)
- return EXT_NOT_ALLOWED;
- }
- else
- #endif
- {
- if (msgType != client_hello &&
- msgType != server_hello)
- return EXT_NOT_ALLOWED;
- }
- ret = CSR2_PARSE(ssl, input + offset, size, isRequest);
- break;
- #ifdef HAVE_EXTENDED_MASTER
- case HELLO_EXT_EXTMS:
- WOLFSSL_MSG("Extended Master Secret extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #if defined(WOLFSSL_TLS13)
- if (IsAtLeastTLSv1_3(ssl->version))
- break;
- #endif
- if (msgType != client_hello &&
- msgType != server_hello)
- return EXT_NOT_ALLOWED;
- if (size != 0)
- return BUFFER_ERROR;
- #ifndef NO_WOLFSSL_SERVER
- if (isRequest)
- ssl->options.haveEMS = 1;
- #endif
- pendingEMS = 1;
- break;
- #endif
- case TLSX_RENEGOTIATION_INFO:
- WOLFSSL_MSG("Secure Renegotiation extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version))
- break;
- #endif
- if (msgType != client_hello &&
- msgType != server_hello)
- return EXT_NOT_ALLOWED;
- ret = SCR_PARSE(ssl, input + offset, size, isRequest);
- break;
- case TLSX_SESSION_TICKET:
- WOLFSSL_MSG("Session Ticket extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
- if (IsAtLeastTLSv1_3(ssl->version)) {
- if (msgType != client_hello)
- return EXT_NOT_ALLOWED;
- }
- else
- #endif
- {
- if (msgType != client_hello &&
- msgType != server_hello)
- return EXT_NOT_ALLOWED;
- }
- ret = WOLF_STK_PARSE(ssl, input + offset, size, isRequest);
- break;
- case TLSX_APPLICATION_LAYER_PROTOCOL:
- WOLFSSL_MSG("ALPN extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #if defined(WOLFSSL_TLS13) && defined(HAVE_ALPN)
- if (IsAtLeastTLSv1_3(ssl->version)) {
- if (msgType != client_hello &&
- msgType != encrypted_extensions)
- return EXT_NOT_ALLOWED;
- }
- else
- #endif
- {
- if (msgType != client_hello &&
- msgType != server_hello)
- return EXT_NOT_ALLOWED;
- }
- ret = ALPN_PARSE(ssl, input + offset, size, isRequest);
- break;
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- case TLSX_SIGNATURE_ALGORITHMS:
- WOLFSSL_MSG("Signature Algorithms extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- if (!IsAtLeastTLSv1_2(ssl))
- break;
- #ifdef WOLFSSL_TLS13
- if (IsAtLeastTLSv1_3(ssl->version)) {
- if (msgType != client_hello &&
- msgType != certificate_request)
- return EXT_NOT_ALLOWED;
- }
- else
- #endif
- {
- if (msgType != client_hello)
- return EXT_NOT_ALLOWED;
- }
- ret = SA_PARSE(ssl, input + offset, size, isRequest, suites);
- break;
- #endif
- #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
- case TLSX_ENCRYPT_THEN_MAC:
- WOLFSSL_MSG("Encrypt-Then-Mac extension received");
- /* Ignore for TLS 1.3+ */
- if (IsAtLeastTLSv1_3(ssl->version))
- break;
- if (msgType != client_hello &&
- msgType != server_hello)
- return EXT_NOT_ALLOWED;
- ret = ETM_PARSE(ssl, input + offset, size, msgType);
- break;
- #endif /* HAVE_ENCRYPT_THEN_MAC */
- #ifdef WOLFSSL_TLS13
- case TLSX_SUPPORTED_VERSIONS:
- WOLFSSL_MSG("Skipping Supported Versions - already processed");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- if (msgType != client_hello &&
- msgType != server_hello &&
- msgType != hello_retry_request)
- return EXT_NOT_ALLOWED;
- break;
- #ifdef WOLFSSL_SEND_HRR_COOKIE
- case TLSX_COOKIE:
- WOLFSSL_MSG("Cookie extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- if (!IsAtLeastTLSv1_3(ssl->version))
- break;
- if (msgType != client_hello &&
- msgType != hello_retry_request) {
- return EXT_NOT_ALLOWED;
- }
- ret = CKE_PARSE(ssl, input + offset, size, msgType);
- break;
- #endif
- #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
- case TLSX_PRE_SHARED_KEY:
- WOLFSSL_MSG("Pre-Shared Key extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- if (!IsAtLeastTLSv1_3(ssl->version))
- break;
- if (msgType != client_hello &&
- msgType != server_hello) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- ret = PSK_PARSE(ssl, input + offset, size, msgType);
- pskDone = 1;
- break;
- case TLSX_PSK_KEY_EXCHANGE_MODES:
- WOLFSSL_MSG("PSK Key Exchange Modes extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- if (!IsAtLeastTLSv1_3(ssl->version))
- break;
- if (msgType != client_hello) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- ret = PKM_PARSE(ssl, input + offset, size, msgType);
- break;
- #endif
- #ifdef WOLFSSL_EARLY_DATA
- case TLSX_EARLY_DATA:
- WOLFSSL_MSG("Early Data extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- if (!IsAtLeastTLSv1_3(ssl->version))
- break;
- if (msgType != client_hello && msgType != session_ticket &&
- msgType != encrypted_extensions) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- ret = EDI_PARSE(ssl, input + offset, size, msgType);
- break;
- #endif
- #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
- case TLSX_POST_HANDSHAKE_AUTH:
- WOLFSSL_MSG("Post Handshake Authentication extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- if (!IsAtLeastTLSv1_3(ssl->version))
- break;
- if (msgType != client_hello) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- ret = PHA_PARSE(ssl, input + offset, size, msgType);
- break;
- #endif
- #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
- case TLSX_SIGNATURE_ALGORITHMS_CERT:
- WOLFSSL_MSG("Signature Algorithms extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- if (!IsAtLeastTLSv1_3(ssl->version))
- break;
- if (msgType != client_hello &&
- msgType != certificate_request) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- ret = SAC_PARSE(ssl, input + offset, size, isRequest);
- break;
- #endif
- case TLSX_KEY_SHARE:
- WOLFSSL_MSG("Key Share extension received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- #ifdef HAVE_SUPPORTED_CURVES
- if (!IsAtLeastTLSv1_3(ssl->version))
- break;
- if (msgType != client_hello && msgType != server_hello &&
- msgType != hello_retry_request) {
- WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
- return EXT_NOT_ALLOWED;
- }
- #endif
- ret = KS_PARSE(ssl, input + offset, size, msgType);
- break;
- #endif
- #ifdef WOLFSSL_SRTP
- case TLSX_USE_SRTP:
- WOLFSSL_MSG("Use SRTP extension received");
- ret = SRTP_PARSE(ssl, input + offset, size, isRequest);
- break;
- #endif
- #ifdef WOLFSSL_QUIC
- case TLSX_KEY_QUIC_TP_PARAMS:
- FALL_THROUGH;
- case TLSX_KEY_QUIC_TP_PARAMS_DRAFT:
- WOLFSSL_MSG("QUIC transport parameter received");
- #ifdef WOLFSSL_DEBUG_TLS
- WOLFSSL_BUFFER(input + offset, size);
- #endif
- if (IsAtLeastTLSv1_3(ssl->version) &&
- msgType != client_hello &&
- msgType != server_hello &&
- msgType != encrypted_extensions) {
- return EXT_NOT_ALLOWED;
- }
- else if (!IsAtLeastTLSv1_3(ssl->version) &&
- msgType == encrypted_extensions) {
- return EXT_NOT_ALLOWED;
- }
- else if (WOLFSSL_IS_QUIC(ssl)) {
- ret = QTP_PARSE(ssl, input + offset, size, type, msgType);
- }
- else {
- WOLFSSL_MSG("QUIC transport param TLS extension type, but no QUIC");
- return EXT_NOT_ALLOWED; /* be safe, this should not happen */
- }
- break;
- #endif /* WOLFSSL_QUIC */
- #if defined(WOLFSSL_DTLS_CID)
- case TLSX_CONNECTION_ID:
- /* connection ID not supported in DTLSv1.2 */
- if (!IsAtLeastTLSv1_3(ssl->version))
- break;
- if (msgType != client_hello && msgType != server_hello)
- return EXT_NOT_ALLOWED;
- WOLFSSL_MSG("ConnectionID extension received");
- ret = CID_PARSE(ssl, input + offset, size, isRequest);
- break;
- #endif /* defined(WOLFSSL_DTLS_CID) */
- default:
- WOLFSSL_MSG("Unknown TLS extension type");
- }
- /* offset should be updated here! */
- offset += size;
- }
- #ifdef HAVE_EXTENDED_MASTER
- if (IsAtLeastTLSv1_3(ssl->version) && msgType == hello_retry_request) {
- /* Don't change EMS status until server_hello received.
- * Second ClientHello must have same extensions.
- */
- }
- else if (!isRequest && ssl->options.haveEMS && !pendingEMS)
- ssl->options.haveEMS = 0;
- #endif
- if (ret == 0)
- ret = SNI_VERIFY_PARSE(ssl, isRequest);
- if (ret == 0)
- ret = TCA_VERIFY_PARSE(ssl, isRequest);
- return ret;
- }
- /* undefining semaphore macros */
- #undef IS_OFF
- #undef TURN_ON
- #undef SEMAPHORE_SIZE
- #endif /* HAVE_TLS_EXTENSIONS */
- #ifndef NO_WOLFSSL_CLIENT
- WOLFSSL_METHOD* wolfTLS_client_method(void)
- {
- return wolfTLS_client_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLS_client_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("TLS_client_method_ex");
- if (method) {
- #if defined(WOLFSSL_TLS13)
- InitSSL_Method(method, MakeTLSv1_3());
- #elif !defined(WOLFSSL_NO_TLS12)
- InitSSL_Method(method, MakeTLSv1_2());
- #elif !defined(NO_OLD_TLS)
- InitSSL_Method(method, MakeTLSv1_1());
- #elif defined(WOLFSSL_ALLOW_TLSV10)
- InitSSL_Method(method, MakeTLSv1());
- #else
- #error No TLS version enabled!
- #endif
- method->downgrade = 1;
- method->side = WOLFSSL_CLIENT_END;
- }
- return method;
- }
- #ifndef NO_OLD_TLS
- #ifdef WOLFSSL_ALLOW_TLSV10
- WOLFSSL_METHOD* wolfTLSv1_client_method(void)
- {
- return wolfTLSv1_client_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLSv1_client_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("TLSv1_client_method_ex");
- if (method)
- InitSSL_Method(method, MakeTLSv1());
- return method;
- }
- #endif /* WOLFSSL_ALLOW_TLSV10 */
- WOLFSSL_METHOD* wolfTLSv1_1_client_method(void)
- {
- return wolfTLSv1_1_client_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLSv1_1_client_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("TLSv1_1_client_method_ex");
- if (method)
- InitSSL_Method(method, MakeTLSv1_1());
- return method;
- }
- #endif /* !NO_OLD_TLS */
- #ifndef WOLFSSL_NO_TLS12
- WOLFSSL_ABI
- WOLFSSL_METHOD* wolfTLSv1_2_client_method(void)
- {
- return wolfTLSv1_2_client_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLSv1_2_client_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("TLSv1_2_client_method_ex");
- if (method)
- InitSSL_Method(method, MakeTLSv1_2());
- return method;
- }
- #endif /* WOLFSSL_NO_TLS12 */
- #ifdef WOLFSSL_TLS13
- /* The TLS v1.3 client method data.
- *
- * returns the method data for a TLS v1.3 client.
- */
- WOLFSSL_ABI
- WOLFSSL_METHOD* wolfTLSv1_3_client_method(void)
- {
- return wolfTLSv1_3_client_method_ex(NULL);
- }
- /* The TLS v1.3 client method data.
- *
- * heap The heap used for allocation.
- * returns the method data for a TLS v1.3 client.
- */
- WOLFSSL_METHOD* wolfTLSv1_3_client_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method = (WOLFSSL_METHOD*)
- XMALLOC(sizeof(WOLFSSL_METHOD), heap,
- DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("TLSv1_3_client_method_ex");
- if (method)
- InitSSL_Method(method, MakeTLSv1_3());
- return method;
- }
- #endif /* WOLFSSL_TLS13 */
- #ifdef WOLFSSL_DTLS
- WOLFSSL_METHOD* wolfDTLS_client_method(void)
- {
- return wolfDTLS_client_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfDTLS_client_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("DTLS_client_method_ex");
- if (method) {
- #if defined(WOLFSSL_DTLS13)
- InitSSL_Method(method, MakeDTLSv1_3());
- #elif !defined(WOLFSSL_NO_TLS12)
- InitSSL_Method(method, MakeDTLSv1_2());
- #elif !defined(NO_OLD_TLS)
- InitSSL_Method(method, MakeDTLSv1());
- #else
- #error No DTLS version enabled!
- #endif
- method->downgrade = 1;
- method->side = WOLFSSL_CLIENT_END;
- }
- return method;
- }
- #ifndef NO_OLD_TLS
- WOLFSSL_METHOD* wolfDTLSv1_client_method(void)
- {
- return wolfDTLSv1_client_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfDTLSv1_client_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("DTLSv1_client_method_ex");
- if (method)
- InitSSL_Method(method, MakeDTLSv1());
- return method;
- }
- #endif /* NO_OLD_TLS */
- #ifndef WOLFSSL_NO_TLS12
- WOLFSSL_METHOD* wolfDTLSv1_2_client_method(void)
- {
- return wolfDTLSv1_2_client_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfDTLSv1_2_client_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("DTLSv1_2_client_method_ex");
- if (method)
- InitSSL_Method(method, MakeDTLSv1_2());
- (void)heap;
- return method;
- }
- #endif /* !WOLFSSL_NO_TLS12 */
- #endif /* WOLFSSL_DTLS */
- #endif /* NO_WOLFSSL_CLIENT */
- /* EITHER SIDE METHODS */
- #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
- #ifndef NO_OLD_TLS
- #ifdef WOLFSSL_ALLOW_TLSV10
- /* Gets a WOLFSSL_METHOD type that is not set as client or server
- *
- * Returns a pointer to a WOLFSSL_METHOD struct
- */
- WOLFSSL_METHOD* wolfTLSv1_method(void)
- {
- return wolfTLSv1_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLSv1_method_ex(void* heap)
- {
- WOLFSSL_METHOD* m;
- WOLFSSL_ENTER("TLSv1_method");
- #ifndef NO_WOLFSSL_CLIENT
- m = wolfTLSv1_client_method_ex(heap);
- #else
- m = wolfTLSv1_server_method_ex(heap);
- #endif
- if (m != NULL) {
- m->side = WOLFSSL_NEITHER_END;
- }
- return m;
- }
- #endif /* WOLFSSL_ALLOW_TLSV10 */
- /* Gets a WOLFSSL_METHOD type that is not set as client or server
- *
- * Returns a pointer to a WOLFSSL_METHOD struct
- */
- WOLFSSL_METHOD* wolfTLSv1_1_method(void)
- {
- return wolfTLSv1_1_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLSv1_1_method_ex(void* heap)
- {
- WOLFSSL_METHOD* m;
- WOLFSSL_ENTER("TLSv1_1_method");
- #ifndef NO_WOLFSSL_CLIENT
- m = wolfTLSv1_1_client_method_ex(heap);
- #else
- m = wolfTLSv1_1_server_method_ex(heap);
- #endif
- if (m != NULL) {
- m->side = WOLFSSL_NEITHER_END;
- }
- return m;
- }
- #endif /* !NO_OLD_TLS */
- #ifndef WOLFSSL_NO_TLS12
- /* Gets a WOLFSSL_METHOD type that is not set as client or server
- *
- * Returns a pointer to a WOLFSSL_METHOD struct
- */
- WOLFSSL_METHOD* wolfTLSv1_2_method(void)
- {
- return wolfTLSv1_2_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLSv1_2_method_ex(void* heap)
- {
- WOLFSSL_METHOD* m;
- WOLFSSL_ENTER("TLSv1_2_method");
- #ifndef NO_WOLFSSL_CLIENT
- m = wolfTLSv1_2_client_method_ex(heap);
- #else
- m = wolfTLSv1_2_server_method_ex(heap);
- #endif
- if (m != NULL) {
- m->side = WOLFSSL_NEITHER_END;
- }
- return m;
- }
- #endif /* !WOLFSSL_NO_TLS12 */
- #ifdef WOLFSSL_TLS13
- /* Gets a WOLFSSL_METHOD type that is not set as client or server
- *
- * Returns a pointer to a WOLFSSL_METHOD struct
- */
- WOLFSSL_METHOD* wolfTLSv1_3_method(void)
- {
- return wolfTLSv1_3_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLSv1_3_method_ex(void* heap)
- {
- WOLFSSL_METHOD* m;
- WOLFSSL_ENTER("TLSv1_3_method");
- #ifndef NO_WOLFSSL_CLIENT
- m = wolfTLSv1_3_client_method_ex(heap);
- #else
- m = wolfTLSv1_3_server_method_ex(heap);
- #endif
- if (m != NULL) {
- m->side = WOLFSSL_NEITHER_END;
- }
- return m;
- }
- #endif /* WOLFSSL_TLS13 */
- #ifdef WOLFSSL_DTLS
- WOLFSSL_METHOD* wolfDTLS_method(void)
- {
- return wolfDTLS_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfDTLS_method_ex(void* heap)
- {
- WOLFSSL_METHOD* m;
- WOLFSSL_ENTER("DTLS_method_ex");
- #ifndef NO_WOLFSSL_CLIENT
- m = wolfDTLS_client_method_ex(heap);
- #else
- m = wolfDTLS_server_method_ex(heap);
- #endif
- if (m != NULL) {
- m->side = WOLFSSL_NEITHER_END;
- }
- return m;
- }
- #ifndef NO_OLD_TLS
- WOLFSSL_METHOD* wolfDTLSv1_method(void)
- {
- return wolfDTLSv1_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfDTLSv1_method_ex(void* heap)
- {
- WOLFSSL_METHOD* m;
- WOLFSSL_ENTER("DTLSv1_method_ex");
- #ifndef NO_WOLFSSL_CLIENT
- m = wolfDTLSv1_client_method_ex(heap);
- #else
- m = wolfDTLSv1_server_method_ex(heap);
- #endif
- if (m != NULL) {
- m->side = WOLFSSL_NEITHER_END;
- }
- return m;
- }
- #endif /* !NO_OLD_TLS */
- #ifndef WOLFSSL_NO_TLS12
- WOLFSSL_METHOD* wolfDTLSv1_2_method(void)
- {
- return wolfDTLSv1_2_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfDTLSv1_2_method_ex(void* heap)
- {
- WOLFSSL_METHOD* m;
- WOLFSSL_ENTER("DTLSv1_2_method");
- #ifndef NO_WOLFSSL_CLIENT
- m = wolfDTLSv1_2_client_method_ex(heap);
- #else
- m = wolfDTLSv1_2_server_method_ex(heap);
- #endif
- if (m != NULL) {
- m->side = WOLFSSL_NEITHER_END;
- }
- return m;
- }
- #endif /* !WOLFSSL_NO_TLS12 */
- #endif /* WOLFSSL_DTLS */
- #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
- #ifndef NO_WOLFSSL_SERVER
- WOLFSSL_METHOD* wolfTLS_server_method(void)
- {
- return wolfTLS_server_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLS_server_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("TLS_server_method_ex");
- if (method) {
- #if defined(WOLFSSL_TLS13)
- InitSSL_Method(method, MakeTLSv1_3());
- #elif !defined(WOLFSSL_NO_TLS12)
- InitSSL_Method(method, MakeTLSv1_2());
- #elif !defined(NO_OLD_TLS)
- InitSSL_Method(method, MakeTLSv1_1());
- #elif defined(WOLFSSL_ALLOW_TLSV10)
- InitSSL_Method(method, MakeTLSv1());
- #else
- #error No TLS version enabled!
- #endif
- method->downgrade = 1;
- method->side = WOLFSSL_SERVER_END;
- }
- return method;
- }
- #ifndef NO_OLD_TLS
- #ifdef WOLFSSL_ALLOW_TLSV10
- WOLFSSL_METHOD* wolfTLSv1_server_method(void)
- {
- return wolfTLSv1_server_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLSv1_server_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("TLSv1_server_method_ex");
- if (method) {
- InitSSL_Method(method, MakeTLSv1());
- method->side = WOLFSSL_SERVER_END;
- }
- return method;
- }
- #endif /* WOLFSSL_ALLOW_TLSV10 */
- WOLFSSL_METHOD* wolfTLSv1_1_server_method(void)
- {
- return wolfTLSv1_1_server_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLSv1_1_server_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("TLSv1_1_server_method_ex");
- if (method) {
- InitSSL_Method(method, MakeTLSv1_1());
- method->side = WOLFSSL_SERVER_END;
- }
- return method;
- }
- #endif /* !NO_OLD_TLS */
- #ifndef WOLFSSL_NO_TLS12
- WOLFSSL_ABI
- WOLFSSL_METHOD* wolfTLSv1_2_server_method(void)
- {
- return wolfTLSv1_2_server_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfTLSv1_2_server_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("TLSv1_2_server_method_ex");
- if (method) {
- InitSSL_Method(method, MakeTLSv1_2());
- method->side = WOLFSSL_SERVER_END;
- }
- return method;
- }
- #endif /* !WOLFSSL_NO_TLS12 */
- #ifdef WOLFSSL_TLS13
- /* The TLS v1.3 server method data.
- *
- * returns the method data for a TLS v1.3 server.
- */
- WOLFSSL_ABI
- WOLFSSL_METHOD* wolfTLSv1_3_server_method(void)
- {
- return wolfTLSv1_3_server_method_ex(NULL);
- }
- /* The TLS v1.3 server method data.
- *
- * heap The heap used for allocation.
- * returns the method data for a TLS v1.3 server.
- */
- WOLFSSL_METHOD* wolfTLSv1_3_server_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("TLSv1_3_server_method_ex");
- if (method) {
- InitSSL_Method(method, MakeTLSv1_3());
- method->side = WOLFSSL_SERVER_END;
- }
- return method;
- }
- #endif /* WOLFSSL_TLS13 */
- #ifdef WOLFSSL_DTLS
- WOLFSSL_METHOD* wolfDTLS_server_method(void)
- {
- return wolfDTLS_server_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfDTLS_server_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("DTLS_server_method_ex");
- if (method) {
- #if defined(WOLFSSL_DTLS13)
- InitSSL_Method(method, MakeDTLSv1_3());
- #elif !defined(WOLFSSL_NO_TLS12)
- InitSSL_Method(method, MakeDTLSv1_2());
- #elif !defined(NO_OLD_TLS)
- InitSSL_Method(method, MakeDTLSv1());
- #else
- #error No DTLS version enabled!
- #endif
- method->downgrade = 1;
- method->side = WOLFSSL_SERVER_END;
- }
- return method;
- }
- #ifndef NO_OLD_TLS
- WOLFSSL_METHOD* wolfDTLSv1_server_method(void)
- {
- return wolfDTLSv1_server_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfDTLSv1_server_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- (void)heap;
- WOLFSSL_ENTER("DTLSv1_server_method_ex");
- if (method) {
- InitSSL_Method(method, MakeDTLSv1());
- method->side = WOLFSSL_SERVER_END;
- }
- return method;
- }
- #endif /* !NO_OLD_TLS */
- #ifndef WOLFSSL_NO_TLS12
- WOLFSSL_METHOD* wolfDTLSv1_2_server_method(void)
- {
- return wolfDTLSv1_2_server_method_ex(NULL);
- }
- WOLFSSL_METHOD* wolfDTLSv1_2_server_method_ex(void* heap)
- {
- WOLFSSL_METHOD* method =
- (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
- heap, DYNAMIC_TYPE_METHOD);
- WOLFSSL_ENTER("DTLSv1_2_server_method_ex");
- (void)heap;
- if (method) {
- InitSSL_Method(method, MakeDTLSv1_2());
- method->side = WOLFSSL_SERVER_END;
- }
- (void)heap;
- return method;
- }
- #endif /* !WOLFSSL_NO_TLS12 */
- #endif /* WOLFSSL_DTLS */
- #endif /* NO_WOLFSSL_SERVER */
- #endif /* NO_TLS */
- #endif /* WOLFCRYPT_ONLY */
|