mongoose.c 1.1 MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346
  1. // Copyright (c) 2004-2013 Sergey Lyubka
  2. // Copyright (c) 2013-2025 Cesanta Software Limited
  3. // All rights reserved
  4. //
  5. // This software is dual-licensed: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License version 2 as
  7. // published by the Free Software Foundation. For the terms of this
  8. // license, see http://www.gnu.org/licenses/
  9. //
  10. // You are free to use this software under the terms of the GNU General
  11. // Public License, but WITHOUT ANY WARRANTY; without even the implied
  12. // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. // See the GNU General Public License for more details.
  14. //
  15. // Alternatively, you can license this software under a commercial
  16. // license, as set out in https://www.mongoose.ws/licensing/
  17. //
  18. // SPDX-License-Identifier: GPL-2.0-only or commercial
  19. #include "mongoose.h"
  20. #ifdef MG_ENABLE_LINES
  21. #line 1 "src/base64.c"
  22. #endif
  23. static int mg_base64_encode_single(int c) {
  24. if (c < 26) {
  25. return c + 'A';
  26. } else if (c < 52) {
  27. return c - 26 + 'a';
  28. } else if (c < 62) {
  29. return c - 52 + '0';
  30. } else {
  31. return c == 62 ? '+' : '/';
  32. }
  33. }
  34. static int base64_decode_single(int c, char plus, char slash) {
  35. if (c >= 'A' && c <= 'Z') {
  36. return c - 'A';
  37. } else if (c >= 'a' && c <= 'z') {
  38. return c + 26 - 'a';
  39. } else if (c >= '0' && c <= '9') {
  40. return c + 52 - '0';
  41. } else if (c == plus) {
  42. return 62;
  43. } else if (c == slash) {
  44. return 63;
  45. } else if (c == '=') {
  46. return 64;
  47. } else {
  48. return -1;
  49. }
  50. }
  51. static int mg_base64_decode_single(int c) {
  52. return base64_decode_single(c, '+', '/');
  53. }
  54. static int mg_base64url_decode_single(int c) {
  55. return base64_decode_single(c, '-', '_');
  56. }
  57. size_t mg_base64_update(unsigned char ch, char *to, size_t n) {
  58. unsigned long rem = (n & 3) % 3;
  59. if (rem == 0) {
  60. to[n] = (char) mg_base64_encode_single(ch >> 2);
  61. to[++n] = (char) ((ch & 3) << 4);
  62. } else if (rem == 1) {
  63. to[n] = (char) mg_base64_encode_single(to[n] | (ch >> 4));
  64. to[++n] = (char) ((ch & 15) << 2);
  65. } else {
  66. to[n] = (char) mg_base64_encode_single(to[n] | (ch >> 6));
  67. to[++n] = (char) mg_base64_encode_single(ch & 63);
  68. n++;
  69. }
  70. return n;
  71. }
  72. size_t mg_base64_final(char *to, size_t n) {
  73. size_t saved = n;
  74. // printf("---[%.*s]\n", n, to);
  75. if (n & 3) n = mg_base64_update(0, to, n);
  76. if ((saved & 3) == 2) n--;
  77. // printf(" %d[%.*s]\n", n, n, to);
  78. while (n & 3) to[n++] = '=';
  79. to[n] = '\0';
  80. return n;
  81. }
  82. size_t mg_base64_encode(const unsigned char *p, size_t n, char *to, size_t dl) {
  83. size_t i, len = 0;
  84. if (dl > 0) to[0] = '\0';
  85. if (dl < ((n / 3) + (n % 3 ? 1 : 0)) * 4 + 1) return 0;
  86. for (i = 0; i < n; i++) len = mg_base64_update(p[i], to, len);
  87. len = mg_base64_final(to, len);
  88. return len;
  89. }
  90. size_t mg_base64_decode(const char *src, size_t n, char *dst, size_t dl) {
  91. const char *end = src == NULL ? NULL : src + n; // Cannot add to NULL
  92. size_t len = 0;
  93. if (dl < n / 4 * 3 + 1) goto fail;
  94. while (src != NULL && src + 3 < end) {
  95. int a = mg_base64_decode_single(src[0]),
  96. b = mg_base64_decode_single(src[1]),
  97. c = mg_base64_decode_single(src[2]),
  98. d = mg_base64_decode_single(src[3]);
  99. if (a == 64 || a < 0 || b == 64 || b < 0 || c < 0 || d < 0) {
  100. goto fail;
  101. }
  102. dst[len++] = (char) ((a << 2) | (b >> 4));
  103. if (src[2] != '=') {
  104. dst[len++] = (char) ((b << 4) | (c >> 2));
  105. if (src[3] != '=') dst[len++] = (char) ((c << 6) | d);
  106. }
  107. src += 4;
  108. }
  109. dst[len] = '\0';
  110. return len;
  111. fail:
  112. if (dl > 0) dst[0] = '\0';
  113. return 0;
  114. }
  115. size_t mg_base64url_encode(const unsigned char *p, size_t n, char *to,
  116. size_t dl) {
  117. size_t i, len = mg_base64_encode(p, n, to, dl);
  118. if (len == 0) return 0;
  119. for (i = 0; i < len; i++) {
  120. if (to[i] == '+') {
  121. to[i] = '-';
  122. } else if (to[i] == '/') {
  123. to[i] = '_';
  124. }
  125. }
  126. while (len > 0 && to[len - 1] == '=') to[--len] = '\0';
  127. return len;
  128. }
  129. size_t mg_base64url_decode(const char *src, size_t n, char *dst, size_t dl) {
  130. size_t i, len = 0;
  131. unsigned int bits = 0, v = 0;
  132. if (dl == 0 || (n & 3) == 1) goto fail;
  133. for (i = 0; src != NULL && i < n; i++) {
  134. int c = mg_base64url_decode_single(src[i]);
  135. if (c == 64) break;
  136. if (c < 0) goto fail;
  137. v = (v << 6) | (unsigned int) c;
  138. bits += 6;
  139. if (bits >= 8) {
  140. bits -= 8;
  141. if (len + 1 >= dl) goto fail;
  142. dst[len++] = (char) ((v >> bits) & 255U);
  143. }
  144. }
  145. dst[len] = '\0';
  146. return len;
  147. fail:
  148. if (dl > 0) dst[0] = '\0';
  149. return 0;
  150. }
  151. #ifdef MG_ENABLE_LINES
  152. #line 1 "src/bsd.c"
  153. #endif
  154. #if MG_ENABLE_BSD_SOCKETS
  155. // Queue-based BSD shim is currently TCP/SOCK_STREAM only. UDP/SOCK_DGRAM would
  156. // need datagram boundaries, e.g. datagram queues or SOD/EOD framing.
  157. // Unconnected UDP also needs per-packet peer addresses for sendto()/recvfrom().
  158. // It is also IPv4-only: transports store sockaddr_in and build IPv4 URLs.
  159. #ifndef MG_ENABLE_BSD_LOG
  160. #define MG_ENABLE_BSD_LOG 0
  161. #define bsd_log(type, tag, a, b, c, n)
  162. #else
  163. #define MG_BSD_LOG_SOCK 1
  164. #define MG_BSD_LOG_ACCEPT 2
  165. #define MG_BSD_LOG_CLOSE 3
  166. #define MG_BSD_LOG_TRANSPORT 4
  167. #define MG_BSD_LOG_RESULT 5
  168. #define MG_BSD_LOG_CONNECT 6
  169. // Type is always a constant, so optimised builds fold the switch to one log.
  170. #define bsd_log(type, tag, a, b, c, n) \
  171. do { \
  172. switch (type) { \
  173. case MG_BSD_LOG_SOCK: { \
  174. struct mg_bsd_sock *log_s = (struct mg_bsd_sock *) (a); \
  175. MG_DEBUG(("SOCK %s %ld %p", tag, (long) (n), log_s->t)); \
  176. break; \
  177. } \
  178. case MG_BSD_LOG_ACCEPT: { \
  179. struct mg_connection *log_mc = (struct mg_connection *) (a); \
  180. if ((n) >= 0) { \
  181. MG_DEBUG(("ACCEPT %lu %p %u %ld", log_mc->id, c, \
  182. (unsigned) mg_ntohs(log_mc->rem.port), (long) (n))); \
  183. } else { \
  184. MG_DEBUG(("ACCEPT %lu %p %u", log_mc->id, c, \
  185. (unsigned) mg_ntohs(log_mc->rem.port))); \
  186. } \
  187. break; \
  188. } \
  189. case MG_BSD_LOG_CLOSE: { \
  190. struct mg_connection *log_mc = (struct mg_connection *) (a); \
  191. if ((n) >= 0) MG_INFO(("CLOSE %s %lu %p %ld", tag, log_mc->id, b, \
  192. (long) (n))); \
  193. else MG_DEBUG(("CLOSE %s %lu %p", tag, log_mc->id, b)); \
  194. break; \
  195. } \
  196. case MG_BSD_LOG_TRANSPORT: \
  197. if ((n) >= 0) MG_INFO(("TRANSP %s %p %ld", tag, a, (long) (n))); \
  198. else MG_DEBUG(("TRANSP %s %p", tag, a)); \
  199. break; \
  200. case MG_BSD_LOG_RESULT: \
  201. MG_DEBUG(("RESULT %s %p %ld", tag, a, (long) (n))); \
  202. break; \
  203. case MG_BSD_LOG_CONNECT: \
  204. if ((c) != NULL) { \
  205. MG_DEBUG(("CONNECT %s %p %p %s %ld", tag, a, b, \
  206. (const char *) (c), (long) (n))); \
  207. } else { \
  208. MG_DEBUG(("CONNECT %s %p %p %ld", tag, a, b, (long) (n))); \
  209. } \
  210. break; \
  211. } \
  212. } while (0)
  213. #endif
  214. struct mg_bsd_sock {
  215. void *t; // opaque transport handle
  216. int fd;
  217. int domain, type, proto;
  218. bool nonblock;
  219. struct sockaddr_in addr; // bind address
  220. struct sockaddr_in peer; // peer address (after accept/connect)
  221. struct mg_bsd_sock *next;
  222. };
  223. #define MG_BSD_FD_BASE 17777
  224. // static struct mg_mgr *s_mgr;
  225. static struct mg_bsd_sock *s_socks;
  226. static struct mg_bsd_sock *get(int fd) {
  227. if (fd < MG_BSD_FD_BASE) return NULL;
  228. for (struct mg_bsd_sock *s = s_socks; s; s = s->next)
  229. if (s->fd == fd) return s;
  230. return NULL;
  231. }
  232. static int alloc_sock(struct mg_bsd_sock *s) {
  233. for (int fd = MG_BSD_FD_BASE; ; fd++) {
  234. if (get(fd) == NULL) { s->fd = fd; break; }
  235. }
  236. s->next = s_socks;
  237. s_socks = s;
  238. return s->fd;
  239. }
  240. static void release_sock(int fd) {
  241. struct mg_bsd_sock **p = &s_socks;
  242. while (*p && (*p)->fd != fd) p = &(*p)->next;
  243. if (*p) *p = (*p)->next;
  244. }
  245. int socket(int domain, int type, int proto) {
  246. struct mg_bsd_sock *s = (struct mg_bsd_sock *) calloc(1, sizeof(*s));
  247. if (!s) { errno = ENOMEM; return -1; }
  248. s->t = mg_bsd_transport_new(domain, type, proto);
  249. if (!s->t) { free(s); return -1; }
  250. if (alloc_sock(s) < 0) { mg_bsd_transport_free(s->t); free(s); errno = ENOMEM; return -1; }
  251. s->domain = domain; s->type = type; s->proto = proto;
  252. return s->fd;
  253. }
  254. int bind(int fd, const struct sockaddr *addr, socklen_t len) {
  255. struct mg_bsd_sock *s = get(fd);
  256. if (!s) return -1;
  257. memcpy(&s->addr, addr, len < sizeof(s->addr) ? len : sizeof(s->addr));
  258. return 0;
  259. }
  260. int listen(int fd, int backlog) {
  261. struct mg_bsd_sock *s = get(fd);
  262. if (!s) return -1;
  263. (void) backlog;
  264. return mg_bsd_transport_listen(s->t, &s->addr);
  265. }
  266. int accept(int fd, struct sockaddr *addr, socklen_t *addrlen) {
  267. struct mg_bsd_sock *ls = get(fd);
  268. if (!ls) return -1;
  269. struct sockaddr_in peer;
  270. memset(&peer, 0, sizeof(peer));
  271. void *t = mg_bsd_transport_accept(ls->t, &peer, ls->nonblock);
  272. if (!t) return -1; // errno was set by transport_accept()
  273. struct mg_bsd_sock *ns = (struct mg_bsd_sock *) calloc(1, sizeof(*ns));
  274. if (!ns || alloc_sock(ns) < 0) { mg_bsd_transport_close(t); free(ns); errno = ENOMEM; return -1; }
  275. ns->t = t; ns->domain = ls->domain; ns->type = ls->type; ns->peer = peer;
  276. if (addr && addrlen) {
  277. size_t sz = sizeof(peer) < *addrlen ? sizeof(peer) : *addrlen;
  278. memcpy(addr, &peer, sz);
  279. *addrlen = (socklen_t) sizeof(peer);
  280. }
  281. return ns->fd;
  282. }
  283. int connect(int fd, const struct sockaddr *addr, socklen_t len) {
  284. struct mg_bsd_sock *s = get(fd);
  285. if (!s) return -1;
  286. (void) len;
  287. return mg_bsd_transport_connect(s->t, (const struct sockaddr_in *) addr, s->nonblock);
  288. }
  289. ssize_t send(int fd, const void *buf, size_t len, int flags) {
  290. struct mg_bsd_sock *s = get(fd);
  291. if (!s) return -1;
  292. return mg_bsd_transport_send(s->t, buf, len, s->nonblock || (flags & MSG_DONTWAIT));
  293. }
  294. ssize_t recv(int fd, void *buf, size_t len, int flags) {
  295. struct mg_bsd_sock *s = get(fd);
  296. if (!s) return -1;
  297. return mg_bsd_transport_recv(s->t, buf, len, s->nonblock || (flags & MSG_DONTWAIT));
  298. }
  299. ssize_t sendto(int fd, const void *buf, size_t len, int flags,
  300. const struct sockaddr *dest, socklen_t addrlen) {
  301. (void) fd; (void) buf; (void) len; (void) flags; (void) dest; (void) addrlen;
  302. errno = EPROTONOSUPPORT;
  303. return -1;
  304. }
  305. ssize_t recvfrom(int fd, void *buf, size_t len, int flags,
  306. struct sockaddr *src, socklen_t *addrlen) {
  307. (void) fd; (void) buf; (void) len; (void) flags; (void) src; (void) addrlen;
  308. errno = EPROTONOSUPPORT;
  309. return -1;
  310. }
  311. ssize_t write(int fd, const void *buf, size_t len) { return send(fd, buf, len, 0); }
  312. ssize_t read(int fd, void *buf, size_t len) { return recv(fd, buf, len, 0); }
  313. int close(int fd) {
  314. struct mg_bsd_sock *s = get(fd);
  315. if (!s) return -1;
  316. bsd_log(MG_BSD_LOG_SOCK, "CLOSE", s, NULL, NULL, (long) fd);
  317. mg_bsd_transport_close(s->t);
  318. bsd_log(MG_BSD_LOG_SOCK, "FREE", s, NULL, NULL, (long) fd);
  319. release_sock(fd);
  320. free(s);
  321. return 0;
  322. }
  323. int shutdown(int fd, int how) { (void) how; return close(fd); }
  324. int fcntl(int fd, int cmd, int arg) {
  325. struct mg_bsd_sock *s = get(fd);
  326. if (!s) return -1;
  327. if (cmd == F_GETFL) return s->nonblock ? O_NONBLOCK : 0;
  328. if (cmd == F_SETFL) { s->nonblock = (arg & O_NONBLOCK) != 0; return 0; }
  329. return -1;
  330. }
  331. int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen) {
  332. (void) fd; (void) level; (void) optname; (void) optval; (void) optlen;
  333. return 0;
  334. }
  335. int getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen) {
  336. (void) fd; (void) level; (void) optname;
  337. if (optval && optlen && *optlen >= sizeof(int)) { *(int *) optval = 0; *optlen = sizeof(int); }
  338. return 0;
  339. }
  340. int getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen) {
  341. struct mg_bsd_sock *s = get(fd);
  342. if (!s) return -1;
  343. size_t sz = sizeof(s->addr) < *addrlen ? sizeof(s->addr) : *addrlen;
  344. memcpy(addr, &s->addr, sz);
  345. *addrlen = (socklen_t) sz;
  346. return 0;
  347. }
  348. int getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen) {
  349. struct mg_bsd_sock *s = get(fd);
  350. if (!s) { errno = ENOTCONN; return -1; }
  351. size_t sz = sizeof(s->peer) < *addrlen ? sizeof(s->peer) : *addrlen;
  352. memcpy(addr, &s->peer, sz);
  353. *addrlen = (socklen_t) sz;
  354. return 0;
  355. }
  356. // select/poll: not implemented for queue-based backend
  357. int select(int nfds, fd_set *r, fd_set *w, fd_set *e, struct timeval *tv) {
  358. (void) nfds; (void) r; (void) w; (void) e; (void) tv;
  359. return 0;
  360. }
  361. int poll(struct pollfd *fds, unsigned int nfds, int timeout) {
  362. (void) fds; (void) nfds; (void) timeout;
  363. return 0;
  364. }
  365. // DNS stubs (overridden in the FreeRTOS backend below)
  366. #if !MG_ENABLE_FREERTOS
  367. struct hostent *gethostbyname(const char *name) { (void) name; return NULL; }
  368. int getaddrinfo(const char *node, const char *service,
  369. const struct addrinfo *hints, struct addrinfo **res) {
  370. (void) node; (void) service; (void) hints; (void) res;
  371. return -1;
  372. }
  373. void freeaddrinfo(struct addrinfo *res) { (void) res; }
  374. #endif
  375. int inet_pton(int af, const char *src, void *dst) {
  376. struct mg_addr a;
  377. memset(&a, 0, sizeof(a));
  378. if (af == AF_INET && mg_aton(mg_str_s(src), &a)) { memcpy(dst, &a.addr.ip4, 4); return 1; }
  379. return 0;
  380. }
  381. const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) {
  382. if (af == AF_INET && size >= 16) {
  383. const uint8_t *ip = (const uint8_t *) src;
  384. snprintf(dst, size, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
  385. return dst;
  386. }
  387. return NULL;
  388. }
  389. in_addr_t inet_addr(const char *cp) {
  390. struct mg_addr a;
  391. memset(&a, 0, sizeof(a));
  392. return mg_aton(mg_str_s(cp), &a) ? a.addr.ip4 : (in_addr_t) -1;
  393. }
  394. static char s_ntoa_buf[16];
  395. char *inet_ntoa(struct in_addr in) {
  396. const uint8_t *ip = (const uint8_t *) &in.s_addr;
  397. snprintf(s_ntoa_buf, sizeof(s_ntoa_buf), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
  398. return s_ntoa_buf;
  399. }
  400. #ifdef MG_ENABLE_BSD_PROTOTYPES
  401. uint16_t htons(uint16_t n) { return mg_htons(n); }
  402. uint16_t ntohs(uint16_t n) { return mg_htons(n); }
  403. uint32_t htonl(uint32_t n) { return mg_htonl(n); }
  404. uint32_t ntohl(uint32_t n) { return mg_htonl(n); }
  405. #endif
  406. // ============================================================
  407. // FreeRTOS + Mongoose transport backend
  408. // ============================================================
  409. #if MG_ENABLE_FREERTOS
  410. #include <queue.h>
  411. #ifndef MG_BSD_CHUNK_SIZE
  412. #define MG_BSD_CHUNK_SIZE 256
  413. #endif
  414. #ifndef MG_BSD_Q_DEPTH
  415. #define MG_BSD_Q_DEPTH 4
  416. #endif
  417. #ifndef MG_BSD_ACCEPT_MS
  418. #define MG_BSD_ACCEPT_MS 3000 // Timeout for accept queue handoff
  419. #endif
  420. struct mg_bsd_chunk { uint8_t data[MG_BSD_CHUNK_SIZE]; uint16_t len; };
  421. struct mg_xport {
  422. struct mg_connection *c; // Mongoose connection, task1-only
  423. QueueHandle_t recv_q; // task1 writes on MG_EV_READ, task2 reads in recv()
  424. QueueHandle_t send_q; // task2 writes in send(), task1 drains on MG_EV_POLL
  425. QueueHandle_t accept_q; // task1 writes on MG_EV_ACCEPT, task2 reads in accept()
  426. struct sockaddr_in peer;
  427. uint16_t rx_off;
  428. uint64_t accept_expire;
  429. int err;
  430. bool closed;
  431. bool orphan; // accepted connection not handed to socket owner
  432. TaskHandle_t connect_waiter; // task blocked in connect(), woken by MG_EV_CONNECT
  433. int *connect_result; // where to store 0/−1 connect outcome
  434. };
  435. enum mg_bsd_cmd_op { BSD_CMD_LISTEN, BSD_CMD_CLOSE, BSD_CMD_CONNECT, BSD_CMD_RESOLVE };
  436. struct mg_bsd_cmd {
  437. enum mg_bsd_cmd_op type;
  438. struct mg_xport *x;
  439. char url[64];
  440. TaskHandle_t caller;
  441. int *result;
  442. };
  443. static QueueHandle_t s_cmd_q;
  444. static bool bsd_qsend(QueueHandle_t q, const void *item, TickType_t ticks,
  445. bool reserve) {
  446. BaseType_t ok = pdFALSE;
  447. if (!reserve || uxQueueSpacesAvailable(q) > 1) ok = xQueueSend(q, item, ticks);
  448. if (ok != pdTRUE) MG_ERROR(("%p", q));
  449. return ok == pdTRUE;
  450. }
  451. static bool xport_accept(struct mg_xport *x) {
  452. if (bsd_qsend(x->accept_q, &x, 0, true)) {
  453. x->orphan = false; // not an orphan anymore
  454. x->accept_q = NULL;
  455. return true;
  456. }
  457. return false; // still an orphan, retry later
  458. }
  459. // static DNS resolve state; not reentrant (see below)
  460. static struct { struct mg_addr addr; bool error; TaskHandle_t caller; } s_resolve;
  461. // gethostbyname statics (official isn't reentrant anyway, and is obsolete)
  462. static struct hostent s_hostent;
  463. static char *s_h_aliases[1];
  464. static char *s_h_addr_list[2];
  465. static uint32_t s_h_addr;
  466. static char s_h_name[64];
  467. static void resolve_cb(struct mg_connection *c, int ev, void *ev_data) {
  468. bool notify = false;
  469. if (ev == MG_EV_RESOLVE) {
  470. s_resolve.addr = c->rem;
  471. c->is_closing = 1;
  472. MG_DEBUG(("%lu resolved", c->id));
  473. notify = true;
  474. } else if (ev == MG_EV_ERROR) {
  475. s_resolve.error = true;
  476. MG_DEBUG(("%lu failed", c->id));
  477. notify = true;
  478. } else if (ev == MG_EV_CLOSE) {
  479. s_resolve.caller = NULL; // The resolver connection has fully unwound.
  480. MG_DEBUG(("%lu done", c->id));
  481. }
  482. if (notify) xTaskNotifyGive(s_resolve.caller);
  483. (void) ev_data;
  484. }
  485. // Allocate transport for an accepted connection (recv+send queues only)
  486. static struct mg_xport *xport_alloc(void) {
  487. struct mg_xport *x = (struct mg_xport *) calloc(1, sizeof(*x));
  488. if (!x) return NULL;
  489. // +1 keeps a terminal EOF/error slot for MG_EV_CLOSE
  490. x->recv_q = xQueueCreate(MG_BSD_Q_DEPTH + 1, sizeof(struct mg_bsd_chunk));
  491. x->send_q = xQueueCreate(MG_BSD_Q_DEPTH, sizeof(struct mg_bsd_chunk));
  492. if (!x->recv_q || !x->send_q) { mg_bsd_transport_free(x); return NULL; }
  493. x->orphan = true; // haven't attached this connection to its socket
  494. return x;
  495. }
  496. static void xport_ev(struct mg_connection *c, int ev, void *ev_data) {
  497. struct mg_xport *x = (struct mg_xport *) c->fn_data;
  498. if (!x) return;
  499. if (ev == MG_EV_ACCEPT) {
  500. // c is the new accepted connection; x is the listening transport
  501. bool ok;
  502. struct mg_xport *nx = xport_alloc();
  503. if (!nx) { c->fn_data = NULL; mg_error(c, "accept OOM"); return; }
  504. nx->c = c;
  505. nx->accept_q = x->accept_q;
  506. nx->accept_expire = mg_millis() + MG_BSD_ACCEPT_MS;
  507. nx->peer.sin_family = AF_INET;
  508. nx->peer.sin_port = c->rem.port;
  509. memcpy(&nx->peer.sin_addr, &c->rem.addr.ip4, 4);
  510. c->fn_data = nx;
  511. ok = xport_accept(nx); // leaves orphaned on failure, retry on POLL
  512. bsd_log(MG_BSD_LOG_ACCEPT, NULL, c, x, nx, ok ? 1 : 0);
  513. } else if (ev == MG_EV_POLL && x->orphan && x->accept_q) {
  514. if (uxQueueSpacesAvailable(x->accept_q) > 1 && xport_accept(x)) {
  515. bsd_log(MG_BSD_LOG_ACCEPT, NULL, c, NULL, x, 1);
  516. } else if (mg_millis() > x->accept_expire) { // retried enough, give up
  517. x->err = EIO;
  518. mg_error(c, "accept_q");
  519. }
  520. } else if (ev == MG_EV_READ || ev == MG_EV_POLL) {
  521. if (x->recv_q) { // let POLL resume abandoned READ processing on full queue
  522. // Drain c->recv into recv_q in fixed-size chunks; task1 owns c->recv
  523. size_t off = 0;
  524. while (off < c->recv.len) {
  525. struct mg_bsd_chunk chunk;
  526. size_t n = c->recv.len - off;
  527. if (n > MG_BSD_CHUNK_SIZE) n = MG_BSD_CHUNK_SIZE;
  528. memcpy(chunk.data, c->recv.buf + off, n);
  529. chunk.len = (uint16_t) n;
  530. if (uxQueueSpacesAvailable(x->recv_q) <= 1 ||
  531. !bsd_qsend(x->recv_q, &chunk, 0, false)) break; // retry later
  532. off += n;
  533. }
  534. mg_iobuf_del(&c->recv, 0, off);
  535. }
  536. if (ev == MG_EV_POLL && x->send_q) {
  537. // Drain send_q → mg_send(); task1 owns c
  538. struct mg_bsd_chunk chunk;
  539. while (xQueuePeek(x->send_q, &chunk, 0) == pdTRUE) {
  540. if (!mg_send(c, chunk.data, chunk.len)) break; // retry later
  541. xQueueReceive(x->send_q, &chunk, 0);
  542. }
  543. }
  544. } else if (ev == MG_EV_CONNECT) {
  545. // Outgoing connection established: wake the task blocked in connect()
  546. if (x->connect_waiter) {
  547. bsd_log(MG_BSD_LOG_CONNECT, "OK", x, c, NULL, 0);
  548. if (x->connect_result) *x->connect_result = 0;
  549. TaskHandle_t h = x->connect_waiter;
  550. x->connect_waiter = NULL; x->connect_result = NULL;
  551. xTaskNotifyGive(h);
  552. }
  553. } else if (ev == MG_EV_ERROR) { // remember error condition
  554. if (x->err == 0) x->err = EIO; // and let CLOSE handle it
  555. bsd_log(MG_BSD_LOG_CLOSE, "ERR", c, x, NULL, (long) x->err);
  556. } else if (ev == MG_EV_CLOSE) {
  557. bsd_log(MG_BSD_LOG_CLOSE, "IN", c, x, NULL, -1);
  558. x->c = NULL; x->closed = true; c->fn_data = NULL;
  559. // If connect() is still waiting, signal failure
  560. if (x->connect_waiter) {
  561. bsd_log(MG_BSD_LOG_CONNECT, "FAIL", x, c, NULL, -1);
  562. if (x->connect_result) *x->connect_result = -1;
  563. TaskHandle_t h = x->connect_waiter;
  564. x->connect_waiter = NULL; x->connect_result = NULL;
  565. xTaskNotifyGive(h);
  566. // The notified task owns the transport and can close/free it immediately.
  567. return;
  568. }
  569. if (x->orphan) { // connection --> socket attachment failed
  570. x->accept_q = NULL; // borrowed from listener; do not delete it here
  571. bsd_log(MG_BSD_LOG_CLOSE, "FREE", c, x, NULL, -1);
  572. mg_bsd_transport_free(x); // connection closed, release resources
  573. return;
  574. }
  575. if (x->recv_q) {
  576. struct mg_bsd_chunk eof;
  577. bool ok;
  578. memset(&eof, 0, sizeof(eof));
  579. eof.len = 0;
  580. ok = bsd_qsend(x->recv_q, &eof, 0, false);
  581. bsd_log(MG_BSD_LOG_CLOSE, "EOF>", c, x, NULL, ok ? 1 : 0);
  582. if (!ok) MG_ERROR(("recv_q close notification failed"));
  583. // recv() wakeup transfers control to the transport owner.
  584. return;
  585. }
  586. if (x->accept_q) {
  587. struct mg_xport *nil = NULL;
  588. bool ok;
  589. ok = bsd_qsend(x->accept_q, &nil, 0, false);
  590. bsd_log(MG_BSD_LOG_CLOSE, "ACCEPT>", c, x, NULL, ok ? 1 : 0);
  591. if (!ok) MG_ERROR(("accept_q close notification failed"));
  592. // accept() wakeup transfers control to the transport owner.
  593. return;
  594. }
  595. bsd_log(MG_BSD_LOG_CLOSE, "OUT", c, x, NULL, -1);
  596. }
  597. (void) ev_data;
  598. }
  599. void mg_bsd_init(void) {
  600. s_cmd_q = xQueueCreate(8, sizeof(struct mg_bsd_cmd));
  601. }
  602. void mg_bsd_poll(struct mg_mgr *mgr) {
  603. struct mg_bsd_cmd cmd;
  604. if (s_cmd_q == NULL) return;
  605. while (xQueueReceive(s_cmd_q, &cmd, 0) == pdTRUE) {
  606. bool notify = true;
  607. if (cmd.type == BSD_CMD_LISTEN) {
  608. struct mg_connection *c = mg_listen(mgr, cmd.url, xport_ev, cmd.x);
  609. cmd.x->c = c;
  610. *cmd.result = c ? 0 : -1;
  611. } else if (cmd.type == BSD_CMD_CLOSE) {
  612. bsd_log(MG_BSD_LOG_TRANSPORT, "CMD", cmd.x, NULL, NULL, -1);
  613. if (cmd.x->c) {
  614. cmd.x->c->fn_data = NULL;
  615. cmd.x->c->is_draining = 1;
  616. cmd.x->c = NULL;
  617. }
  618. cmd.x->closed = true;
  619. *cmd.result = 0;
  620. } else if (cmd.type == BSD_CMD_CONNECT) {
  621. cmd.x->connect_waiter = cmd.caller;
  622. cmd.x->connect_result = cmd.result;
  623. struct mg_connection *c = mg_connect(mgr, cmd.url, xport_ev, cmd.x);
  624. bsd_log(MG_BSD_LOG_CONNECT, "NEW", cmd.x, c, cmd.url, c ? 1 : 0);
  625. cmd.x->c = c;
  626. if (!c) { *cmd.result = -1; cmd.x->connect_waiter = NULL; cmd.x->connect_result = NULL; }
  627. else notify = false; // xport_ev notifies when connected or on error
  628. } else if (cmd.type == BSD_CMD_RESOLVE) {
  629. s_resolve.error = false;
  630. s_resolve.caller = cmd.caller;
  631. struct mg_connection *c;
  632. c = mg_alloc_conn(mgr);
  633. if (c == NULL) {
  634. } else {
  635. c->fn = resolve_cb;
  636. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  637. mg_call(c, MG_EV_OPEN, NULL);
  638. MG_DEBUG(("%lu resolve %s", c->id, cmd.url));
  639. mg_resolve(c, cmd.url);
  640. notify = false; // resolve_cb notifies when done
  641. }
  642. }
  643. if (notify) xTaskNotifyGive(cmd.caller);
  644. }
  645. }
  646. void *mg_bsd_transport_new(int domain, int type, int proto) {
  647. if (domain != AF_INET || type != SOCK_STREAM ||
  648. (proto != 0 && proto != IPPROTO_TCP)) {
  649. errno = EPROTONOSUPPORT;
  650. return NULL;
  651. }
  652. // For socket() calls: allocate accept_q only; recv/send added when needed.
  653. // +1 keeps a terminal slot for MG_EV_CLOSE without blocking Mongoose.
  654. struct mg_xport *x = (struct mg_xport *) calloc(1, sizeof(*x));
  655. if (!x) return NULL;
  656. x->accept_q = xQueueCreate(MG_BSD_BACKLOG + 1, sizeof(struct mg_xport *));
  657. if (!x->accept_q) { free(x); return NULL; }
  658. return x;
  659. }
  660. void mg_bsd_transport_free(void *t) {
  661. struct mg_xport *x = (struct mg_xport *) t;
  662. if (!x) return;
  663. bsd_log(MG_BSD_LOG_TRANSPORT, "FREE", x, NULL, NULL, -1);
  664. if (x->recv_q) vQueueDelete(x->recv_q);
  665. if (x->send_q) vQueueDelete(x->send_q);
  666. if (x->accept_q) vQueueDelete(x->accept_q);
  667. free(x);
  668. }
  669. int mg_bsd_transport_listen(void *t, const struct sockaddr_in *addr) {
  670. struct mg_xport *x = (struct mg_xport *) t;
  671. int result = -1;
  672. struct mg_bsd_cmd cmd = {BSD_CMD_LISTEN, x, {0}, xTaskGetCurrentTaskHandle(), &result};
  673. snprintf(cmd.url, sizeof(cmd.url), "tcp://0.0.0.0:%d", mg_ntohs(addr->sin_port));
  674. if (!bsd_qsend(s_cmd_q, &cmd, portMAX_DELAY, false)) return -1;
  675. ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
  676. return result;
  677. }
  678. void *mg_bsd_transport_accept(void *t, struct sockaddr_in *peer, bool nonblock) {
  679. struct mg_xport *x = (struct mg_xport *) t;
  680. struct mg_xport *nx = NULL;
  681. TickType_t ticks = nonblock ? 0 : portMAX_DELAY;
  682. if (xQueueReceive(x->accept_q, &nx, ticks) != pdTRUE) {
  683. errno = x->closed ? (x->err ? x->err : EIO) : (nonblock ? EAGAIN : EIO);
  684. return NULL;
  685. }
  686. if (!nx) { errno = x->err ? x->err : EIO; return NULL; }
  687. if (peer) *peer = nx->peer;
  688. return nx;
  689. }
  690. ssize_t mg_bsd_transport_recv(void *t, void *buf, size_t len, bool nonblock) {
  691. struct mg_xport *x = (struct mg_xport *) t;
  692. uint8_t *p = (uint8_t *) buf;
  693. size_t recvd = 0;
  694. TickType_t ticks = nonblock ? 0 : portMAX_DELAY;
  695. while (recvd < len) {
  696. struct mg_bsd_chunk chunk;
  697. if (xQueuePeek(x->recv_q, &chunk, recvd == 0 ? ticks : 0) != pdTRUE) {
  698. if (recvd > 0) break;
  699. errno = x->closed ? (x->err ? x->err : EIO) : (nonblock ? EAGAIN : EIO);
  700. return -1;
  701. }
  702. if (chunk.len == 0) {
  703. if (recvd > 0) break;
  704. xQueueReceive(x->recv_q, &chunk, 0);
  705. if (x->err) { errno = x->err; return -1; }
  706. return 0; // EOF
  707. } else {
  708. size_t n = chunk.len - x->rx_off;
  709. if (n > len - recvd) n = len - recvd;
  710. memcpy(p + recvd, chunk.data + x->rx_off, n);
  711. recvd += n;
  712. x->rx_off = (uint16_t) (x->rx_off + n);
  713. if (x->rx_off >= chunk.len) {
  714. xQueueReceive(x->recv_q, &chunk, 0);
  715. x->rx_off = 0;
  716. }
  717. }
  718. }
  719. return (ssize_t) recvd;
  720. }
  721. ssize_t mg_bsd_transport_send(void *t, const void *buf, size_t len, bool nonblock) {
  722. struct mg_xport *x = (struct mg_xport *) t;
  723. if (x->closed) { errno = x->err ? x->err : EPIPE; return -1; }
  724. size_t sent = 0;
  725. TickType_t ticks = nonblock ? 0 : portMAX_DELAY;
  726. while (sent < len) {
  727. struct mg_bsd_chunk chunk;
  728. size_t n = len - sent;
  729. if (n > MG_BSD_CHUNK_SIZE) n = MG_BSD_CHUNK_SIZE;
  730. memcpy(chunk.data, (const uint8_t *) buf + sent, n);
  731. chunk.len = (uint16_t) n;
  732. if (!bsd_qsend(x->send_q, &chunk, ticks, false)) {
  733. errno = x->closed ? (x->err ? x->err : EPIPE) : (nonblock ? EAGAIN : EIO);
  734. return sent > 0 ? (ssize_t) sent : -1;
  735. }
  736. sent += n;
  737. }
  738. return sent > 0 ? (ssize_t) sent : (errno = EAGAIN, -1);
  739. }
  740. int mg_bsd_transport_connect(void *t, const struct sockaddr_in *addr, bool nonblock) {
  741. struct mg_xport *x = (struct mg_xport *) t;
  742. (void) nonblock;
  743. if (!x->recv_q) x->recv_q = xQueueCreate(MG_BSD_Q_DEPTH + 1, sizeof(struct mg_bsd_chunk));
  744. if (!x->send_q) x->send_q = xQueueCreate(MG_BSD_Q_DEPTH, sizeof(struct mg_bsd_chunk));
  745. if (!x->recv_q || !x->send_q) { errno = ENOMEM; return -1; }
  746. int result = -1;
  747. struct mg_bsd_cmd cmd = {BSD_CMD_CONNECT, x, {0}, xTaskGetCurrentTaskHandle(), &result};
  748. uint8_t *ip = (uint8_t *) &addr->sin_addr.s_addr;
  749. snprintf(cmd.url, sizeof(cmd.url), "tcp://%d.%d.%d.%d:%d",
  750. ip[0], ip[1], ip[2], ip[3], mg_ntohs(addr->sin_port));
  751. bsd_log(MG_BSD_LOG_CONNECT, "REQ", x, NULL, cmd.url, -1);
  752. if (!bsd_qsend(s_cmd_q, &cmd, portMAX_DELAY, false)) return -1;
  753. ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
  754. if (result != 0) errno = x->err ? x->err : EIO;
  755. return result;
  756. }
  757. // gethostbyname: resolve via Mongoose DNS (not reentrant)
  758. struct hostent *gethostbyname(const char *name) {
  759. struct mg_bsd_cmd cmd = {BSD_CMD_RESOLVE, NULL, {0}, xTaskGetCurrentTaskHandle(), NULL};
  760. snprintf(cmd.url, sizeof(cmd.url), "%s", name);
  761. if (!bsd_qsend(s_cmd_q, &cmd, portMAX_DELAY, false)) return NULL;
  762. ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
  763. if (s_resolve.error) return NULL;
  764. s_h_addr = s_resolve.addr.addr.ip4;
  765. s_h_addr_list[0] = (char *) &s_h_addr;
  766. s_h_addr_list[1] = NULL;
  767. s_h_aliases[0] = NULL;
  768. snprintf(s_h_name, sizeof(s_h_name), "%s", name);
  769. s_hostent.h_name = s_h_name;
  770. s_hostent.h_aliases = s_h_aliases;
  771. s_hostent.h_addrtype = AF_INET;
  772. s_hostent.h_length = 4;
  773. s_hostent.h_addr_list = s_h_addr_list;
  774. return &s_hostent;
  775. }
  776. int getaddrinfo(const char *node, const char *service,
  777. const struct addrinfo *hints, struct addrinfo **res) {
  778. struct hostent *h = gethostbyname(node);
  779. if (!h) return -1;
  780. struct addrinfo *ai = (struct addrinfo *) calloc(1, sizeof(*ai));
  781. struct sockaddr_in *sa = (struct sockaddr_in *) calloc(1, sizeof(*sa));
  782. if (!ai || !sa) { free(ai); free(sa); return -1; }
  783. sa->sin_family = AF_INET;
  784. memcpy(&sa->sin_addr, h->h_addr, 4);
  785. if (service) sa->sin_port = htons((uint16_t) atoi(service));
  786. ai->ai_family = AF_INET;
  787. ai->ai_socktype = hints ? hints->ai_socktype : SOCK_STREAM;
  788. ai->ai_addrlen = sizeof(*sa);
  789. ai->ai_addr = (struct sockaddr *) sa;
  790. *res = ai;
  791. return 0;
  792. }
  793. void freeaddrinfo(struct addrinfo *res) {
  794. while (res) {
  795. struct addrinfo *next = res->ai_next;
  796. free(res->ai_addr);
  797. free(res);
  798. res = next;
  799. }
  800. }
  801. void mg_bsd_transport_close(void *t) {
  802. struct mg_xport *x = (struct mg_xport *) t;
  803. bsd_log(MG_BSD_LOG_TRANSPORT, "CLOSE", x, NULL, NULL, -1);
  804. if (!x->closed && x->c) {
  805. int result = 0;
  806. struct mg_bsd_cmd cmd = {BSD_CMD_CLOSE, x, {0}, xTaskGetCurrentTaskHandle(), &result};
  807. bool ok = bsd_qsend(s_cmd_q, &cmd, portMAX_DELAY, false);
  808. bsd_log(MG_BSD_LOG_TRANSPORT, "CMD>", x, NULL, NULL, ok ? 1 : 0);
  809. if (ok) {
  810. ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
  811. bsd_log(MG_BSD_LOG_RESULT, "CMD", x, NULL, NULL, (long) result);
  812. }
  813. }
  814. bsd_log(MG_BSD_LOG_TRANSPORT, "FREE_REQ", x, NULL, NULL, -1);
  815. mg_bsd_transport_free(x);
  816. }
  817. #ifndef MG_WAKEUP_QUEUE_DEPTH
  818. #define MG_WAKEUP_QUEUE_DEPTH 4
  819. #endif
  820. struct wumsg {
  821. unsigned long id;
  822. size_t len;
  823. uint8_t data[];
  824. };
  825. static void wufn(struct mg_connection *c, int ev, void *ev_data) {
  826. QueueHandle_t q = (QueueHandle_t) c->mgr->pipe.q;
  827. if (ev == MG_EV_POLL) {
  828. struct wumsg *m;
  829. if (xQueueReceive(q, &m, 0) == pdTRUE) {
  830. struct mg_connection *t;
  831. for (t = c->mgr->conns; t != NULL; t = t->next) {
  832. if (t->id == m->id) {
  833. struct mg_str data = mg_str_n((char *) m->data, m->len);
  834. mg_call(t, MG_EV_WAKEUP, &data);
  835. break;
  836. }
  837. }
  838. free(m);
  839. }
  840. } else if (ev == MG_EV_CLOSE) {
  841. struct wumsg *m;
  842. while (xQueueReceive(q, &m, 0) == pdTRUE) free(m);
  843. vQueueDelete(q);
  844. c->mgr->pipe.q = NULL;
  845. }
  846. (void) ev_data;
  847. }
  848. bool mg_wakeup_init(struct mg_mgr *mgr) {
  849. struct mg_connection *c;
  850. if (mgr->pipe.q != NULL) return true;
  851. mgr->pipe.q = xQueueCreate(MG_WAKEUP_QUEUE_DEPTH, sizeof(void *));
  852. if (mgr->pipe.q == NULL) {
  853. MG_ERROR(("Cannot create queue"));
  854. return false;
  855. }
  856. c = mg_alloc_conn(mgr);
  857. if (c == NULL) {
  858. vQueueDelete((QueueHandle_t) mgr->pipe.q);
  859. mgr->pipe.q = NULL;
  860. return false;
  861. }
  862. c->fd = (void *) (size_t) MG_INVALID_SOCKET;
  863. c->fn = wufn;
  864. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  865. MG_DEBUG(("%lu queue %p", c->id, mgr->pipe.q));
  866. mg_call(c, MG_EV_OPEN, NULL);
  867. return true;
  868. }
  869. bool mg_wakeup(struct mg_mgr *mgr, unsigned long conn_id, const void *buf,
  870. size_t len) {
  871. struct wumsg *m;
  872. if (mgr->pipe.q == NULL || conn_id == 0) return false;
  873. m = (struct wumsg *) calloc(1, sizeof(*m) + len);
  874. if (m == NULL) {
  875. MG_ERROR(("OOM"));
  876. return false;
  877. }
  878. m->id = conn_id;
  879. m->len = len;
  880. memcpy(m->data, buf, len);
  881. if (!bsd_qsend((QueueHandle_t) mgr->pipe.q, &m, 0, false)) {
  882. free(m);
  883. return false;
  884. }
  885. return true;
  886. }
  887. #endif // MG_ENABLE_FREERTOS
  888. #endif // MG_ENABLE_BSD_SOCKETS
  889. #ifdef MG_ENABLE_LINES
  890. #line 1 "src/dash.c"
  891. #endif
  892. #define MG_NO_CACHE_HEADERS "Cache-Control: no-cache\r\n"
  893. #define MG_JSON_HEADERS "Content-Type: application/json\r\n" MG_NO_CACHE_HEADERS
  894. #define CONN_HANDLED 'Z'
  895. struct mg_dash_cdata {
  896. char marker;
  897. struct mg_dash_user *u;
  898. struct mg_dash *dash;
  899. };
  900. static struct mg_dash_user s_guest;
  901. static struct mg_dash_user *s_users; // List of authenticated users
  902. static struct mg_str trimq(struct mg_str s) { // Trim double quotes
  903. if (s.len > 1 && s.buf[0] == '"') s.len -= 2, s.buf++;
  904. return s;
  905. }
  906. static struct mg_field_set *mg_dash_find_field_set(struct mg_dash *dash,
  907. struct mg_str name) {
  908. struct mg_field_set *fs;
  909. for (fs = dash->sets; fs != NULL; fs = fs->next) {
  910. if (mg_strcmp(name, mg_str(fs->name)) == 0) return fs;
  911. }
  912. return NULL;
  913. }
  914. // static struct mg_field *mg_dash_find_field(struct mg_field *fields,
  915. // struct mg_str name) {
  916. // size_t i;
  917. // for (i = 0; fields != NULL && fields[i].name != NULL; i++) {
  918. // if (mg_strcmp(name, mg_str(fields[i].name)) == 0) return &fields[i];
  919. // }
  920. // return NULL;
  921. // }
  922. static size_t mg_print_field(mg_pfn_t fn, void *arg, va_list *ap) {
  923. struct mg_field *f = va_arg(*ap, struct mg_field *);
  924. size_t n = 0;
  925. n += mg_xprintf(fn, arg, "%m:", MG_ESC(f->name));
  926. if (f->type == MG_VAL_BOOL) {
  927. n += mg_xprintf(fn, arg, "%s", *(bool *) f->value ? "true" : "false");
  928. } else if (f->type == MG_VAL_INT) {
  929. n += mg_xprintf(fn, arg, "%d", *(int *) f->value);
  930. } else if (f->type == MG_VAL_UINT64) {
  931. n += mg_xprintf(fn, arg, "%llu", (uint64_t) *(uint64_t *) f->value);
  932. } else if (f->type == MG_VAL_DBL) {
  933. n += mg_xprintf(fn, arg, "%.2f", *(double *) f->value);
  934. } else if (f->type == MG_VAL_STR) {
  935. n += mg_xprintf(fn, arg, "%m", MG_ESC(f->value));
  936. } else if (f->type == MG_VAL_RAW) {
  937. n += mg_xprintf(fn, arg, "%s", f->value);
  938. } else {
  939. n += mg_xprintf(fn, arg, "null");
  940. }
  941. return n;
  942. }
  943. static size_t mg_print_field_set(mg_pfn_t fn, void *arg, va_list *ap) {
  944. struct mg_field_set *set = va_arg(*ap, struct mg_field_set *);
  945. size_t i, n = 0;
  946. n += mg_xprintf(fn, arg, "{");
  947. for (i = 0; set != NULL && set->fields[i].name != NULL; i++) {
  948. if (i > 0) n += mg_xprintf(fn, arg, ",");
  949. n += mg_xprintf(fn, arg, "%M", mg_print_field, &set->fields[i]);
  950. }
  951. n += mg_xprintf(fn, arg, "}");
  952. return n;
  953. }
  954. static int mg_dash_array_size(struct mg_field_set *set,
  955. struct mg_dash_user *u) {
  956. int saved = *set->index, sz = -1;
  957. *set->index = -1;
  958. if (set->fn) {
  959. if (set->fn(MG_DASH_READ, u)) sz = *set->index;
  960. } else if (set->get_dir) {
  961. mg_dash_dir_read(set, u);
  962. sz = *set->index;
  963. }
  964. *set->index = saved;
  965. return sz;
  966. }
  967. static size_t mg_dash_print_array(mg_pfn_t fn, void *arg, va_list *ap) {
  968. struct mg_field_set *set = va_arg(*ap, struct mg_field_set *);
  969. int from = va_arg(*ap, int);
  970. int to = va_arg(*ap, int);
  971. struct mg_dash_user *u = va_arg(*ap, struct mg_dash_user *);
  972. bool started = false;
  973. int saved = *set->index;
  974. size_t n = 0;
  975. *set->index = from;
  976. n += mg_xprintf(fn, arg, "[");
  977. for (;;) {
  978. bool done = to >= 0 && *set->index > to;
  979. if (!done) {
  980. if (set->fn)
  981. set->fn(MG_DASH_READ, u);
  982. else if (set->get_dir)
  983. mg_dash_dir_read(set, u);
  984. done = *set->index < 0;
  985. }
  986. if (done) break;
  987. n += mg_xprintf(fn, arg, "%s%M", started ? "," : "", mg_print_field_set,
  988. set);
  989. started = true;
  990. (*set->index)++;
  991. }
  992. n += mg_xprintf(fn, arg, "]");
  993. *set->index = saved;
  994. return n;
  995. }
  996. static size_t mg_dash_print_endpoint(mg_pfn_t fn, void *arg, va_list *ap) {
  997. struct mg_dash *dash = va_arg(*ap, struct mg_dash *);
  998. struct mg_dash_user *u = va_arg(*ap, struct mg_dash_user *);
  999. struct mg_str *name = va_arg(*ap, struct mg_str *);
  1000. struct mg_str *from_str = va_arg(*ap, struct mg_str *);
  1001. struct mg_str *to_str = va_arg(*ap, struct mg_str *);
  1002. struct mg_field_set *set = mg_dash_find_field_set(dash, *name);
  1003. size_t n = 0;
  1004. if (name->len == 0) {
  1005. struct mg_field_set *fs;
  1006. const char *comma = "";
  1007. n += mg_xprintf(fn, arg, "{");
  1008. for (fs = dash->sets; fs != NULL; fs = fs->next) {
  1009. if (fs->index != NULL) {
  1010. int sz = mg_dash_array_size(fs, u);
  1011. if (sz < 0) continue;
  1012. n += mg_xprintf(fn, arg, comma);
  1013. n += mg_xprintf(fn, arg, "%m:%d", MG_ESC(fs->name), sz);
  1014. } else {
  1015. if (fs->fn && !fs->fn(MG_DASH_READ, u)) continue;
  1016. n += mg_xprintf(fn, arg, comma);
  1017. n += mg_xprintf(fn, arg, "%m:%M", MG_ESC(fs->name), mg_print_field_set,
  1018. fs);
  1019. }
  1020. comma = ",";
  1021. }
  1022. n += mg_xprintf(fn, arg, "}");
  1023. } else if (set != NULL && (set->fn == NULL || set->fn(MG_DASH_READ, u))) {
  1024. if (set->index != NULL && from_str != NULL && from_str->len > 0) {
  1025. int from = 0, to = 0;
  1026. mg_str_to_num(*from_str, 10, &from, sizeof(from));
  1027. to = from;
  1028. if (to_str != NULL && to_str->len > 0) {
  1029. mg_str_to_num(*to_str, 10, &to, sizeof(to));
  1030. }
  1031. n += mg_xprintf(fn, arg, "%M", mg_dash_print_array, set, from, to, u);
  1032. } else if (set->index != NULL) {
  1033. n += mg_xprintf(fn, arg, "%d", mg_dash_array_size(set, u));
  1034. } else {
  1035. n += mg_xprintf(fn, arg, "%M", mg_print_field_set, set);
  1036. }
  1037. } else {
  1038. n += mg_xprintf(fn, arg, "null");
  1039. }
  1040. return n;
  1041. }
  1042. void mg_dash_send_change(struct mg_mgr *mgr, struct mg_field_set *set) {
  1043. struct mg_connection *c;
  1044. for (c = mgr->conns; c != NULL; c = c->next) {
  1045. struct mg_dash_cdata *d;
  1046. struct mg_dash_user *u;
  1047. if (!c->is_websocket) continue;
  1048. d = (struct mg_dash_cdata *) c->data;
  1049. u = d->u;
  1050. if (u == NULL) continue;
  1051. if (set->index != NULL && *set->index < 0) {
  1052. int sz = mg_dash_array_size(set, u);
  1053. if (sz < 0) continue;
  1054. mg_ws_printf(c, WEBSOCKET_OP_TEXT, "{%m:%m,%m:{%m:%d}}", MG_ESC("method"),
  1055. MG_ESC("change"), MG_ESC("params"), MG_ESC(set->name), sz);
  1056. } else {
  1057. int saved_idx = set->index != NULL ? *set->index : 0;
  1058. bool ok = set->fn ? set->fn(MG_DASH_READ, u)
  1059. : (set->get_dir ? mg_dash_dir_read(set, u) : true);
  1060. if (!ok) {
  1061. if (set->index != NULL) *set->index = saved_idx;
  1062. continue;
  1063. }
  1064. if (set->index != NULL) {
  1065. char key[64];
  1066. mg_snprintf(key, sizeof(key), "%s/%d", set->name, *set->index);
  1067. mg_ws_printf(c, WEBSOCKET_OP_TEXT, "{%m:%m,%m:{%m:%M}}",
  1068. MG_ESC("method"), MG_ESC("change"), MG_ESC("params"),
  1069. MG_ESC(key), mg_print_field_set, set);
  1070. *set->index = saved_idx;
  1071. } else {
  1072. mg_ws_printf(c, WEBSOCKET_OP_TEXT, "{%m:%m,%m:{%m:%M}}",
  1073. MG_ESC("method"), MG_ESC("change"), MG_ESC("params"),
  1074. MG_ESC(set->name), mg_print_field_set, set);
  1075. }
  1076. }
  1077. }
  1078. }
  1079. static int mg_dash_parse_field(struct mg_str json, struct mg_field *f) {
  1080. char json_path[128];
  1081. bool ok = false;
  1082. mg_snprintf(json_path, sizeof(json_path), "$.%s", f->name);
  1083. if (f->type == MG_VAL_BOOL) {
  1084. ok = f->value_size == sizeof(bool) &&
  1085. mg_json_get_bool(json, json_path, (bool *) f->value);
  1086. } else if (f->type == MG_VAL_INT) {
  1087. double d;
  1088. if (f->value_size == sizeof(int) && mg_json_get_num(json, json_path, &d) &&
  1089. d == (int) d) {
  1090. *(int *) f->value = (int) d;
  1091. ok = true;
  1092. }
  1093. } else if (f->type == MG_VAL_UINT64) {
  1094. double d;
  1095. if (f->value_size == sizeof(uint64_t) &&
  1096. mg_json_get_num(json, json_path, &d) && d == (double) (int64_t) d) {
  1097. *(uint64_t *) f->value = (uint64_t) d;
  1098. ok = true;
  1099. }
  1100. } else if (f->type == MG_VAL_DBL) {
  1101. ok = f->value_size == sizeof(double) &&
  1102. mg_json_get_num(json, json_path, (double *) f->value);
  1103. } else if (f->type == MG_VAL_STR && f->value_size > 0) {
  1104. struct mg_str tok = mg_json_get_tok(json, json_path);
  1105. ok = tok.len >= 2 && tok.buf[0] == '"' &&
  1106. tok.buf[tok.len - 1] == '"';
  1107. if (ok) mg_json_unescape(json, json_path, (char *) f->value, f->value_size);
  1108. } else if (f->type == MG_VAL_RAW && f->value_size > 0) {
  1109. ok = mg_snprintf((char *) f->value, f->value_size, "%.*s", json.len,
  1110. json.buf) == json.len;
  1111. }
  1112. return ok;
  1113. }
  1114. static int mg_dash_apply(struct mg_connection *c, struct mg_dash *dash,
  1115. struct mg_str json, struct mg_dash_user *u) {
  1116. struct mg_str key, val;
  1117. size_t ofs = 0;
  1118. int total_count = 0;
  1119. while ((ofs = mg_json_next(json, ofs, &key, &val)) > 0) {
  1120. struct mg_field_set *set = mg_dash_find_field_set(dash, trimq(key));
  1121. int count = 0;
  1122. if (set == NULL) {
  1123. MG_ERROR(("UNKNOWN SET: [%.*s]", key.len, key.buf));
  1124. continue;
  1125. }
  1126. if (set->fn != NULL && !set->fn(MG_DASH_WRITE, u)) continue; // auth check
  1127. {
  1128. size_t i;
  1129. for (i = 0; set->fields[i].name != NULL; i++) {
  1130. if (mg_dash_parse_field(val, &set->fields[i])) count++;
  1131. }
  1132. }
  1133. if (count) {
  1134. if (set->fn) set->fn(MG_DASH_WRITE, u); // apply side effects
  1135. mg_dash_send_change(c->mgr, set);
  1136. total_count += count;
  1137. }
  1138. }
  1139. return total_count;
  1140. }
  1141. bool mg_dash_dir_read(struct mg_field_set *set, struct mg_dash_user *u) {
  1142. char dir[256], fname[128] = "";
  1143. struct mg_fs *fs = u->dash->upload_fs ? u->dash->upload_fs : &mg_fs_posix;
  1144. struct mg_field *name_field = NULL, *size_field = NULL;
  1145. size_t i;
  1146. if (!set->get_dir(u, dir, sizeof(dir))) return false;
  1147. for (i = 0; set->fields[i].name != NULL; i++) {
  1148. if (name_field == NULL && set->fields[i].type == MG_VAL_STR &&
  1149. strcmp(set->fields[i].name, "name") == 0)
  1150. name_field = &set->fields[i];
  1151. if (size_field == NULL && strcmp(set->fields[i].name, "size") == 0)
  1152. size_field = &set->fields[i];
  1153. }
  1154. if (name_field == NULL) return false;
  1155. if (*set->index == -1) { // Size query: count all files
  1156. int count = 0;
  1157. while (mg_fs_ls(fs, dir, fname, sizeof(fname))) count++;
  1158. *set->index = count;
  1159. return true;
  1160. }
  1161. { // Regular read: scan to *set->index
  1162. int target = *set->index, cur = 0;
  1163. while (mg_fs_ls(fs, dir, fname, sizeof(fname))) {
  1164. if (cur++ == target) {
  1165. mg_snprintf((char *) name_field->value, name_field->value_size, "%s",
  1166. fname);
  1167. if (size_field != NULL) {
  1168. char path[512];
  1169. size_t sz = 0;
  1170. mg_snprintf(path, sizeof(path), "%s/%s", dir, fname);
  1171. fs->st(path, &sz, NULL);
  1172. if (size_field->type == MG_VAL_UINT64)
  1173. *(uint64_t *) size_field->value = (uint64_t) sz;
  1174. else if (size_field->type == MG_VAL_INT)
  1175. *(int *) size_field->value = (int) sz;
  1176. }
  1177. return true;
  1178. }
  1179. }
  1180. *set->index = -1; // No more entries
  1181. return true;
  1182. }
  1183. }
  1184. static bool mg_dash_set_file_name(struct mg_field_set *set,
  1185. struct mg_str name) {
  1186. size_t i;
  1187. for (i = 0; set->fields[i].name != NULL; i++) {
  1188. struct mg_field *f = &set->fields[i];
  1189. if (f->type == MG_VAL_STR && strcmp(f->name, "name") == 0) {
  1190. mg_snprintf((char *) f->value, f->value_size, "%.*s", (int) name.len,
  1191. name.buf);
  1192. return true;
  1193. }
  1194. }
  1195. return false;
  1196. }
  1197. static inline void mg_log_http_req(struct mg_connection *c,
  1198. struct mg_http_message *hm) {
  1199. int len = 0;
  1200. size_t n, spaces = 0, body_n = hm->body.len;
  1201. struct mg_http_message tmp;
  1202. memset(&tmp, 0, sizeof(tmp));
  1203. len = mg_http_parse((char *) c->send.buf, c->send.len, &tmp);
  1204. n = (len < 0 || (size_t) len > c->send.len) ? c->send.len : (size_t) len;
  1205. while ((n + spaces) < c->send.len && spaces < c->send.len &&
  1206. (c->send.buf[c->send.len - spaces - 1] == '\r' ||
  1207. c->send.buf[c->send.len - spaces - 1] == '\n'))
  1208. spaces++;
  1209. // hm->body.len comes from Content-Length and can be larger than the bytes
  1210. // actually buffered so far (e.g. mid-stream uploads); cap the preview to
  1211. // what's actually present in c->recv, or we'd read past its end
  1212. {
  1213. char *recv_end = (char *) c->recv.buf + c->recv.len;
  1214. if (hm->body.buf >= (char *) c->recv.buf && hm->body.buf <= recv_end) {
  1215. size_t avail = (size_t) (recv_end - hm->body.buf);
  1216. if (body_n > avail) body_n = avail;
  1217. } else {
  1218. body_n = 0;
  1219. }
  1220. }
  1221. MG_DEBUG(("%lu %.*s %.*s%s%.*s %.*s: %lu %.*s -> %lu %.*s", c->id,
  1222. hm->method.len, hm->method.buf, hm->uri.len, hm->uri.buf,
  1223. hm->query.len > 0 ? "?" : "", hm->query.len, hm->query.buf,
  1224. c->send.len > 15 ? 3 : 0, &c->send.buf[9], hm->body.len, body_n,
  1225. hm->body.buf, c->send.len - n, c->send.len - n - spaces,
  1226. c->send.buf + n));
  1227. }
  1228. static void mg_dash_ota_cb(struct mg_connection *c, const char *errmsg) {
  1229. mg_http_reply(c, errmsg ? 500 : 200, NULL, errmsg ? errmsg : "ok\n");
  1230. c->is_draining = 1;
  1231. }
  1232. static void mg_dash_upload_cb(struct mg_connection *c, const char *errmsg) {
  1233. if (errmsg) {
  1234. mg_http_reply(c, 500, NULL, "%s\n", errmsg);
  1235. } else {
  1236. // mg_http_start_upload() repurposes c->data for its own bookkeeping,
  1237. // so the field set can't be cached there. Re-derive the dashboard from
  1238. // c->fn_data instead, and notify every file-backed array: the upload
  1239. // could belong to any of them, and re-querying get_dir() per recipient
  1240. // is what mg_dash_send_change() does anyway (directories can be
  1241. // user-specific)
  1242. struct mg_dash *dash = (struct mg_dash *) c->fn_data;
  1243. struct mg_field_set *fs;
  1244. mg_http_reply(c, 200, NULL, "ok\n");
  1245. for (fs = dash->sets; fs != NULL; fs = fs->next) {
  1246. if (fs->get_dir == NULL) continue;
  1247. *fs->index = -1; // Signal mg_dash_send_change() to broadcast new size
  1248. mg_dash_send_change(c->mgr, fs);
  1249. }
  1250. }
  1251. c->is_draining = 1;
  1252. }
  1253. static uint64_t mg_dash_make_expiration_time(struct mg_dash *dash) {
  1254. unsigned t = (unsigned) dash->session_auto_expiration_seconds;
  1255. if (t == 0) t = 3600; // Default expiration time in seconds
  1256. return mg_millis() + t * 1000;
  1257. }
  1258. static struct mg_dash_user *mg_dash_add_user(struct mg_dash_user **users,
  1259. struct mg_dash *dash,
  1260. const char *name,
  1261. const char *token, int level) {
  1262. struct mg_dash_user *u = (struct mg_dash_user *) mg_calloc(1, sizeof(*u));
  1263. if (u != NULL) {
  1264. mg_snprintf(u->name, sizeof(u->name), "%s", name);
  1265. if (token == NULL) {
  1266. mg_random_str(u->token, sizeof(u->token) - 1);
  1267. } else {
  1268. mg_snprintf(u->token, sizeof(u->token), "%s", token);
  1269. }
  1270. u->level = level;
  1271. u->expire = mg_dash_make_expiration_time(dash);
  1272. u->dash = dash;
  1273. u->next = *users;
  1274. *users = u;
  1275. }
  1276. return u;
  1277. }
  1278. static struct mg_dash_user *mg_dash_find_user(struct mg_dash_user *users,
  1279. struct mg_dash *dash,
  1280. const char *name) {
  1281. struct mg_dash_user *u;
  1282. for (u = users; u != NULL; u = u->next) {
  1283. if (u->dash == dash && strcmp(u->name, name) == 0) return u;
  1284. }
  1285. return NULL;
  1286. }
  1287. static struct mg_dash_user *mg_dash_find_token(struct mg_dash_user *users,
  1288. struct mg_dash *dash,
  1289. const char *token) {
  1290. struct mg_dash_user *u;
  1291. for (u = users; u != NULL; u = u->next) {
  1292. if (u->dash == dash && strcmp(u->token, token) == 0) return u;
  1293. }
  1294. return NULL;
  1295. }
  1296. static void mg_dash_refresh_user(struct mg_dash *dash,
  1297. struct mg_dash_user *user) {
  1298. user->expire = mg_dash_make_expiration_time(dash);
  1299. }
  1300. static void mg_dash_delete_user(struct mg_mgr *mgr, struct mg_dash_user *u) {
  1301. struct mg_connection *conn;
  1302. for (conn = mgr->conns; conn != NULL; conn = conn->next) {
  1303. struct mg_dash_cdata *d = (struct mg_dash_cdata *) conn->data;
  1304. if (conn->is_websocket && d->dash == u->dash && d->u == u) {
  1305. d->u = NULL;
  1306. conn->is_closing = 1;
  1307. }
  1308. }
  1309. LIST_DELETE(struct mg_dash_user, &s_users, u);
  1310. mg_free(u);
  1311. }
  1312. static void mg_dash_delete_users(struct mg_mgr *mgr, struct mg_dash *dash) {
  1313. struct mg_dash_user *u, *tmp;
  1314. for (u = s_users; u != NULL; u = tmp) {
  1315. tmp = u->next;
  1316. if (u->dash == dash) mg_dash_delete_user(mgr, u);
  1317. }
  1318. }
  1319. // Parse HTTP requests, return authenticated user or NULL
  1320. static struct mg_dash_user *mg_dash_authenticate(struct mg_connection *c,
  1321. struct mg_http_message *hm,
  1322. struct mg_dash *dash) {
  1323. char user[100], pass[100];
  1324. struct mg_dash_user *u, *tmp;
  1325. struct mg_str *ah;
  1326. int level = 0, num_users = 0;
  1327. if (dash->authenticate == NULL) {
  1328. mg_snprintf(s_guest.name, sizeof(s_guest.name), "%s", "guest");
  1329. s_guest.level = 9;
  1330. s_guest.dash = dash;
  1331. dash->guest = &s_guest;
  1332. return dash->guest;
  1333. }
  1334. mg_http_creds(hm, user, sizeof(user), pass, sizeof(pass));
  1335. ah = mg_http_get_header(hm, "Authorization");
  1336. // MG_DEBUG(("user [%s], pass: [%s], h: %.*s", user, pass, hm->head.len,
  1337. // hm->head.buf));
  1338. // Remove expired users
  1339. for (u = s_users; u != NULL; u = tmp) {
  1340. tmp = u->next;
  1341. if (u->expire < mg_millis()) {
  1342. MG_DEBUG(("Deleting expired auth %s/%d %llu %u", u->name, u->level,
  1343. u->expire, mg_millis() - u->expire));
  1344. mg_dash_delete_user(c->mgr, u);
  1345. }
  1346. }
  1347. if (pass[0] == '\0') return NULL;
  1348. for (u = s_users; u != NULL; u = u->next) {
  1349. if (u->dash == dash) num_users++;
  1350. }
  1351. if (ah == NULL) {
  1352. u = mg_dash_find_token(s_users, dash, pass);
  1353. if (u != NULL) {
  1354. mg_dash_refresh_user(dash, u);
  1355. return u;
  1356. }
  1357. }
  1358. level = dash->authenticate(user, sizeof(user), pass);
  1359. MG_DEBUG(("user %s, level: %d", user, level));
  1360. if (level <= 0) return NULL;
  1361. u = mg_dash_find_user(s_users, dash, user);
  1362. if (u != NULL) {
  1363. if (ah == NULL) mg_snprintf(u->token, sizeof(u->token), "%s", pass);
  1364. mg_dash_refresh_user(dash, u);
  1365. return u;
  1366. }
  1367. if (num_users < 10)
  1368. return mg_dash_add_user(&s_users, dash, user, ah == NULL ? pass : NULL,
  1369. level);
  1370. // MG_DEBUG(("[%s/%s] -> %s", user, pass, result ? "OK" : "FAIL"));
  1371. return NULL;
  1372. }
  1373. static void mg_handle_login(struct mg_connection *c, struct mg_dash_user *u) {
  1374. char cookie[256];
  1375. mg_snprintf(cookie, sizeof(cookie),
  1376. "Set-Cookie: access_token=%s; Path=/; "
  1377. "%sHttpOnly; SameSite=Lax; Max-Age=%d\r\n%s",
  1378. u->token, c->is_tls ? "Secure; " : "", 3600 * 24,
  1379. MG_JSON_HEADERS);
  1380. mg_http_reply(c, 200, cookie, "{%m:%m,%m:%d}\n", //
  1381. MG_ESC("user"), MG_ESC(u->name), //
  1382. MG_ESC("level"), u->level);
  1383. }
  1384. static void mg_handle_logout(struct mg_connection *c) {
  1385. char cookie[256];
  1386. mg_snprintf(cookie, sizeof(cookie),
  1387. "Set-Cookie: access_token=; Path=/; "
  1388. "Expires=Thu, 01 Jan 1970 00:00:00 UTC; "
  1389. "%sHttpOnly; Max-Age=0; \r\n",
  1390. c->is_tls ? "Secure; " : "");
  1391. mg_http_reply(c, 401, cookie, "Unauthorized\n");
  1392. }
  1393. static void mg_dash_handle_del(struct mg_connection *c, struct mg_dash *dash,
  1394. struct mg_dash_user *u, struct mg_str *parts) {
  1395. struct mg_field_set *set = mg_dash_find_field_set(dash, parts[0]);
  1396. if (set == NULL || set->index == NULL) {
  1397. mg_http_reply(c, 404, MG_JSON_HEADERS, "null\n");
  1398. } else {
  1399. int from = 0, to = 0, count = 0;
  1400. if (parts[1].len) mg_str_to_num(parts[1], 10, &from, sizeof(from));
  1401. to = parts[2].len ? 0 : from;
  1402. if (parts[2].len) mg_str_to_num(parts[2], 10, &to, sizeof(to));
  1403. for (*set->index = from; *set->index <= to; (*set->index)++) {
  1404. if (set->fn && set->fn(MG_DASH_DELETE, u))
  1405. count++;
  1406. else
  1407. break;
  1408. }
  1409. if (count) {
  1410. *set->index = -1;
  1411. mg_dash_send_change(c->mgr, set);
  1412. mg_http_reply(c, 200, MG_JSON_HEADERS, "%d\n", count);
  1413. } else {
  1414. mg_http_reply(c, 403, MG_JSON_HEADERS, "false\n");
  1415. }
  1416. }
  1417. }
  1418. // Handle "POST /api/get/<set>/<index>": modify one array element. Loads the
  1419. // element at <index> first - that doubles as a read-access check and as a
  1420. // pre-fill, so that JSON keys absent from the body keep their old values -
  1421. // then overlays the values from the body and asks fn to persist them
  1422. static void mg_dash_handle_mod(struct mg_connection *c, struct mg_dash *dash,
  1423. struct mg_dash_user *u, struct mg_str *parts,
  1424. struct mg_str body) {
  1425. struct mg_field_set *set = mg_dash_find_field_set(dash, parts[0]);
  1426. int index = 0, count = 0;
  1427. size_t i;
  1428. if (set == NULL || set->index == NULL || set->fn == NULL) {
  1429. mg_http_reply(c, 404, MG_JSON_HEADERS, "null\n");
  1430. return;
  1431. }
  1432. mg_str_to_num(parts[1], 10, &index, sizeof(index));
  1433. *set->index = index;
  1434. if (!set->fn(MG_DASH_READ, u) || *set->index != index) {
  1435. mg_http_reply(c, 404, MG_JSON_HEADERS, "null\n");
  1436. return;
  1437. }
  1438. for (i = 0; set->fields[i].name != NULL; i++) {
  1439. if (mg_dash_parse_field(body, &set->fields[i])) count++;
  1440. }
  1441. if (count && set->fn(MG_DASH_WRITE, u)) {
  1442. mg_dash_send_change(c->mgr, set);
  1443. mg_http_reply(c, 200, MG_JSON_HEADERS, "%d\n", count);
  1444. } else {
  1445. mg_http_reply(c, 403, MG_JSON_HEADERS, "false\n");
  1446. }
  1447. }
  1448. // Handle "POST /api/add/<set>": append a new array element. Parses the body
  1449. // straight into the bound fields, then asks fn to accept and persist them as
  1450. // a new element - fn returns false to reject, e.g. when a cap is reached
  1451. static void mg_dash_handle_add(struct mg_connection *c, struct mg_dash *dash,
  1452. struct mg_dash_user *u, struct mg_str *parts,
  1453. struct mg_str body) {
  1454. struct mg_field_set *set = mg_dash_find_field_set(dash, parts[0]);
  1455. int count = 0;
  1456. size_t i;
  1457. if (set == NULL || set->index == NULL || set->fn == NULL) {
  1458. mg_http_reply(c, 404, MG_JSON_HEADERS, "null\n");
  1459. return;
  1460. }
  1461. for (i = 0; set->fields[i].name != NULL; i++) {
  1462. if (mg_dash_parse_field(body, &set->fields[i])) count++;
  1463. }
  1464. if (count && set->fn(MG_DASH_ADD, u)) {
  1465. *set->index = -1; // Signal mg_dash_send_change() to send new size
  1466. mg_dash_send_change(c->mgr, set);
  1467. mg_http_reply(c, 200, MG_JSON_HEADERS, "true\n");
  1468. } else {
  1469. mg_http_reply(c, 403, MG_JSON_HEADERS, "false\n");
  1470. }
  1471. }
  1472. void mg_dash_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
  1473. struct mg_dash *dash = (struct mg_dash *) c->fn_data;
  1474. struct mg_dash_cdata *d = (struct mg_dash_cdata *) c->data;
  1475. if (ev == MG_EV_OPEN) {
  1476. d->dash = dash;
  1477. // c->is_hexdumping = 1;
  1478. } else if (ev == MG_EV_CLOSE && c->is_listening) {
  1479. mg_dash_delete_users(c->mgr, dash);
  1480. } else if (ev == MG_EV_HTTP_HDRS && d->marker == 0) {
  1481. // Received headers - check authentication and possibly start uploads/ota
  1482. struct mg_http_message *hm = (struct mg_http_message *) ev_data;
  1483. struct mg_dash_user *u = mg_dash_authenticate(c, hm, dash);
  1484. struct mg_str parts[3];
  1485. memset(parts, 0, sizeof(parts));
  1486. if (mg_match(hm->uri, mg_str("/api/hi"), NULL) ||
  1487. mg_match(hm->uri, mg_str("/api/logout"), NULL)) {
  1488. // Do nothing, handle them MG_EV_HTTP_MSG. We bypass auth for those
  1489. } else if (u == NULL && mg_match(hm->uri, mg_str("/api/#"), NULL)) {
  1490. mg_http_reply(c, 403, MG_JSON_HEADERS, "Not Authorised\n");
  1491. d->marker = CONN_HANDLED;
  1492. } else if (mg_match(hm->uri, mg_str("/api/login"), NULL) && u != NULL) {
  1493. mg_handle_login(c, u);
  1494. d->marker = CONN_HANDLED;
  1495. } else if (mg_match(hm->uri, mg_str("/api/ota"), NULL)) {
  1496. mg_http_start_ota(c, hm, mg_dash_ota_cb);
  1497. } else if (mg_match(hm->uri, mg_str("/fs/*/*"), parts) &&
  1498. (mg_strcasecmp(hm->method, mg_str("POST")) == 0 ||
  1499. mg_strcasecmp(hm->method, mg_str("PUT")) == 0)) {
  1500. struct mg_field_set *set = mg_dash_find_field_set(dash, parts[0]);
  1501. struct mg_str name = parts[1];
  1502. int len =
  1503. mg_url_decode(name.buf, name.len, (char *) name.buf, name.len + 1, 0);
  1504. if (len > 0 && (size_t) len <= name.len) name.len = (size_t) len;
  1505. if (set == NULL || set->get_dir == NULL) {
  1506. mg_http_reply(c, 404, MG_JSON_HEADERS, "Not Found\n");
  1507. d->marker = CONN_HANDLED;
  1508. } else if (u == NULL) {
  1509. mg_http_reply(c, 403, MG_JSON_HEADERS, "Not Authorised\n");
  1510. d->marker = CONN_HANDLED;
  1511. } else if (!mg_path_is_sane(name)) {
  1512. mg_http_reply(c, 400, MG_JSON_HEADERS, "Bad file name\n");
  1513. d->marker = CONN_HANDLED;
  1514. } else {
  1515. mg_dash_set_file_name(set, name);
  1516. if (set->fn != NULL && !set->fn(MG_DASH_WRITE, u)) {
  1517. mg_http_reply(c, 403, MG_JSON_HEADERS, "Not Authorised\n");
  1518. d->marker = CONN_HANDLED;
  1519. } else {
  1520. char dir[256];
  1521. struct mg_fs *fs = dash->upload_fs ? dash->upload_fs : &mg_fs_posix;
  1522. if (!set->get_dir(u, dir, sizeof(dir))) {
  1523. mg_http_reply(c, 500, MG_JSON_HEADERS, "Upload dir error\n");
  1524. d->marker = CONN_HANDLED;
  1525. } else {
  1526. mg_http_start_upload(c, hm, name, mg_str(dir), fs,
  1527. mg_dash_upload_cb);
  1528. }
  1529. }
  1530. }
  1531. }
  1532. if (d->marker != '\0') mg_log_http_req(c, hm);
  1533. } else if (ev == MG_EV_HTTP_MSG && d->marker != '\0') {
  1534. // The response has been send in EV_HDRS path, so we're not reponding
  1535. // anything but clearing the marker for the next request.
  1536. d->marker = 0;
  1537. c->is_resp = 0;
  1538. } else if (ev == MG_EV_HTTP_MSG && d->marker == '\0') {
  1539. struct mg_http_message *hm = (struct mg_http_message *) ev_data;
  1540. struct mg_dash_user *u = mg_dash_authenticate(c, hm, dash);
  1541. struct mg_str parts[5];
  1542. memset(parts, 0, sizeof(parts));
  1543. if (mg_match(hm->uri, mg_str("/api/hi"), NULL)) {
  1544. mg_http_reply(c, 200, MG_JSON_HEADERS, "hi\n");
  1545. } else if (mg_match(hm->uri, mg_str("/api/logout"), NULL)) {
  1546. mg_handle_logout(c);
  1547. mg_ws_printf(c, WEBSOCKET_OP_TEXT, "{%m:%m}", MG_ESC("method"),
  1548. MG_ESC("logout"));
  1549. } else if (mg_match(hm->uri, mg_str("/api/websocket"), NULL)) {
  1550. d->u = u;
  1551. mg_ws_upgrade(c, hm, NULL);
  1552. } else if (mg_match(hm->uri, mg_str("/fs/*/*"), parts)) {
  1553. struct mg_field_set *set = mg_dash_find_field_set(dash, parts[0]);
  1554. if (set == NULL || set->get_dir == NULL) {
  1555. mg_http_reply(c, 404, MG_JSON_HEADERS, "Not Found");
  1556. } else if (u == NULL) {
  1557. mg_http_reply(c, 403, MG_JSON_HEADERS, "Not Authorised\n");
  1558. } else {
  1559. char dir[256], path[512];
  1560. struct mg_fs *fs = dash->upload_fs ? dash->upload_fs : &mg_fs_posix;
  1561. struct mg_str name = parts[1];
  1562. int len = mg_url_decode(name.buf, name.len, (char *) name.buf,
  1563. name.len + 1, 0);
  1564. if (len > 0 && (size_t) len <= name.len) name.len = (size_t) len;
  1565. if (!mg_path_is_sane(name)) {
  1566. mg_http_reply(c, 400, MG_JSON_HEADERS, "Bad file name\n");
  1567. return;
  1568. }
  1569. if (!set->get_dir(u, dir, sizeof(dir))) {
  1570. mg_http_reply(c, 500, MG_JSON_HEADERS, "Upload dir error\n");
  1571. return;
  1572. }
  1573. mg_snprintf(path, sizeof(path), "%s/%.*s", dir, name.len, name.buf);
  1574. if (mg_strcasecmp(hm->method, mg_str("DELETE")) == 0) {
  1575. mg_dash_set_file_name(set, name);
  1576. if (set->fn != NULL && !set->fn(MG_DASH_DELETE, u)) {
  1577. mg_http_reply(c, 403, MG_JSON_HEADERS, "Not Authorised\n");
  1578. } else {
  1579. fs->rm(path);
  1580. *set->index = -1; // Signal mg_dash_send_change() to send new size
  1581. mg_dash_send_change(c->mgr, set);
  1582. mg_http_reply(c, 200, NULL, "true");
  1583. }
  1584. } else {
  1585. mg_http_serve_file(c, hm, path, NULL);
  1586. }
  1587. }
  1588. } else if (mg_match(hm->uri, mg_str("/api/del/*/*/*"), parts) ||
  1589. mg_match(hm->uri, mg_str("/api/del/*/*"), parts)) {
  1590. mg_dash_handle_del(c, dash, u, parts);
  1591. } else if (mg_match(hm->uri, mg_str("/api/add/*"), parts)) {
  1592. mg_dash_handle_add(c, dash, u, parts, hm->body);
  1593. } else if (mg_match(hm->uri, mg_str("/api/get/*/*"), parts) &&
  1594. mg_strcasecmp(hm->method, mg_str("POST")) == 0) {
  1595. mg_dash_handle_mod(c, dash, u, parts, hm->body);
  1596. } else if (mg_match(hm->uri, mg_str("/api/get/*/*/*"), parts) ||
  1597. mg_match(hm->uri, mg_str("/api/get/*/*"), parts) ||
  1598. mg_match(hm->uri, mg_str("/api/get/*"), parts) ||
  1599. mg_match(hm->uri, mg_str("/api/get"), NULL)) {
  1600. mg_http_reply(c, 200, MG_JSON_HEADERS, "%M\n", mg_dash_print_endpoint,
  1601. dash, u, &parts[0], &parts[1], &parts[2]);
  1602. } else if (mg_match(hm->uri, mg_str("/api/set"), NULL)) {
  1603. int count = mg_dash_apply(c, dash, hm->body, u);
  1604. mg_http_reply(c, 200, MG_JSON_HEADERS, "%d\n", count);
  1605. } else if (mg_match(hm->uri, mg_str("/"), NULL)) {
  1606. struct mg_http_serve_opts opts;
  1607. memset(&opts, 0, sizeof(opts));
  1608. opts.fs = &mg_fs_packed;
  1609. mg_http_serve_file(c, hm, "/dashboard.html", &opts);
  1610. } else {
  1611. struct mg_dash_custom_handler *ch = dash->custom_handlers;
  1612. for (ch = dash->custom_handlers; ch != NULL; ch = ch->next) {
  1613. if (mg_match(hm->uri, ch->uri_pattern, NULL)) {
  1614. ch->handler(c, ev, ev_data);
  1615. break;
  1616. }
  1617. }
  1618. if (ch == NULL) mg_http_reply(c, 404, MG_JSON_HEADERS, "Not Found");
  1619. mg_log_http_req(c, hm);
  1620. }
  1621. }
  1622. }
  1623. #ifdef MG_ENABLE_LINES
  1624. #line 1 "src/dns.c"
  1625. #endif
  1626. struct dns_data {
  1627. struct dns_data *next;
  1628. struct mg_connection *c;
  1629. uint64_t expire;
  1630. uint16_t txnid;
  1631. };
  1632. static void sendnsreq(struct mg_connection *, struct mg_str *, int,
  1633. struct mg_dns *, bool);
  1634. struct mdns_data {
  1635. struct mdns_data *next;
  1636. struct mg_connection *c;
  1637. uint64_t expire;
  1638. struct mg_str name;
  1639. };
  1640. static void sendmdnsreq(struct mg_connection *, struct mg_str *, int,
  1641. struct mg_connection *, bool);
  1642. static void dns_free(struct dns_data **head, struct dns_data *d) {
  1643. LIST_DELETE(struct dns_data, head, d);
  1644. mg_free(d);
  1645. }
  1646. static void mdns_free(struct mdns_data **head, struct mdns_data *d) {
  1647. LIST_DELETE(struct mdns_data, head, d);
  1648. mg_free((void *) d->name.buf);
  1649. mg_free(d);
  1650. }
  1651. void mg_resolve_cancel(struct mg_connection *c) {
  1652. struct dns_data *tmp, *d;
  1653. struct mdns_data *mtmp, *md;
  1654. struct dns_data **head = (struct dns_data **) &c->mgr->active_dns_requests;
  1655. struct mdns_data **mhead =
  1656. (struct mdns_data **) &c->mgr->active_mdns_requests;
  1657. for (d = *head; d != NULL; d = tmp) {
  1658. tmp = d->next;
  1659. if (d->c == c) dns_free(head, d);
  1660. }
  1661. for (md = *mhead; md != NULL; md = mtmp) {
  1662. mtmp = md->next;
  1663. if (md->c == c) mdns_free(mhead, md);
  1664. }
  1665. }
  1666. static size_t mg_dns_parse_name_depth(const uint8_t *s, size_t len, size_t ofs,
  1667. char *to, size_t tolen, size_t j,
  1668. int depth) {
  1669. size_t i = 0;
  1670. if (tolen > 0 && depth == 0) to[0] = '\0';
  1671. if (depth > 5) return 0;
  1672. // MG_INFO(("ofs %lx %x %x", (unsigned long) ofs, s[ofs], s[ofs + 1]));
  1673. while (ofs + i + 1 < len) {
  1674. size_t n = s[ofs + i];
  1675. if (n == 0) {
  1676. i++;
  1677. break;
  1678. }
  1679. if (n & 0xc0) {
  1680. size_t ptr = (((n & 0x3f) << 8) | s[ofs + i + 1]); // 12 is hdr len
  1681. // MG_INFO(("PTR %lx", (unsigned long) ptr));
  1682. if (ptr + 1 < len && (s[ptr] & 0xc0) == 0 &&
  1683. mg_dns_parse_name_depth(s, len, ptr, to, tolen, j, depth + 1) == 0)
  1684. return 0;
  1685. i += 2;
  1686. break;
  1687. }
  1688. if (ofs + i + n + 1 >= len) return 0;
  1689. if (j > 0) {
  1690. if (j < tolen) to[j] = '.';
  1691. j++;
  1692. }
  1693. if (j + n < tolen) memcpy(&to[j], &s[ofs + i + 1], n);
  1694. j += n;
  1695. i += n + 1;
  1696. if (j < tolen) to[j] = '\0'; // Zero-terminate this chunk
  1697. // MG_INFO(("--> [%s]", to));
  1698. }
  1699. if (tolen > 0) to[tolen - 1] = '\0'; // Make sure it is nul-term
  1700. return i;
  1701. }
  1702. static size_t mg_dns_parse_name(const uint8_t *s, size_t n, size_t ofs,
  1703. char *dst, size_t dstlen) {
  1704. return mg_dns_parse_name_depth(s, n, ofs, dst, dstlen, 0, 0);
  1705. }
  1706. size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
  1707. bool is_question, struct mg_dns_rr *rr) {
  1708. const uint8_t *s = buf + ofs, *e = &buf[len];
  1709. memset(rr, 0, sizeof(*rr));
  1710. if (len < sizeof(struct mg_dns_header)) return 0; // Too small
  1711. if (len > 512) return 0; // Too large, we don't expect that
  1712. if (s >= e) return 0; // Overflow
  1713. if ((rr->nlen = (uint16_t) mg_dns_parse_name(buf, len, ofs, NULL, 0)) == 0)
  1714. return 0;
  1715. s += rr->nlen + 4;
  1716. if (s > e) return 0;
  1717. rr->atype = (uint16_t) (((uint16_t) s[-4] << 8) | s[-3]);
  1718. rr->aclass = (uint16_t) (((uint16_t) s[-2] << 8) | s[-1]);
  1719. if (is_question) return (size_t) (rr->nlen + 4);
  1720. s += 6;
  1721. if (s > e) return 0;
  1722. rr->alen = (uint16_t) (((uint16_t) s[-2] << 8) | s[-1]);
  1723. if (s + rr->alen > e) return 0;
  1724. return (size_t) (rr->nlen + rr->alen + 10);
  1725. }
  1726. bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
  1727. const struct mg_dns_header *h = (struct mg_dns_header *) buf;
  1728. struct mg_dns_rr rr;
  1729. size_t i, n, num_answers, ofs = sizeof(*h);
  1730. bool is_response;
  1731. memset(dm, 0, sizeof(*dm));
  1732. if (len < sizeof(*h)) return 0; // Too small, headers dont fit
  1733. if (mg_ntohs(h->num_questions) > 1) return 0; // Sanity
  1734. num_answers = mg_ntohs(h->num_answers);
  1735. if (num_answers > 10) {
  1736. MG_DEBUG(("Got %u answers, ignoring beyond 10th one", num_answers));
  1737. num_answers = 10; // Sanity cap
  1738. }
  1739. dm->txnid = mg_ntohs(h->txnid);
  1740. is_response = mg_ntohs(h->flags) & 0x8000;
  1741. for (i = 0; i < mg_ntohs(h->num_questions); i++) {
  1742. if ((n = mg_dns_parse_rr(buf, len, ofs, true, &rr)) == 0) return false;
  1743. // MG_INFO(("Q %lu %lu %hu/%hu", ofs, n, rr.atype, rr.aclass));
  1744. mg_dns_parse_name(buf, len, ofs, dm->name, sizeof(dm->name));
  1745. ofs += n;
  1746. }
  1747. if (!is_response) {
  1748. // For queries, there is no need to parse the answers. In this way,
  1749. // we also ensure the domain name (dm->name) is parsed from
  1750. // the question field.
  1751. return true;
  1752. }
  1753. for (i = 0; i < num_answers; i++) {
  1754. if ((n = mg_dns_parse_rr(buf, len, ofs, false, &rr)) == 0) return false;
  1755. // MG_INFO(("A -- %lu %lu %hu/%hu %s", ofs, n, rr.atype, rr.aclass,
  1756. // dm->name));
  1757. mg_dns_parse_name(buf, len, ofs, dm->name, sizeof(dm->name));
  1758. ofs += n;
  1759. if (rr.alen == 4 && rr.atype == MG_DNS_RTYPE_A && rr.aclass == 1) {
  1760. dm->addr.is_ip6 = false;
  1761. memcpy(&dm->addr.addr.ip, &buf[ofs - 4], 4);
  1762. dm->resolved = true;
  1763. break; // Return success
  1764. } else if (rr.alen == 16 && rr.atype == MG_DNS_RTYPE_AAAA &&
  1765. rr.aclass == 1) {
  1766. dm->addr.is_ip6 = true;
  1767. memcpy(&dm->addr.addr.ip, &buf[ofs - 16], 16);
  1768. dm->resolved = true;
  1769. break; // Return success
  1770. }
  1771. }
  1772. return true;
  1773. }
  1774. static void dns_cb(struct mg_connection *c, int ev, void *ev_data) {
  1775. struct dns_data *d, *tmp;
  1776. struct dns_data **head = (struct dns_data **) &c->mgr->active_dns_requests;
  1777. if (ev == MG_EV_POLL) {
  1778. uint64_t now = *(uint64_t *) ev_data;
  1779. for (d = *head; d != NULL; d = tmp) {
  1780. tmp = d->next;
  1781. // MG_DEBUG(("%lu %lu dns poll", d->expire, now));
  1782. if (now > d->expire) mg_error(d->c, "DNS timeout"); // will remove entry
  1783. }
  1784. } else if (ev == MG_EV_READ) {
  1785. struct mg_dns_message dm;
  1786. int resolved = 0;
  1787. if (mg_dns_parse(c->recv.buf, c->recv.len, &dm) == false) {
  1788. MG_ERROR(("Unexpected DNS response:"));
  1789. mg_hexdump(c->recv.buf, c->recv.len);
  1790. } else {
  1791. // MG_VERBOSE(("%s %d", dm.name, dm.resolved));
  1792. for (d = *head; d != NULL; d = tmp) {
  1793. tmp = d->next;
  1794. // MG_INFO(("d %p %hu %hu", d, d->txnid, dm.txnid));
  1795. if (dm.txnid != d->txnid) continue;
  1796. if (d->c->is_resolving) {
  1797. if (dm.resolved) {
  1798. dm.addr.port = d->c->rem.port; // Save port
  1799. d->c->rem = dm.addr; // Copy resolved address
  1800. MG_DEBUG(
  1801. ("%lu %s is %M", d->c->id, dm.name, mg_print_ip, &d->c->rem));
  1802. mg_connect_resolved(d->c);
  1803. #if MG_ENABLE_IPV6
  1804. } else if (dm.addr.is_ip6 == false && dm.name[0] != '\0' &&
  1805. c->mgr->use_dns6 == false) {
  1806. struct mg_str x = mg_str(dm.name);
  1807. sendnsreq(d->c, &x, c->mgr->dnstimeout, &c->mgr->dns6, true);
  1808. #endif
  1809. } else {
  1810. mg_error(d->c, "%s DNS lookup failed", dm.name);
  1811. }
  1812. } else {
  1813. MG_ERROR(("%lu already resolved", d->c->id));
  1814. }
  1815. dns_free(head, d);
  1816. resolved = 1;
  1817. }
  1818. }
  1819. if (!resolved) MG_ERROR(("stray DNS reply"));
  1820. c->recv.len = 0;
  1821. } else if (ev == MG_EV_CLOSE) {
  1822. for (d = *head; d != NULL; d = tmp) {
  1823. tmp = d->next;
  1824. mg_error(d->c, "DNS error"); // will remove entry
  1825. }
  1826. }
  1827. }
  1828. static bool dns_send(struct mg_connection *c, const struct mg_str *name,
  1829. unsigned int rtype, uint16_t txnid, uint16_t flags) {
  1830. struct { // RFC-1035 4.1.2
  1831. struct mg_dns_header header;
  1832. uint8_t data[256];
  1833. } pkt;
  1834. size_t i, n;
  1835. memset(&pkt, 0, sizeof(pkt));
  1836. pkt.header.txnid = mg_htons(txnid);
  1837. pkt.header.flags = mg_htons(flags);
  1838. pkt.header.num_questions = mg_htons(1);
  1839. for (i = n = 0; i < sizeof(pkt.data) - 5; i++) {
  1840. if (name->buf[i] == '.' || i >= name->len) {
  1841. pkt.data[n] = (uint8_t) (i - n);
  1842. memcpy(&pkt.data[n + 1], name->buf + n, i - n);
  1843. n = i + 1;
  1844. }
  1845. if (i >= name->len) break;
  1846. }
  1847. memset(&pkt.data[n], 0, 5); // nul, QTYPE, QCLASS
  1848. pkt.data[n + 2] = (uint8_t) rtype; // QTYPE = rtype, only 0-255 supported
  1849. pkt.data[n + 4] = 1; // QCLASS = IN
  1850. n += 5;
  1851. return mg_send(c, &pkt, sizeof(pkt.header) + n);
  1852. }
  1853. static bool mg_dns_send(struct mg_connection *c, const struct mg_str *name,
  1854. uint16_t txnid, bool ipv6) {
  1855. return dns_send(c, name, ipv6 ? MG_DNS_RTYPE_AAAA : MG_DNS_RTYPE_A, txnid,
  1856. 0x100); // RD
  1857. }
  1858. bool mg_dnsc_init(struct mg_mgr *mgr, struct mg_dns *dnsc);
  1859. bool mg_dnsc_init(struct mg_mgr *mgr, struct mg_dns *dnsc) {
  1860. if (dnsc->url == NULL) {
  1861. mg_error(0, "DNS server URL is NULL. Call mg_mgr_init()");
  1862. return false;
  1863. }
  1864. if (dnsc->c == NULL) {
  1865. dnsc->c = mg_connect(mgr, dnsc->url, NULL, NULL);
  1866. if (dnsc->c == NULL) return false;
  1867. dnsc->c->pfn = dns_cb;
  1868. }
  1869. return true;
  1870. }
  1871. static void sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
  1872. struct mg_dns *dnsc, bool ipv6) {
  1873. struct dns_data *d = NULL;
  1874. if (!mg_dnsc_init(c->mgr, dnsc)) {
  1875. mg_error(c, "resolver");
  1876. } else if ((d = (struct dns_data *) mg_calloc(1, sizeof(*d))) == NULL) {
  1877. mg_error(c, "resolve OOM");
  1878. } else {
  1879. struct dns_data *reqs = (struct dns_data *) c->mgr->active_dns_requests;
  1880. uint16_t id;
  1881. mg_random(&id, sizeof(uint16_t));
  1882. if (reqs != NULL) // no seq, no collision for upto 256 in-flight requests
  1883. id = (uint16_t) (reqs->txnid + (id & 0xFF) + 1);
  1884. d->txnid = id;
  1885. d->next = reqs;
  1886. c->mgr->active_dns_requests = d;
  1887. d->expire = mg_millis() + (uint64_t) ms;
  1888. d->c = c;
  1889. c->is_resolving = 1;
  1890. MG_VERBOSE(("%lu resolving %.*s @ %s, txnid %hu", c->id, (int) name->len,
  1891. name->buf, dnsc->url, d->txnid));
  1892. if (!mg_dns_send(dnsc->c, name, d->txnid, ipv6)) {
  1893. mg_error(dnsc->c, "DNS send");
  1894. }
  1895. }
  1896. }
  1897. void mg_resolve(struct mg_connection *c, const char *url) {
  1898. struct mg_str host = mg_url_host(url);
  1899. c->rem.port = mg_htons(mg_url_port(url));
  1900. if (mg_aton(host, &c->rem)) {
  1901. // host is an IP address, do not fire name resolution
  1902. mg_connect_resolved(c);
  1903. } else if (host.len > 6 &&
  1904. strncmp(".local", &host.buf[host.len - 6], 6) == 0) {
  1905. // this is a request for a .local name (mDNS)
  1906. sendmdnsreq(c, &host, 500, c->mgr->mdns, c->mgr->use_dns6); // 500ms tmout
  1907. } else {
  1908. // host is not an IP nor a .local, send DNS resolution request
  1909. struct mg_dns *dns = c->mgr->use_dns6 ? &c->mgr->dns6 : &c->mgr->dns4;
  1910. sendnsreq(c, &host, c->mgr->dnstimeout, dns, c->mgr->use_dns6);
  1911. }
  1912. }
  1913. // Response header length is 10 bytes
  1914. static const uint8_t mdns_answer[] = {
  1915. 0, 1, // 2 bytes - record type, A
  1916. 0, 1, // 2 bytes - address class, INET
  1917. 0, 0, 0, 120, // 4 bytes - TTL
  1918. 0, 4 // 2 bytes - address length
  1919. };
  1920. // A name length is name->len + '.local' + 2 = name->len + 8
  1921. static uint8_t *build_name(struct mg_str *name, uint8_t *p) {
  1922. *p++ = (uint8_t) name->len; // label 1
  1923. memcpy(p, name->buf, name->len), p += name->len;
  1924. *p++ = 5; // label 2
  1925. memcpy(p, "local", 5), p += 5;
  1926. *p++ = 0; // no more labels
  1927. return p;
  1928. }
  1929. void mg_getlocaddr(struct mg_connection *, struct mg_addr *, struct mg_addr *);
  1930. // An A record length is 10 + 4 = 14 bytes
  1931. static uint8_t *build_a_record(struct mg_connection *c, uint8_t *p,
  1932. struct mg_addr *addr) {
  1933. memcpy(p, mdns_answer, sizeof(mdns_answer)), p += sizeof(mdns_answer);
  1934. if (addr != NULL && !addr->is_ip6) {
  1935. memcpy(p, &addr->addr.ip4, 4), p += 4;
  1936. } else {
  1937. #if MG_ENABLE_TCPIP
  1938. memcpy(p, &c->mgr->ifp->ip, 4), p += 4;
  1939. #else
  1940. struct mg_addr loc, to;
  1941. memset(&loc, 0, sizeof(loc));
  1942. to.is_ip6 = false;
  1943. to.port = mg_htons(5353);
  1944. to.addr.ip4 = MG_IPV4(224, 0, 0, 51);
  1945. mg_getlocaddr(c, &to, &loc);
  1946. memcpy(p, &loc.addr.ip4, 4), p += 4;
  1947. #endif
  1948. }
  1949. return p;
  1950. }
  1951. // A srv name length is r->srvcproto.len + '.local' + 2 = r->srvcproto.len + 8
  1952. static uint8_t *build_srv_name(uint8_t *p, struct mg_dnssd_record *r) {
  1953. *p++ = (uint8_t) r->srvcproto.len - 5; // label 1, up to '._tcp'
  1954. memcpy(p, r->srvcproto.buf, r->srvcproto.len), p += r->srvcproto.len;
  1955. p[-5] = 4; // label 2, '_tcp', overwrite '.'
  1956. *p++ = 5; // label 3
  1957. memcpy(p, "local", 5), p += 5;
  1958. *p++ = 0; // no more labels
  1959. return p;
  1960. }
  1961. #if 0
  1962. // TODO(): for listing
  1963. static uint8_t *build_mysrv_name(struct mg_str *name, uint8_t *p,
  1964. struct mg_dnssd_record *r) {
  1965. *p++ = name->len; // label 1
  1966. memcpy(p, name->buf, name->len), p += name->len;
  1967. return build_srv_name(p, r);
  1968. }
  1969. #endif
  1970. // A PTR record length is 10 + name->len + 3 = name->len + 13
  1971. static uint8_t *build_ptr_record(struct mg_str *name, uint8_t *p, uint16_t o) {
  1972. uint16_t offset = mg_htons(o);
  1973. memcpy(p, mdns_answer, sizeof(mdns_answer));
  1974. p[1] = MG_DNS_RTYPE_PTR; // overwrite record type
  1975. p += sizeof(mdns_answer);
  1976. p[-1] = (uint8_t) name->len +
  1977. 3; // overwrite response length, label length + label + offset
  1978. *p++ = (uint8_t) name->len; // response: label 1
  1979. memcpy(p, name->buf, name->len), p += name->len; // copy label
  1980. memcpy(p, &offset, 2);
  1981. *p |= 0xC0, p += 2;
  1982. return p;
  1983. }
  1984. // An SRV record length is 10 + name->len + 9 = name->len + 19
  1985. static uint8_t *build_srv_record(struct mg_str *name, uint8_t *p,
  1986. struct mg_dnssd_record *r, uint16_t o) {
  1987. uint16_t port = mg_htons(r->port);
  1988. uint16_t offset = mg_htons(o);
  1989. memcpy(p, mdns_answer, sizeof(mdns_answer));
  1990. p[1] = MG_DNS_RTYPE_SRV; // overwrite record type
  1991. p += sizeof(mdns_answer);
  1992. p[-1] = (uint8_t) name->len + 9; // overwrite response length (4+2+1+2)
  1993. *p++ = 0; // priority
  1994. *p++ = 0;
  1995. *p++ = 0; // weight
  1996. *p++ = 0;
  1997. memcpy(p, &port, 2), p += 2; // port
  1998. *p++ = (uint8_t) name->len; // label 1
  1999. memcpy(p, name->buf, name->len), p += name->len;
  2000. memcpy(p, &offset, 2);
  2001. *p |= 0xC0, p += 2;
  2002. return p;
  2003. }
  2004. // A TXT record length is r->txt.len (txt contents) + 10
  2005. static uint8_t *build_txt_record(uint8_t *p, struct mg_dnssd_record *r) {
  2006. uint16_t len = mg_htons((uint16_t) r->txt.len);
  2007. memcpy(p, mdns_answer, sizeof(mdns_answer));
  2008. p[1] = MG_DNS_RTYPE_TXT; // overwrite record type
  2009. p += sizeof(mdns_answer);
  2010. memcpy(p - 2, &len, 2); // overwrite response length
  2011. memcpy(p, r->txt.buf, r->txt.len), p += r->txt.len; // copy record verbatim
  2012. return p;
  2013. }
  2014. // Each additional record has a 2-byte field pointing to the name label
  2015. // RFC-6762 16: case-insensitivity --> RFC-1034, 1035
  2016. static void handle_mdns_query(struct mg_connection *c) {
  2017. struct mg_dns_header *qh = (struct mg_dns_header *) c->recv.buf;
  2018. struct mg_dns_rr rr;
  2019. size_t n;
  2020. // Parse first question, offset 12 is header size
  2021. n = mg_dns_parse_rr(c->recv.buf, c->recv.len, 12, true, &rr);
  2022. MG_VERBOSE(("mDNS request parsed, result=%d", (int) n));
  2023. if (n > 0) {
  2024. // RFC-6762 Appendix C, RFC2181 11: m(n + 1-63), max 255 + 0x0
  2025. uint8_t buf[sizeof(struct mg_dns_header) + 256 + sizeof(mdns_answer) + 4];
  2026. struct mg_dns_header *h = (struct mg_dns_header *) buf;
  2027. uint8_t *p = &buf[sizeof(*h)];
  2028. char name[256];
  2029. uint8_t name_len;
  2030. // uint16_t q = mg_ntohs(qh->num_questions);
  2031. struct mg_str defname = mg_str((const char *) c->fn_data);
  2032. struct mg_str *respname;
  2033. struct mg_mdns_req req;
  2034. memset(&req, 0, sizeof(req));
  2035. req.is_unicast = (rr.aclass & MG_BIT(15)) != 0; // QU
  2036. rr.aclass &= (uint16_t) ~MG_BIT(15); // remove "QU" (unicast response)
  2037. qh->num_questions = mg_htons(1); // parser sanity
  2038. mg_dns_parse_name(c->recv.buf, c->recv.len, 12, name, sizeof(name));
  2039. name_len = (uint8_t) strlen(name); // verify it ends in .local
  2040. if (name_len <= 6 || strcmp(".local", &name[name_len - 6]) != 0 ||
  2041. (rr.aclass != 1 && rr.aclass != 0xff))
  2042. return;
  2043. name[name_len -= 6] = '\0'; // remove .local
  2044. MG_VERBOSE(("RR %u %u %s", (unsigned int) rr.atype,
  2045. (unsigned int) rr.aclass, name));
  2046. if (rr.atype == MG_DNS_RTYPE_A) {
  2047. // if we have a name to match, go; otherwise users will match and fill
  2048. // req.r.name and set req.is_resp
  2049. if (c->fn_data != NULL && mg_casecmp((char *) c->fn_data, name) != 0)
  2050. return;
  2051. req.is_resp = (c->fn_data != NULL);
  2052. req.reqname = mg_str_n(name, name_len);
  2053. } else // users have to match the request to something in their db, then
  2054. // fill req.r and set req.is_resp
  2055. if (rr.atype == MG_DNS_RTYPE_PTR) {
  2056. if (strcmp("_services._dns-sd._udp", name) == 0) req.is_listing = true;
  2057. MG_DEBUG(
  2058. ("PTR request for %s", req.is_listing ? "services listing" : name));
  2059. req.reqname = mg_str_n(name, name_len);
  2060. } else if (rr.atype == MG_DNS_RTYPE_SRV || rr.atype == MG_DNS_RTYPE_TXT) {
  2061. MG_DEBUG(("%s request for %s",
  2062. rr.atype == MG_DNS_RTYPE_SRV ? "SRV" : "TXT", name));
  2063. // if possible, check it starts with our name, users will check it ends
  2064. // in a service name they handle
  2065. if (c->fn_data != NULL) {
  2066. if (mg_strcasecmp(defname, mg_str_n(name, defname.len)) != 0 ||
  2067. name[defname.len] != '.')
  2068. return;
  2069. req.reqname =
  2070. mg_str_n(name + defname.len + 1, name_len - defname.len - 1);
  2071. MG_DEBUG(
  2072. ("That's us, handing %.*s", req.reqname.len, req.reqname.buf));
  2073. } else {
  2074. req.reqname = mg_str_n(name, name_len);
  2075. }
  2076. } else { // unhandled record
  2077. return;
  2078. }
  2079. req.rr = &rr;
  2080. mg_call(c, MG_EV_MDNS_REQ, &req);
  2081. if (!req.is_resp) return;
  2082. respname = req.respname.buf != NULL ? &req.respname : &defname;
  2083. memset(h, 0, sizeof(*h)); // clear header
  2084. h->txnid = req.is_unicast ? qh->txnid : 0; // RFC-6762 18.1
  2085. h->num_answers = mg_htons(1); // RFC-6762 6: 0 questions, 1 Answer
  2086. h->flags = mg_htons(0x8400); // Authoritative response
  2087. if (req.is_listing) {
  2088. // TODO(): RFC-6762 6: each responder SHOULD delay its response by a
  2089. // random amount of time selected with uniform random distribution in the
  2090. // range 20-120 ms.
  2091. // TODO():
  2092. return;
  2093. } else if (rr.atype == MG_DNS_RTYPE_PTR) { // serve PTR + SRV + TXT + A
  2094. // TODO(): RFC-6762 6: each responder SHOULD delay its response by a
  2095. // random amount of time selected with uniform random distribution in the
  2096. // range 20-120 ms. Response to PTR is local_name._myservice._tcp.local
  2097. uint8_t *o = p, *aux;
  2098. uint16_t offset;
  2099. if (respname->buf == NULL || respname->len == 0) return;
  2100. if ((sizeof(*h) + req.r->srvcproto.len + 8 + respname->len + 13 + 2 +
  2101. respname->len + 19 + 2 + req.r->txt.len + 10 + 2 + 14) >
  2102. sizeof(buf)) // srv name + PTR + 2 + SRV + 2 + TXT + 2 + A
  2103. return;
  2104. h->num_other_prs = mg_htons(3); // 3 additional records
  2105. p = build_srv_name(p, req.r);
  2106. aux = build_ptr_record(respname, p, (uint16_t) (o - buf));
  2107. o = p + sizeof(mdns_answer); // point to PTR response (full srvc name)
  2108. offset = mg_htons((uint16_t) (o - buf));
  2109. o = p - 7; // point to '.local' label (\x05local\x00)
  2110. p = aux;
  2111. memcpy(p, &offset, 2); // point to full srvc name, in record
  2112. *p |= 0xC0, p += 2;
  2113. aux = p;
  2114. p = build_srv_record(respname, p, req.r, (uint16_t) (o - buf));
  2115. o = aux + sizeof(mdns_answer) + 6; // point to target in SRV
  2116. memcpy(p, &offset, 2); // point to full srvc name, in record
  2117. *p |= 0xC0, p += 2;
  2118. p = build_txt_record(p, req.r);
  2119. offset = mg_htons((uint16_t) (o - buf));
  2120. memcpy(p, &offset, 2); // point to target name, in record
  2121. *p |= 0xC0, p += 2;
  2122. p = build_a_record(c, p, req.addr);
  2123. } else if (rr.atype == MG_DNS_RTYPE_TXT) {
  2124. if ((sizeof(*h) + req.r->srvcproto.len + 8 + req.r->txt.len + 10) >
  2125. sizeof(buf)) // srv name + TXT
  2126. return;
  2127. p = build_srv_name(p, req.r);
  2128. p = build_txt_record(p, req.r);
  2129. } else if (rr.atype == MG_DNS_RTYPE_SRV) { // serve SRV + A
  2130. uint8_t *o, *aux;
  2131. uint16_t offset;
  2132. if (respname->buf == NULL || respname->len == 0) return;
  2133. if ((sizeof(*h) + req.r->srvcproto.len + 8 + respname->len + 19 + 2 +
  2134. 14) > sizeof(buf)) // srv name + SRV + 2 + A
  2135. return;
  2136. h->num_other_prs = mg_htons(1); // 1 additional record
  2137. p = build_srv_name(p, req.r);
  2138. o = p - 7; // point to '.local' label (\x05local\x00)
  2139. aux = p;
  2140. p = build_srv_record(respname, p, req.r, (uint16_t) (o - buf));
  2141. o = aux + sizeof(mdns_answer) + 6; // point to target in SRV
  2142. offset = mg_htons((uint16_t) (o - buf));
  2143. memcpy(p, &offset, 2); // point to target name, in record
  2144. *p |= 0xC0, p += 2;
  2145. p = build_a_record(c, p, req.addr);
  2146. } else { // A requested
  2147. // RFC-6762 6: 0 Auth, 0 Additional RRs
  2148. if (respname->buf == NULL || respname->len == 0) return;
  2149. if ((sizeof(*h) + respname->len + 8 + 14) > sizeof(buf)) // name + A
  2150. return;
  2151. p = build_name(respname, p);
  2152. p = build_a_record(c, p, req.addr);
  2153. }
  2154. if (!req.is_unicast) mg_multicast_restore(c, (uint8_t *) &c->loc);
  2155. mg_send(c, buf, (size_t) (p - buf)); // And send it!
  2156. MG_DEBUG(("%M > %M", mg_print_ip_port, &c->loc, mg_print_ip_port, &c->rem));
  2157. MG_DEBUG(("mDNS %s response sent", req.is_unicast ? "unicast" : "mcast"));
  2158. }
  2159. }
  2160. static size_t srvtoname(char *svc) {
  2161. char *dot = strchr(svc, '.');
  2162. if (dot == NULL) return 0;
  2163. *dot = '\0';
  2164. return (size_t) (dot - svc);
  2165. }
  2166. #define MG_MAX_MDNS_RECORDS 8
  2167. // Condense one useful mDNS/DNS-SD chain from a response datagram into a single
  2168. // MG_EV_MDNS_RESP event. A/AAAA as the first supported record are terminal
  2169. // address answers (AAAA currently ignored). For PTR/SRV/TXT, subsequent
  2170. // records are attached only when their label matches the service instance, or
  2171. // the SRV target for address records.
  2172. // Some devices send SRV/TXT as extra Answer RRs instead of Additional RRs, so
  2173. // both sections are parsed as one chain.
  2174. static void handle_mdns_response(struct mg_connection *c) {
  2175. struct mg_dns_header *rh = (struct mg_dns_header *) c->recv.buf;
  2176. struct mg_dns_rr rr, rr_[5]; // A, PTR, SRV, TXT, AAAA, in that order
  2177. struct mg_mdns_resp resp;
  2178. size_t n, i, num, answers, roff_[5], roff = 12; // offset 12 is header size
  2179. // RFC-6762 Appendix C, RFC2181 11: m(n + 1-63), max 255 + 0x0
  2180. char name[256], srvcproto[256], instance[256], host[256];
  2181. uint16_t atype = 0;
  2182. answers = mg_ntohs(rh->num_answers);
  2183. num = answers + mg_ntohs(rh->num_other_prs);
  2184. if (answers == 0) return;
  2185. MG_VERBOSE(("mDNS response: %u answer, %u additional", (unsigned) answers,
  2186. (unsigned) (num - answers)));
  2187. if (num > MG_MAX_MDNS_RECORDS) {
  2188. num = MG_MAX_MDNS_RECORDS;
  2189. MG_DEBUG(("ignoring > %u records", MG_MAX_MDNS_RECORDS));
  2190. }
  2191. memset(roff_, 0, sizeof(roff_));
  2192. memset(&rr_, 0, sizeof(rr_));
  2193. memset(&resp, 0, sizeof(resp));
  2194. instance[0] = host[0] = '\0';
  2195. for (i = 0; i < num; i++) { // First Answer RR is primary; the rest must match it
  2196. n = mg_dns_parse_rr(c->recv.buf, c->recv.len, roff, false, &rr);
  2197. MG_VERBOSE(("mDNS record parsed, result=%u", n));
  2198. if (n == 0) return;
  2199. if (mg_dns_parse_name(c->recv.buf, c->recv.len, roff, name, sizeof(name)) == 0) return;
  2200. MG_VERBOSE(("RR %u %u %s", (unsigned int) rr.atype, (unsigned int) rr.aclass, name));
  2201. if (rr.alen == 4 && rr.atype == MG_DNS_RTYPE_A && (rr.aclass & 0x7FFF) == 1 &&
  2202. (i == 0 || (host[0] != '\0' && strcmp(name, host) == 0) ||
  2203. (host[0] == '\0' && instance[0] != '\0' && strcmp(name, instance) == 0))) {
  2204. if (rr_[0].atype != 0) break;
  2205. if (i == 0) atype = rr.atype;
  2206. resp.name = mg_str(name);
  2207. resp.addr.is_ip6 = false;
  2208. memcpy(resp.addr.addr.ip, c->recv.buf + roff + n - 4, 4);
  2209. MG_VERBOSE(("A record"));
  2210. roff_[0] = roff, rr_[0] = rr;
  2211. if (atype == MG_DNS_RTYPE_A) break;
  2212. } else if (rr.alen == 16 && rr.atype == MG_DNS_RTYPE_AAAA && (rr.aclass & 0x7FFF) == 1 &&
  2213. (i == 0 || (host[0] != '\0' && strcmp(name, host) == 0) ||
  2214. (host[0] == '\0' && instance[0] != '\0' && strcmp(name, instance) == 0))) {
  2215. # if 0
  2216. if (rr_[4].atype != 0) break;
  2217. resp.addr.is_ip6 = true;
  2218. if (i == 0) atype = rr.atype;
  2219. resp.name = mg_str(name);
  2220. memcpy(resp.addr.addr.ip, c->recv.buf + roff + n - 16, 16);
  2221. MG_VERBOSE(("AAAA record"));
  2222. roff_[4] = roff, rr_[4] = rr;
  2223. if (atype == MG_DNS_RTYPE_AAAA) break;
  2224. #else
  2225. MG_VERBOSE(("ignored AAAA record"));
  2226. #endif
  2227. } else if (rr.atype == MG_DNS_RTYPE_PTR && (rr.aclass & 0x7FFF) == 1 && i == 0) {
  2228. if (rr_[1].atype != 0) break;
  2229. atype = rr.atype;
  2230. if (mg_dns_parse_name(c->recv.buf, c->recv.len, roff + rr.nlen + 10,
  2231. instance, sizeof(instance)) == 0) return;
  2232. MG_VERBOSE(("PTR record"));
  2233. roff_[1] = roff, rr_[1] = rr;
  2234. } else if (rr.atype == MG_DNS_RTYPE_SRV && rr.alen >= 6 && (rr.aclass & 0x7FFF) == 1 &&
  2235. (i == 0 || (instance[0] != '\0' && strcmp(name, instance) == 0))) {
  2236. if (rr_[2].atype != 0) break;
  2237. if (i == 0) atype = rr.atype;
  2238. resp.sd.port = MG_LOAD_BE16(c->recv.buf + roff + rr.nlen + 14);
  2239. resp.addr.port = mg_htons(resp.sd.port);
  2240. if (instance[0] == '\0') mg_snprintf(instance, sizeof(instance), "%s", name);
  2241. if (mg_dns_parse_name(c->recv.buf, c->recv.len, roff + rr.nlen + 16,
  2242. host, sizeof(host)) == 0) return;
  2243. MG_VERBOSE(("SRV record"));
  2244. roff_[2] = roff, rr_[2] = rr;
  2245. } else if (rr.atype == MG_DNS_RTYPE_TXT && (rr.aclass & 0x7FFF) == 1 &&
  2246. (i == 0 || (instance[0] != '\0' && strcmp(name, instance) == 0))) {
  2247. if (rr_[3].atype != 0) break;
  2248. if (i == 0) atype = rr.atype;
  2249. if (instance[0] == '\0') mg_snprintf(instance, sizeof(instance), "%s", name);
  2250. resp.sd.txt = mg_str_n((char *) c->recv.buf + roff + rr.nlen + 10, rr.alen);
  2251. MG_VERBOSE(("TXT record"));
  2252. roff_[3] = roff, rr_[3] = rr;
  2253. }
  2254. roff += n;
  2255. if (i == 0 && atype == 0) return;
  2256. }
  2257. if (atype == MG_DNS_RTYPE_A) {
  2258. resp.rr = &rr_[0];
  2259. MG_DEBUG(("A response from %s = %M", name, mg_print_ip, &resp.addr));
  2260. #if 0
  2261. } else if (atype == MG_DNS_RTYPE_AAAA) {
  2262. resp.rr = &rr_[4];
  2263. MG_DEBUG(("AAAA response from %s = %M", name, mg_print_ip6, resp.addr.addr.ip));
  2264. #endif
  2265. } else if (atype == MG_DNS_RTYPE_PTR) {
  2266. size_t len;
  2267. resp.rr = &rr_[1];
  2268. if (mg_dns_parse_name(c->recv.buf, c->recv.len, roff_[1], srvcproto,
  2269. sizeof(srvcproto)) == 0) return;
  2270. len = strlen(srvcproto);
  2271. if (len <= 6) return;
  2272. resp.sd.srvcproto = mg_str_n(srvcproto, len - 6); // remove .local
  2273. if (host[0] != '\0') {
  2274. resp.name = mg_str(host);
  2275. } else if (rr_[0].atype == 0) {
  2276. mg_snprintf(name, sizeof(name), "%s", instance);
  2277. resp.name = mg_str_n(name, srvtoname(name));
  2278. } else {
  2279. if (mg_dns_parse_name(c->recv.buf, c->recv.len, roff_[0], name,
  2280. sizeof(name)) == 0) return;
  2281. resp.name = mg_str(name);
  2282. }
  2283. MG_DEBUG(("PTR response for %s from %s", srvcproto, name));
  2284. } else if (atype == MG_DNS_RTYPE_SRV || atype == MG_DNS_RTYPE_TXT) {
  2285. size_t len, name_len;
  2286. resp.rr = atype == MG_DNS_RTYPE_SRV ? &rr_[2] : &rr_[3];
  2287. if (mg_dns_parse_name(c->recv.buf, c->recv.len,
  2288. atype == MG_DNS_RTYPE_SRV ? roff_[2] : roff_[3],
  2289. srvcproto, sizeof(srvcproto)) == 0)
  2290. return;
  2291. len = strlen(srvcproto);
  2292. name_len = srvtoname(srvcproto);
  2293. if (name_len == 0 || len <= name_len + 7) return; // remove .local
  2294. resp.sd.srvcproto = mg_str_n(srvcproto + name_len + 1, len - name_len - 7);
  2295. resp.name = mg_str_n(srvcproto, name_len);
  2296. MG_DEBUG(("%s response for %s from %s", atype == MG_DNS_RTYPE_SRV ? "SRV" : "TXT", srvcproto, name));
  2297. } else {
  2298. return;
  2299. }
  2300. mg_call(c, MG_EV_MDNS_RESP, &resp);
  2301. }
  2302. static void handle_mdns_record(struct mg_connection *c) {
  2303. struct mg_dns_header *h = (struct mg_dns_header *) c->recv.buf;
  2304. if (c->recv.len <= 12) return;
  2305. if ((h->flags & mg_htons(0xF800)) == 0) {
  2306. // flags -> !resp, opcode=0 => query; ignore other opcodes
  2307. handle_mdns_query(c);
  2308. } else if ((h->flags & mg_htons(0xF800)) == mg_htons(0x8000)) {
  2309. // flags -> resp, opcode=0 => response; ignore other opcodes
  2310. handle_mdns_response(c);
  2311. }
  2312. }
  2313. static void mdns_cb(struct mg_connection *c, int ev, void *ev_data) {
  2314. struct mdns_data *d, *tmp;
  2315. struct mdns_data **head = (struct mdns_data **) &c->mgr->active_mdns_requests;
  2316. // mDNS resolver
  2317. if (ev == MG_EV_POLL) {
  2318. uint64_t now = *(uint64_t *) ev_data;
  2319. for (d = *head; d != NULL; d = tmp) {
  2320. tmp = d->next;
  2321. // MG_DEBUG(("%lu %lu mdns poll", d->expire, now));
  2322. if (now > d->expire) mg_error(d->c, "mDNS timeout"); // will remove entry
  2323. }
  2324. } else if (ev == MG_EV_CLOSE) {
  2325. for (d = *head; d != NULL; d = tmp) {
  2326. tmp = d->next;
  2327. mg_error(d->c, "mDNS listener error"); // this will remove entry
  2328. }
  2329. } else if (ev == MG_EV_MDNS_RESP) {
  2330. struct mg_mdns_resp *resp = (struct mg_mdns_resp *) ev_data;
  2331. if (resp->rr->atype == MG_DNS_RTYPE_A) {
  2332. for (d = *head; d != NULL; d = tmp) {
  2333. tmp = d->next;
  2334. if (mg_strcasecmp(d->name, resp->name) != 0) continue;
  2335. if (d->c->is_resolving) {
  2336. resp->addr.port = d->c->rem.port; // Save port
  2337. d->c->rem = resp->addr; // Copy resolved address
  2338. MG_DEBUG(("%lu %.*s is %M", d->c->id, resp->name.len, resp->name.buf,
  2339. mg_print_ip, &d->c->rem));
  2340. mg_connect_resolved(d->c);
  2341. } else {
  2342. // this should not happen, unless above does not clear c->is_resolving
  2343. MG_ERROR(("%lu already resolved", d->c->id));
  2344. }
  2345. mdns_free(head, d);
  2346. }
  2347. }
  2348. } else if (ev == MG_EV_READ) {
  2349. // generic mDNS[-SD] handling
  2350. handle_mdns_record(c); // this will call us back with MG_EV_MDNS_RESP
  2351. mg_iobuf_del(&c->recv, 0, c->recv.len);
  2352. }
  2353. (void) ev_data;
  2354. }
  2355. void mg_multicast_add(struct mg_connection *c, char *ip);
  2356. struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn,
  2357. void *fn_data) {
  2358. struct mg_connection *c =
  2359. mg_listen(mgr, "udp://224.0.0.251:5353", fn, fn_data);
  2360. if (c == NULL) return NULL;
  2361. c->mgr->mdns = c; // Add mDNS entry to enable resolver to use it
  2362. c->pfn = mdns_cb, c->pfn_data = fn_data;
  2363. mg_multicast_add(c, (char *) "224.0.0.251");
  2364. return c;
  2365. }
  2366. static bool mdns_query(struct mg_connection *c, struct mg_str *name,
  2367. unsigned int rtype) {
  2368. mg_multicast_restore(c, (uint8_t *) &c->loc);
  2369. return dns_send(c, name, rtype, 0, 0); // RFC-6762 18.1 id = 0, 18.6 RD = 0
  2370. }
  2371. bool mg_mdns_query(struct mg_connection *c, const char *name,
  2372. unsigned int rtype) {
  2373. struct mg_str name_;
  2374. name_.buf = (char *) name, name_.len = strlen(name);
  2375. return mdns_query(c, &name_, rtype);
  2376. }
  2377. static void sendmdnsreq(struct mg_connection *c, struct mg_str *name, int ms,
  2378. struct mg_connection *mdnsc, bool ipv6) {
  2379. struct mdns_data *d = NULL;
  2380. if (mdnsc == NULL) {
  2381. mg_error(c, "no mDNS listener, see mg_mdns_listen()");
  2382. } else if ((d = (struct mdns_data *) mg_calloc(1, sizeof(*d))) == NULL) {
  2383. mg_error(c, "resolve OOM");
  2384. } else {
  2385. struct mdns_data *reqs = (struct mdns_data *) c->mgr->active_mdns_requests;
  2386. d->next = reqs;
  2387. c->mgr->active_mdns_requests = d;
  2388. d->expire = mg_millis() + (uint64_t) ms;
  2389. d->name = mg_strdup(*name);
  2390. d->c = c;
  2391. c->is_resolving = 1;
  2392. MG_VERBOSE(
  2393. ("%lu resolving %.*s via mDNS", c->id, (int) name->len, name->buf));
  2394. if (!mdns_query(mdnsc, name, MG_DNS_RTYPE_A)) {
  2395. mg_error(c, "mDNS send"); // will remove newly created entry
  2396. }
  2397. }
  2398. (void) ipv6;
  2399. }
  2400. #ifdef MG_ENABLE_LINES
  2401. #line 1 "src/event.c"
  2402. #endif
  2403. void mg_call(struct mg_connection *c, int ev, void *ev_data) {
  2404. #if MG_ENABLE_PROFILE
  2405. const char *names[] = {
  2406. "EV_ERROR", "EV_OPEN", "EV_POLL", "EV_RESOLVE",
  2407. "EV_CONNECT", "EV_ACCEPT", "EV_TLS_HS", "EV_READ",
  2408. "EV_WRITE", "EV_CLOSE", "EV_HTTP_MSG", "EV_HTTP_CHUNK",
  2409. "EV_WS_OPEN", "EV_WS_MSG", "EV_WS_CTL", "EV_MQTT_CMD",
  2410. "EV_MQTT_MSG", "EV_MQTT_OPEN", "EV_SNTP_TIME", "EV_USER"};
  2411. if (ev != MG_EV_POLL && ev < (int) (sizeof(names) / sizeof(names[0]))) {
  2412. MG_PROF_ADD(c, names[ev]);
  2413. }
  2414. #endif
  2415. // Fire protocol handler first, user handler second. See #2559
  2416. if (c->pfn != NULL) c->pfn(c, ev, ev_data);
  2417. if (c->fn != NULL) c->fn(c, ev, ev_data);
  2418. }
  2419. void mg_error(struct mg_connection *c, const char *fmt, ...) {
  2420. char buf[64];
  2421. va_list ap;
  2422. va_start(ap, fmt);
  2423. mg_vsnprintf(buf, sizeof(buf), fmt, &ap);
  2424. va_end(ap);
  2425. MG_ERROR(("%lu %ld %s", c->id, c->fd, buf));
  2426. c->is_closing = 1; // Set is_closing before sending MG_EV_CALL
  2427. mg_call(c, MG_EV_ERROR, buf); // Let user handler override it
  2428. }
  2429. #ifdef MG_ENABLE_LINES
  2430. #line 1 "src/flash.c"
  2431. #endif
  2432. #ifdef MG_OTA_PUBLIC_KEY
  2433. #endif
  2434. #if MG_OTA != MG_OTA_NONE && MG_OTA != MG_OTA_CUSTOM
  2435. static char *s_addr; // Current address to write to
  2436. static size_t s_size; // Firmware size to flash. In-progress indicator
  2437. static uint32_t s_crc32; // Firmware checksum
  2438. bool mg_ota_flash_begin(size_t new_firmware_size, struct mg_flash *flash) {
  2439. bool ok = false;
  2440. if (s_size) {
  2441. MG_ERROR(("OTA already in progress. Call mg_ota_end()"));
  2442. } else {
  2443. size_t half = flash->size / 2;
  2444. s_crc32 = 0;
  2445. s_addr = (char *) flash->start + half;
  2446. MG_DEBUG(("FW %lu bytes, max %lu", new_firmware_size, half));
  2447. if (new_firmware_size < half) {
  2448. ok = true;
  2449. s_size = new_firmware_size;
  2450. MG_INFO(("Starting OTA, firmware size %lu", s_size));
  2451. } else {
  2452. MG_ERROR(("Firmware %lu is too big to fit %lu", new_firmware_size, half - flash->align));
  2453. }
  2454. }
  2455. return ok;
  2456. }
  2457. bool mg_ota_flash_write(const void *buf, size_t len, struct mg_flash *flash) {
  2458. bool ok = false;
  2459. if (s_size == 0) {
  2460. MG_ERROR(("OTA is not started, call mg_ota_begin()"));
  2461. } else if (s_addr + MG_ROUND_UP(len, flash->align) >
  2462. (char *) flash->start + flash->size) {
  2463. MG_ERROR(("Flash overflow: attempting to write past the flash boundary"));
  2464. } else {
  2465. size_t len_aligned_down = MG_ROUND_DOWN(len, flash->align);
  2466. if (len_aligned_down) ok = flash->write_fn(s_addr, buf, len_aligned_down);
  2467. if (len_aligned_down < len) {
  2468. size_t left = len - len_aligned_down;
  2469. char tmp[flash->align];
  2470. memset(tmp, 0xff, sizeof(tmp));
  2471. memcpy(tmp, (char *) buf + len_aligned_down, left);
  2472. ok = flash->write_fn(s_addr + len_aligned_down, tmp, sizeof(tmp));
  2473. }
  2474. s_crc32 = mg_crc32(s_crc32, (char *) buf, len); // Update CRC
  2475. MG_DEBUG(("%#x %p %lu -> %d", s_addr - len, buf, len, ok));
  2476. s_addr += len;
  2477. }
  2478. return ok;
  2479. }
  2480. bool mg_ota_flash_end(struct mg_flash *flash) {
  2481. char *base = (char *) flash->start + flash->size / 2;
  2482. bool ok = false;
  2483. int prev_state = MG_OTA_STATE_GET();
  2484. if (s_size) {
  2485. size_t size = (size_t) (s_addr - base);
  2486. uint32_t crc32 = mg_crc32(0, base, s_size);
  2487. if (size == s_size && crc32 == s_crc32) ok = true;
  2488. MG_DEBUG(("CRC: %x/%x, size: %lu/%lu, status: %s", s_crc32, crc32, s_size,
  2489. size, ok ? "ok" : "fail"));
  2490. #ifdef MG_OTA_PUBLIC_KEY
  2491. if (ok) {
  2492. bool signed_fw = s_size > 68 &&
  2493. memcmp((uint8_t *) base + s_size - 4, "MGSG", 4) == 0;
  2494. if (signed_fw) {
  2495. static const uint8_t s_pubkey[] = MG_OTA_PUBLIC_KEY;
  2496. uint8_t hash[32];
  2497. size_t fw_size = s_size - 68; // strip 64-byte sig + 4-byte magic
  2498. mg_sha256(hash, (uint8_t *) base, fw_size);
  2499. ok = mg_uecc_verify(s_pubkey, hash, sizeof(hash),
  2500. (uint8_t *) base + fw_size,
  2501. mg_uecc_secp256r1()) == 1;
  2502. MG_INFO(("Signature: %s", ok ? "ok" : "fail"));
  2503. } else {
  2504. ok = false;
  2505. MG_ERROR(("Unsigned firmware rejected"));
  2506. }
  2507. }
  2508. #endif
  2509. s_size = 0;
  2510. if (ok) MG_OTA_STATE_SET(MG_OTA_TESTING);
  2511. if (ok) ok = flash->swap_fn();
  2512. if (!ok) MG_OTA_STATE_SET(prev_state); // undo state in case of failure
  2513. }
  2514. MG_INFO(("Finishing OTA: %s", ok ? "ok" : "fail"));
  2515. return ok;
  2516. }
  2517. #endif
  2518. #ifdef MG_ENABLE_LINES
  2519. #line 1 "src/fmt.c"
  2520. #endif
  2521. static bool is_digit(int c) {
  2522. return c >= '0' && c <= '9';
  2523. }
  2524. static int addexp(char *buf, int e, int sign) {
  2525. int n = 0;
  2526. buf[n++] = 'e';
  2527. buf[n++] = (char) sign;
  2528. if (e > 400) return 0;
  2529. if (e < 10) buf[n++] = '0';
  2530. if (e >= 100) buf[n++] = (char) (e / 100 + '0'), e -= 100 * (e / 100);
  2531. if (e >= 10) buf[n++] = (char) (e / 10 + '0'), e -= 10 * (e / 10);
  2532. buf[n++] = (char) (e + '0');
  2533. return n;
  2534. }
  2535. static int xisinf(double x) {
  2536. union {
  2537. double f;
  2538. uint64_t u;
  2539. } ieee754;
  2540. ieee754.f = x;
  2541. return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
  2542. ((unsigned) ieee754.u == 0);
  2543. }
  2544. static int xisnan(double x) {
  2545. union {
  2546. double f;
  2547. uint64_t u;
  2548. } ieee754;
  2549. ieee754.f = x;
  2550. return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) +
  2551. ((unsigned) ieee754.u != 0) >
  2552. 0x7ff00000;
  2553. }
  2554. static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) {
  2555. char buf[40];
  2556. int i, s = 0, n = 0, e = 0;
  2557. double t, mul, saved;
  2558. if (d == 0.0) return mg_snprintf(dst, dstlen, "%s", "0");
  2559. if (xisinf(d)) return mg_snprintf(dst, dstlen, "%s", d > 0 ? "inf" : "-inf");
  2560. if (xisnan(d)) return mg_snprintf(dst, dstlen, "%s", "nan");
  2561. if (d < 0.0) d = -d, buf[s++] = '-';
  2562. // Round
  2563. saved = d;
  2564. if (tz) {
  2565. mul = 1.0;
  2566. while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0;
  2567. } else {
  2568. mul = 0.1;
  2569. }
  2570. while (d <= 1.0 && d / mul <= 1.0) mul /= 10.0;
  2571. for (i = 0, t = mul * 5; i < width; i++) t /= 10.0;
  2572. d += t;
  2573. // Calculate exponent, and 'mul' for scientific representation
  2574. mul = 1.0;
  2575. while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0, e++;
  2576. while (d < 1.0 && d / mul < 1.0) mul /= 10.0, e--;
  2577. // printf(" --> %g %d %g %g\n", saved, e, t, mul);
  2578. if (tz && (e >= width || e <= -width) && width > 1) {
  2579. char exp[6];
  2580. int ne;
  2581. n = (int) mg_dtoa(buf + s, sizeof(buf) - (size_t) s, saved / mul, width, tz);
  2582. // printf(" --> %.*g %d [%.*s]\n", 10, d / t, e, n, buf);
  2583. ne = addexp(exp, e < 0 ? -e : e, e < 0 ? '-' : '+');
  2584. if (s + n + ne >= (int) sizeof(buf))
  2585. n = (int) sizeof(buf) - s - ne - 1;
  2586. memcpy(buf + s + n, exp, (size_t) ne);
  2587. n += ne;
  2588. return mg_snprintf(dst, dstlen, "%.*s", s + n, buf);
  2589. } else {
  2590. int targ_width = width;
  2591. for (i = 0, t = mul; t >= 1.0 && s + n < (int) sizeof(buf); i++) {
  2592. int ch = (int) (d / t);
  2593. if (n > 0 || ch > 0) buf[s + n++] = (char) (ch + '0');
  2594. d -= ch * t;
  2595. t /= 10.0;
  2596. }
  2597. // printf(" --> [%g] -> %g %g (%d) [%.*s]\n", saved, d, t, n, s + n, buf);
  2598. if (n == 0) buf[s++] = '0';
  2599. while (t >= 1.0 && n + s < (int) sizeof(buf)) buf[n++] = '0', t /= 10.0;
  2600. if (s + n < (int) sizeof(buf)) buf[n + s++] = '.';
  2601. // printf(" 1--> [%g] -> [%.*s]\n", saved, s + n, buf);
  2602. if (!tz && n > 0) targ_width = width + n;
  2603. for (i = 0, t = 0.1; s + n < (int) sizeof(buf) && n < targ_width; i++) {
  2604. int ch = (int) (d / t);
  2605. buf[s + n++] = (char) (ch + '0');
  2606. d -= ch * t;
  2607. t /= 10.0;
  2608. }
  2609. }
  2610. while (tz && n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeroes
  2611. if (tz && n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
  2612. n += s;
  2613. if (n >= (int) sizeof(buf)) n = (int) sizeof(buf) - 1;
  2614. buf[n] = '\0';
  2615. return mg_snprintf(dst, dstlen, "%s", buf);
  2616. }
  2617. static size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) {
  2618. const char *letters = "0123456789abcdef";
  2619. uint64_t v = (uint64_t) val;
  2620. size_t s = 0, n, i;
  2621. if (is_signed && val < 0) buf[s++] = '-', v = (uint64_t) (-val);
  2622. // This loop prints a number in reverse order. I guess this is because we
  2623. // write numbers from right to left: least significant digit comes last.
  2624. // Maybe because we use Arabic numbers, and Arabs write RTL?
  2625. if (is_hex) {
  2626. for (n = 0; v; v >>= 4) buf[s + n++] = letters[v & 15];
  2627. } else {
  2628. for (n = 0; v; v /= 10) buf[s + n++] = letters[v % 10];
  2629. }
  2630. // Reverse a string
  2631. for (i = 0; i < n / 2; i++) {
  2632. char t = buf[s + i];
  2633. buf[s + i] = buf[s + n - i - 1], buf[s + n - i - 1] = t;
  2634. }
  2635. if (val == 0) buf[n++] = '0'; // Handle special case
  2636. return n + s;
  2637. }
  2638. static size_t scpy(void (*out)(char, void *), void *ptr, char *buf,
  2639. size_t len) {
  2640. size_t i = 0;
  2641. while (i < len && buf[i] != '\0') out(buf[i++], ptr);
  2642. return i;
  2643. }
  2644. size_t mg_xprintf(void (*out)(char, void *), void *ptr, const char *fmt, ...) {
  2645. size_t len = 0;
  2646. va_list ap;
  2647. va_start(ap, fmt);
  2648. len = mg_vxprintf(out, ptr, fmt, &ap);
  2649. va_end(ap);
  2650. return len;
  2651. }
  2652. size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
  2653. va_list *ap) {
  2654. size_t i = 0, n = 0;
  2655. while (fmt[i] != '\0') {
  2656. if (fmt[i] == '%') {
  2657. size_t j, k, x = 0, is_long = 0, w = 0 /* width */, pr = ~0U /* prec */;
  2658. char pad = ' ', minus = 0, c = fmt[++i];
  2659. if (c == '#') x++, c = fmt[++i];
  2660. if (c == '-') minus++, c = fmt[++i];
  2661. if (c == '0') pad = '0', c = fmt[++i];
  2662. while (is_digit(c)) w *= 10, w += (size_t) (c - '0'), c = fmt[++i];
  2663. if (c == '.') {
  2664. c = fmt[++i];
  2665. if (c == '*') {
  2666. pr = (size_t) va_arg(*ap, int);
  2667. c = fmt[++i];
  2668. } else {
  2669. pr = 0;
  2670. while (is_digit(c)) pr *= 10, pr += (size_t) (c - '0'), c = fmt[++i];
  2671. }
  2672. }
  2673. while (c == 'h') c = fmt[++i]; // Treat h and hh as int
  2674. if (c == 'l') {
  2675. is_long++, c = fmt[++i];
  2676. if (c == 'l') is_long++, c = fmt[++i];
  2677. }
  2678. if (c == 'z') is_long = 1, c = fmt[++i];
  2679. if (c == 'p') x = 1, is_long = 1;
  2680. if (c == 'd' || c == 'u' || c == 'x' || c == 'X' || c == 'p' ||
  2681. c == 'g' || c == 'f') {
  2682. bool s = (c == 'd'), h = (c == 'x' || c == 'X' || c == 'p');
  2683. char tmp[40];
  2684. size_t xl = x ? 2 : 0;
  2685. if (c == 'g' || c == 'f') {
  2686. double v = va_arg(*ap, double);
  2687. if (pr == ~0U) pr = 6;
  2688. k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr, c == 'g');
  2689. } else if (is_long == 2) {
  2690. int64_t v = va_arg(*ap, int64_t);
  2691. k = mg_lld(tmp, v, s, h);
  2692. } else if (is_long == 1) {
  2693. long v = va_arg(*ap, long);
  2694. k = mg_lld(tmp, s ? (int64_t) v : (int64_t) (unsigned long) v, s, h);
  2695. } else {
  2696. int v = va_arg(*ap, int);
  2697. k = mg_lld(tmp, s ? (int64_t) v : (int64_t) (unsigned) v, s, h);
  2698. }
  2699. for (j = 0; j < xl && w > 0; j++) w--;
  2700. for (j = 0; pad == ' ' && !minus && k < w && j + k < w; j++)
  2701. n += scpy(out, param, &pad, 1);
  2702. n += scpy(out, param, (char *) "0x", xl);
  2703. for (j = 0; pad == '0' && k < w && j + k < w; j++)
  2704. n += scpy(out, param, &pad, 1);
  2705. n += scpy(out, param, tmp, k);
  2706. for (j = 0; pad == ' ' && minus && k < w && j + k < w; j++)
  2707. n += scpy(out, param, &pad, 1);
  2708. } else if (c == 'm' || c == 'M') {
  2709. mg_pm_t f = va_arg(*ap, mg_pm_t);
  2710. if (c == 'm') out('"', param);
  2711. n += f(out, param, ap);
  2712. if (c == 'm') n += 2, out('"', param);
  2713. } else if (c == 'c') {
  2714. int ch = va_arg(*ap, int);
  2715. out((char) ch, param);
  2716. n++;
  2717. } else if (c == 's') {
  2718. char *p = va_arg(*ap, char *);
  2719. if (pr == ~0U) pr = p == NULL ? 0 : strlen(p);
  2720. for (j = 0; !minus && pr < w && j + pr < w; j++)
  2721. n += scpy(out, param, &pad, 1);
  2722. n += scpy(out, param, p, pr);
  2723. for (j = 0; minus && pr < w && j + pr < w; j++)
  2724. n += scpy(out, param, &pad, 1);
  2725. } else if (c == '%') {
  2726. out('%', param);
  2727. n++;
  2728. } else {
  2729. out('%', param);
  2730. out(c, param);
  2731. n += 2;
  2732. }
  2733. i++;
  2734. } else {
  2735. out(fmt[i], param), n++, i++;
  2736. }
  2737. }
  2738. return n;
  2739. }
  2740. #ifdef MG_ENABLE_LINES
  2741. #line 1 "src/fs.c"
  2742. #endif
  2743. struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) {
  2744. struct mg_fd *fd = (struct mg_fd *) mg_calloc(1, sizeof(*fd));
  2745. if (fd != NULL) {
  2746. fd->fd = fs->op(path, flags);
  2747. fd->fs = fs;
  2748. if (fd->fd == NULL) {
  2749. mg_free(fd);
  2750. fd = NULL;
  2751. }
  2752. }
  2753. return fd;
  2754. }
  2755. void mg_fs_close(struct mg_fd *fd) {
  2756. if (fd != NULL) {
  2757. fd->fs->cl(fd->fd);
  2758. mg_free(fd);
  2759. }
  2760. }
  2761. struct mg_str mg_file_read(struct mg_fs *fs, const char *path) {
  2762. struct mg_str result = {NULL, 0};
  2763. void *fp;
  2764. fs->st(path, &result.len, NULL);
  2765. if ((fp = fs->op(path, MG_FS_READ)) != NULL) {
  2766. result.buf = (char *) mg_calloc(1, result.len + 1);
  2767. if (result.buf != NULL &&
  2768. fs->rd(fp, (void *) result.buf, result.len) != result.len) {
  2769. mg_free((void *) result.buf);
  2770. result.buf = NULL;
  2771. }
  2772. fs->cl(fp);
  2773. }
  2774. if (result.buf == NULL) result.len = 0;
  2775. return result;
  2776. }
  2777. bool mg_file_write(struct mg_fs *fs, const char *path, const void *buf,
  2778. size_t len) {
  2779. bool result = false;
  2780. struct mg_fd *fd;
  2781. char tmp[MG_PATH_MAX], rnd[10];
  2782. size_t path_len = mg_snprintf(tmp, sizeof(tmp), "%s..%s", path,
  2783. mg_random_str(rnd, sizeof(rnd)));
  2784. if (path_len < sizeof(tmp) &&
  2785. (fd = mg_fs_open(fs, tmp, MG_FS_WRITE | MG_FS_EXCL)) != NULL) {
  2786. result = fs->wr(fd->fd, buf, len) == len;
  2787. mg_fs_close(fd);
  2788. if (result) {
  2789. fs->rm(path);
  2790. result = fs->mv(tmp, path);
  2791. }
  2792. fs->rm(tmp);
  2793. }
  2794. return result;
  2795. }
  2796. bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...) {
  2797. va_list ap;
  2798. char *data;
  2799. bool result = false;
  2800. va_start(ap, fmt);
  2801. data = mg_vmprintf(fmt, &ap);
  2802. va_end(ap);
  2803. result = mg_file_write(fs, path, data, strlen(data));
  2804. mg_free(data);
  2805. return result;
  2806. }
  2807. // This helper function allows to scan a filesystem in a sequential way,
  2808. // without using callback function:
  2809. // char buf[100] = "";
  2810. // while (mg_fs_ls(&mg_fs_posix, "./", buf, sizeof(buf))) {
  2811. // ...
  2812. static void mg_fs_ls_fn(const char *filename, void *param) {
  2813. struct mg_str *s = (struct mg_str *) param;
  2814. if (s->buf[0] == '\0') {
  2815. mg_snprintf((char *) s->buf, s->len, "%s", filename);
  2816. } else if (strcmp(s->buf, filename) == 0) {
  2817. ((char *) s->buf)[0] = '\0'; // Fetch next file
  2818. }
  2819. }
  2820. bool mg_fs_ls(struct mg_fs *fs, const char *path, char *buf, size_t len) {
  2821. struct mg_str s;
  2822. s.buf = buf, s.len = len;
  2823. fs->ls(path, mg_fs_ls_fn, &s);
  2824. return buf[0] != '\0';
  2825. }
  2826. #ifdef MG_ENABLE_LINES
  2827. #line 1 "src/fs_fat.c"
  2828. #endif
  2829. #if MG_ENABLE_FATFS
  2830. #include <ff.h>
  2831. static time_t ff_time_to_epoch(uint16_t fdate, uint16_t ftime) {
  2832. unsigned int sec = (ftime << 1) & 0x3e;
  2833. unsigned int min = (ftime >> 5) & 0x3f;
  2834. unsigned int hour = (ftime >> 11) & 0x1f;
  2835. unsigned int day = fdate & 0x1f;
  2836. unsigned int month = (fdate >> 5) & 0x0f;
  2837. unsigned int year = ((fdate >> 9) & 0x7f) + 1980;
  2838. return (time_t) mg_timegm(year, month, day, hour, min, sec);
  2839. }
  2840. static int ff_stat(const char *path, size_t *size, time_t *mtime) {
  2841. FILINFO fi;
  2842. if (path[0] == '\0') {
  2843. if (size) *size = 0;
  2844. if (mtime) *mtime = 0;
  2845. return MG_FS_DIR;
  2846. } else if (f_stat(path, &fi) == 0) {
  2847. if (size) *size = (size_t) fi.fsize;
  2848. if (mtime) *mtime = ff_time_to_epoch(fi.fdate, fi.ftime);
  2849. return MG_FS_READ | MG_FS_WRITE | ((fi.fattrib & AM_DIR) ? MG_FS_DIR : 0);
  2850. } else {
  2851. return 0;
  2852. }
  2853. }
  2854. static void ff_list(const char *dir, void (*fn)(const char *, void *),
  2855. void *userdata) {
  2856. DIR d;
  2857. FILINFO fi;
  2858. if (f_opendir(&d, dir) == FR_OK) {
  2859. while (f_readdir(&d, &fi) == FR_OK && fi.fname[0] != '\0') {
  2860. if (!strcmp(fi.fname, ".") || !strcmp(fi.fname, "..")) continue;
  2861. fn(fi.fname, userdata);
  2862. }
  2863. f_closedir(&d);
  2864. }
  2865. }
  2866. static void *ff_open(const char *path, int flags) {
  2867. FIL *fp = NULL;
  2868. unsigned char mode = FA_READ;
  2869. if (flags & MG_FS_WRITE) {
  2870. mode |= FA_WRITE;
  2871. if (flags & MG_FS_EXCL) {
  2872. mode |= FA_OPEN_ALWAYS | FA_OPEN_APPEND;
  2873. } else {
  2874. mode |= FA_CREATE_NEW;
  2875. }
  2876. }
  2877. if ((fp = mg_calloc(1, sizeof(*fp))) != NULL &&
  2878. f_open(fp, path, mode) != FR_OK) {
  2879. mg_free(fp);
  2880. fp = NULL;
  2881. }
  2882. return fp;
  2883. }
  2884. static void ff_close(void *fp) {
  2885. if (fp != NULL) {
  2886. f_close((FIL *) fp);
  2887. mg_free(fp);
  2888. }
  2889. }
  2890. static size_t ff_read(void *fp, void *buf, size_t len) {
  2891. UINT n = 0, misalign = ((size_t) buf) & 3;
  2892. if (misalign) {
  2893. char aligned[4];
  2894. f_read((FIL *) fp, aligned, len > misalign ? misalign : len, &n);
  2895. memcpy(buf, aligned, n);
  2896. } else {
  2897. f_read((FIL *) fp, buf, len, &n);
  2898. }
  2899. return n;
  2900. }
  2901. static size_t ff_write(void *fp, const void *buf, size_t len) {
  2902. UINT n = 0;
  2903. return f_write((FIL *) fp, (char *) buf, len, &n) == FR_OK ? n : 0;
  2904. }
  2905. static size_t ff_seek(void *fp, size_t offset) {
  2906. f_lseek((FIL *) fp, offset);
  2907. return offset;
  2908. }
  2909. static bool ff_rename(const char *from, const char *to) {
  2910. return f_rename(from, to) == FR_OK;
  2911. }
  2912. static bool ff_remove(const char *path) {
  2913. return f_unlink(path) == FR_OK;
  2914. }
  2915. static bool ff_mkdir(const char *path) {
  2916. return f_mkdir(path) == FR_OK;
  2917. }
  2918. struct mg_fs mg_fs_fat = {ff_stat, ff_list, ff_open, ff_close, ff_read,
  2919. ff_write, ff_seek, ff_rename, ff_remove, ff_mkdir};
  2920. #endif
  2921. #ifdef MG_ENABLE_LINES
  2922. #line 1 "src/fs_packed.c"
  2923. #endif
  2924. struct packed_file {
  2925. const char *data;
  2926. size_t size;
  2927. size_t pos;
  2928. };
  2929. const struct mg_mem_file *mg_mem_files;
  2930. static int mg_scmp(const char *a, const char *b) {
  2931. while (*a && (*a == *b)) a++, b++;
  2932. return *(const unsigned char *) a - *(const unsigned char *) b;
  2933. }
  2934. static const char *mg_unlist(size_t no) {
  2935. return mg_mem_files == NULL ? NULL : mg_mem_files[no].path;
  2936. }
  2937. static const char *mg_unpack(const char *path, size_t *size, time_t *mtime) {
  2938. const struct mg_mem_file *p;
  2939. for (p = mg_mem_files; p != NULL && p->path != NULL; p++) {
  2940. if (mg_scmp(p->path, path) != 0) continue;
  2941. if (size != NULL) *size = p->size;
  2942. if (mtime != NULL) *mtime = p->mtime;
  2943. return (const char *) p->data;
  2944. }
  2945. return NULL;
  2946. }
  2947. struct mg_str mg_unpacked(const char *path) {
  2948. size_t len = 0;
  2949. const char *buf = mg_unpack(path, &len, NULL);
  2950. return mg_str_n(buf, len);
  2951. }
  2952. static int is_dir_prefix(const char *prefix, size_t n, const char *path) {
  2953. // MG_INFO(("[%.*s] [%s] %c", (int) n, prefix, path, path[n]));
  2954. return n < strlen(path) && strncmp(prefix, path, n) == 0 &&
  2955. (n == 0 || path[n] == '/' || path[n - 1] == '/');
  2956. }
  2957. static int packed_stat(const char *path, size_t *size, time_t *mtime) {
  2958. const char *p;
  2959. size_t i, n = strlen(path);
  2960. if (mg_unpack(path, size, mtime)) return MG_FS_READ; // Regular file
  2961. // Scan all files. If `path` is a dir prefix for any of them, it's a dir
  2962. for (i = 0; (p = mg_unlist(i)) != NULL; i++) {
  2963. if (is_dir_prefix(path, n, p)) return MG_FS_DIR;
  2964. }
  2965. return 0;
  2966. }
  2967. static void packed_list(const char *dir, void (*fn)(const char *, void *),
  2968. void *userdata) {
  2969. char buf[MG_PATH_MAX], tmp[sizeof(buf)];
  2970. const char *path, *begin, *end;
  2971. size_t i, n = strlen(dir);
  2972. tmp[0] = '\0'; // Previously listed entry
  2973. for (i = 0; (path = mg_unlist(i)) != NULL; i++) {
  2974. if (!is_dir_prefix(dir, n, path)) continue;
  2975. begin = &path[n + 1];
  2976. end = strchr(begin, '/');
  2977. if (end == NULL) end = begin + strlen(begin);
  2978. mg_snprintf(buf, sizeof(buf), "%.*s", (int) (end - begin), begin);
  2979. buf[sizeof(buf) - 1] = '\0';
  2980. // If this entry has been already listed, skip
  2981. // NOTE: we're assuming that file list is sorted alphabetically
  2982. if (strcmp(buf, tmp) == 0) continue;
  2983. fn(buf, userdata); // Not yet listed, call user function
  2984. strcpy(tmp, buf); // And save this entry as listed
  2985. }
  2986. }
  2987. static void *packed_open(const char *path, int flags) {
  2988. size_t size = 0;
  2989. const char *data = mg_unpack(path, &size, NULL);
  2990. struct packed_file *fp = NULL;
  2991. if (data == NULL) return NULL;
  2992. if (flags & MG_FS_WRITE) return NULL;
  2993. if ((fp = (struct packed_file *) mg_calloc(1, sizeof(*fp))) != NULL) {
  2994. fp->size = size;
  2995. fp->data = data;
  2996. }
  2997. return (void *) fp;
  2998. }
  2999. static void packed_close(void *fp) {
  3000. if (fp != NULL) mg_free(fp);
  3001. }
  3002. static size_t packed_read(void *fd, void *buf, size_t len) {
  3003. struct packed_file *fp = (struct packed_file *) fd;
  3004. if (fp->pos + len > fp->size) len = fp->size - fp->pos;
  3005. memcpy(buf, &fp->data[fp->pos], len);
  3006. fp->pos += len;
  3007. return len;
  3008. }
  3009. static size_t packed_write(void *fd, const void *buf, size_t len) {
  3010. (void) fd, (void) buf, (void) len;
  3011. return 0;
  3012. }
  3013. static size_t packed_seek(void *fd, size_t offset) {
  3014. struct packed_file *fp = (struct packed_file *) fd;
  3015. fp->pos = offset;
  3016. if (fp->pos > fp->size) fp->pos = fp->size;
  3017. return fp->pos;
  3018. }
  3019. static bool packed_rename(const char *from, const char *to) {
  3020. (void) from, (void) to;
  3021. return false;
  3022. }
  3023. static bool packed_remove(const char *path) {
  3024. (void) path;
  3025. return false;
  3026. }
  3027. static bool packed_mkdir(const char *path) {
  3028. (void) path;
  3029. return false;
  3030. }
  3031. struct mg_fs mg_fs_packed = {
  3032. packed_stat, packed_list, packed_open, packed_close, packed_read,
  3033. packed_write, packed_seek, packed_rename, packed_remove, packed_mkdir};
  3034. #ifdef MG_ENABLE_LINES
  3035. #line 1 "src/fs_posix.c"
  3036. #endif
  3037. #if MG_ENABLE_POSIX_FS
  3038. #ifndef MG_STAT_STRUCT
  3039. #define MG_STAT_STRUCT stat
  3040. #endif
  3041. #ifndef MG_STAT_FUNC
  3042. #define MG_STAT_FUNC stat
  3043. #endif
  3044. static int p_stat(const char *path, size_t *size, time_t *mtime) {
  3045. #if !defined(S_ISDIR)
  3046. MG_ERROR(("stat() API is not supported. %p %p %p", path, size, mtime));
  3047. return 0;
  3048. #else
  3049. #if MG_ARCH == MG_ARCH_WIN32
  3050. struct _stati64 st;
  3051. wchar_t tmp[MG_PATH_MAX];
  3052. MultiByteToWideChar(CP_UTF8, 0, path, -1, tmp, sizeof(tmp) / sizeof(tmp[0]));
  3053. if (_wstati64(tmp, &st) != 0) return 0;
  3054. // If path is a symlink, windows reports 0 in st.st_size.
  3055. // Get a real file size by opening it and jumping to the end
  3056. if (st.st_size == 0 && (st.st_mode & _S_IFREG)) {
  3057. FILE *fp = _wfopen(tmp, L"rb");
  3058. if (fp != NULL) {
  3059. fseek(fp, 0, SEEK_END);
  3060. if (ftell(fp) > 0) st.st_size = ftell(fp); // Use _ftelli64 on win10+
  3061. fclose(fp);
  3062. }
  3063. }
  3064. #else
  3065. struct MG_STAT_STRUCT st;
  3066. if (MG_STAT_FUNC(path, &st) != 0) return 0;
  3067. #endif
  3068. if (size) *size = (size_t) st.st_size;
  3069. if (mtime) *mtime = st.st_mtime;
  3070. return MG_FS_READ | MG_FS_WRITE | (S_ISDIR(st.st_mode) ? MG_FS_DIR : 0);
  3071. #endif
  3072. }
  3073. #if MG_ARCH == MG_ARCH_WIN32
  3074. struct dirent {
  3075. char d_name[MAX_PATH];
  3076. };
  3077. typedef struct win32_dir {
  3078. HANDLE handle;
  3079. WIN32_FIND_DATAW info;
  3080. struct dirent result;
  3081. } DIR;
  3082. #if 0
  3083. int gettimeofday(struct timeval *tv, void *tz) {
  3084. FILETIME ft;
  3085. unsigned __int64 tmpres = 0;
  3086. if (tv != NULL) {
  3087. GetSystemTimeAsFileTime(&ft);
  3088. tmpres |= ft.dwHighDateTime;
  3089. tmpres <<= 32;
  3090. tmpres |= ft.dwLowDateTime;
  3091. tmpres /= 10; // convert into microseconds
  3092. tmpres -= (int64_t) 11644473600000000;
  3093. tv->tv_sec = (long) (tmpres / 1000000UL);
  3094. tv->tv_usec = (long) (tmpres % 1000000UL);
  3095. }
  3096. (void) tz;
  3097. return 0;
  3098. }
  3099. #endif
  3100. static int to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
  3101. int ret;
  3102. char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p;
  3103. strncpy(buf, path, sizeof(buf));
  3104. buf[sizeof(buf) - 1] = '\0';
  3105. // Trim trailing slashes. Leave backslash for paths like "X:\"
  3106. p = buf + strlen(buf) - 1;
  3107. while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
  3108. memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
  3109. ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
  3110. // Convert back to Unicode. If doubly-converted string does not match the
  3111. // original, something is fishy, reject.
  3112. WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
  3113. NULL, NULL);
  3114. if (strcmp(buf, buf2) != 0) {
  3115. wbuf[0] = L'\0';
  3116. ret = 0;
  3117. }
  3118. return ret;
  3119. }
  3120. DIR *opendir(const char *name) {
  3121. DIR *d = NULL;
  3122. wchar_t wpath[MAX_PATH];
  3123. DWORD attrs;
  3124. size_t n;
  3125. if (name == NULL) {
  3126. SetLastError(ERROR_BAD_ARGUMENTS);
  3127. } else if ((d = (DIR *) mg_calloc(1, sizeof(*d))) == NULL) {
  3128. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3129. } else {
  3130. to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0]));
  3131. attrs = GetFileAttributesW(wpath);
  3132. if (attrs != 0Xffffffff && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
  3133. n = wcslen(wpath);
  3134. if (n <= (sizeof(wpath) / sizeof(wpath[0])) - 3) {
  3135. (void) wcscat(wpath, L"\\*");
  3136. d->handle = FindFirstFileW(wpath, &d->info);
  3137. d->result.d_name[0] = '\0';
  3138. } else {
  3139. mg_free(d);
  3140. d = NULL;
  3141. SetLastError(ERROR_BUFFER_OVERFLOW);
  3142. }
  3143. } else {
  3144. mg_free(d);
  3145. d = NULL;
  3146. }
  3147. }
  3148. return d;
  3149. }
  3150. int closedir(DIR *d) {
  3151. int result = 0;
  3152. if (d != NULL) {
  3153. if (d->handle != INVALID_HANDLE_VALUE)
  3154. result = FindClose(d->handle) ? 0 : -1;
  3155. mg_free(d);
  3156. } else {
  3157. result = -1;
  3158. SetLastError(ERROR_BAD_ARGUMENTS);
  3159. }
  3160. return result;
  3161. }
  3162. struct dirent *readdir(DIR *d) {
  3163. struct dirent *result = NULL;
  3164. if (d != NULL) {
  3165. memset(&d->result, 0, sizeof(d->result));
  3166. if (d->handle != INVALID_HANDLE_VALUE) {
  3167. result = &d->result;
  3168. WideCharToMultiByte(CP_UTF8, 0, d->info.cFileName, -1, result->d_name,
  3169. sizeof(result->d_name), NULL, NULL);
  3170. if (!FindNextFileW(d->handle, &d->info)) {
  3171. FindClose(d->handle);
  3172. d->handle = INVALID_HANDLE_VALUE;
  3173. }
  3174. } else {
  3175. SetLastError(ERROR_FILE_NOT_FOUND);
  3176. }
  3177. } else {
  3178. SetLastError(ERROR_BAD_ARGUMENTS);
  3179. }
  3180. return result;
  3181. }
  3182. #endif
  3183. static void p_list(const char *dir, void (*fn)(const char *, void *),
  3184. void *userdata) {
  3185. #if MG_ENABLE_DIRLIST
  3186. struct dirent *dp;
  3187. DIR *dirp;
  3188. if ((dirp = (opendir(dir))) == NULL) return;
  3189. while ((dp = readdir(dirp)) != NULL) {
  3190. if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
  3191. fn(dp->d_name, userdata);
  3192. }
  3193. closedir(dirp);
  3194. #else
  3195. (void) dir, (void) fn, (void) userdata;
  3196. #endif
  3197. }
  3198. static void *p_open(const char *path, int flags) {
  3199. #if MG_ARCH == MG_ARCH_WIN32
  3200. const char *mode = flags == MG_FS_READ ? "rb"
  3201. : (flags & MG_FS_EXCL) ? "wxb"
  3202. : "a+b";
  3203. wchar_t b1[MG_PATH_MAX], b2[10];
  3204. MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
  3205. MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
  3206. return (void *) _wfopen(b1, b2);
  3207. #else
  3208. const char *mode = flags == MG_FS_READ ? "rbe"
  3209. : (flags & MG_FS_EXCL) ? "wxbe"
  3210. : "a+be"; // e for CLOSEXEC
  3211. return (void *) fopen(path, mode);
  3212. #endif
  3213. }
  3214. static void p_close(void *fp) {
  3215. fclose((FILE *) fp);
  3216. }
  3217. static size_t p_read(void *fp, void *buf, size_t len) {
  3218. return fread(buf, 1, len, (FILE *) fp);
  3219. }
  3220. static size_t p_write(void *fp, const void *buf, size_t len) {
  3221. return fwrite(buf, 1, len, (FILE *) fp);
  3222. }
  3223. static size_t p_seek(void *fp, size_t offset) {
  3224. #if (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) || \
  3225. (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
  3226. (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
  3227. if (fseeko((FILE *) fp, (off_t) offset, SEEK_SET) != 0) (void) 0;
  3228. #else
  3229. if (fseek((FILE *) fp, (long) offset, SEEK_SET) != 0) (void) 0;
  3230. #endif
  3231. return (size_t) ftell((FILE *) fp);
  3232. }
  3233. static bool p_rename(const char *from, const char *to) {
  3234. return rename(from, to) == 0;
  3235. }
  3236. static bool p_remove(const char *path) {
  3237. return remove(path) == 0;
  3238. }
  3239. static bool p_mkdir(const char *path) {
  3240. return mkdir(path, 0775) == 0;
  3241. }
  3242. #else
  3243. static int p_stat(const char *path, size_t *size, time_t *mtime) {
  3244. (void) path, (void) size, (void) mtime;
  3245. return 0;
  3246. }
  3247. static void p_list(const char *path, void (*fn)(const char *, void *),
  3248. void *userdata) {
  3249. (void) path, (void) fn, (void) userdata;
  3250. }
  3251. static void *p_open(const char *path, int flags) {
  3252. (void) path, (void) flags;
  3253. return NULL;
  3254. }
  3255. static void p_close(void *fp) {
  3256. (void) fp;
  3257. }
  3258. static size_t p_read(void *fd, void *buf, size_t len) {
  3259. (void) fd, (void) buf, (void) len;
  3260. return 0;
  3261. }
  3262. static size_t p_write(void *fd, const void *buf, size_t len) {
  3263. (void) fd, (void) buf, (void) len;
  3264. return 0;
  3265. }
  3266. static size_t p_seek(void *fd, size_t offset) {
  3267. (void) fd, (void) offset;
  3268. return (size_t) ~0;
  3269. }
  3270. static bool p_rename(const char *from, const char *to) {
  3271. (void) from, (void) to;
  3272. return false;
  3273. }
  3274. static bool p_remove(const char *path) {
  3275. (void) path;
  3276. return false;
  3277. }
  3278. static bool p_mkdir(const char *path) {
  3279. (void) path;
  3280. return false;
  3281. }
  3282. #endif
  3283. struct mg_fs mg_fs_posix = {p_stat, p_list, p_open, p_close, p_read,
  3284. p_write, p_seek, p_rename, p_remove, p_mkdir};
  3285. #ifdef MG_ENABLE_LINES
  3286. #line 1 "src/http.c"
  3287. #endif
  3288. static int mg_ncasecmp(const char *s1, const char *s2, size_t len) {
  3289. int diff = 0;
  3290. if (len > 0) do {
  3291. int c = *s1++, d = *s2++;
  3292. if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
  3293. if (d >= 'A' && d <= 'Z') d += 'a' - 'A';
  3294. diff = c - d;
  3295. } while (diff == 0 && s1[-1] != '\0' && --len > 0);
  3296. return diff;
  3297. }
  3298. bool mg_to_size_t(struct mg_str str, size_t *val);
  3299. bool mg_to_size_t(struct mg_str str, size_t *val) {
  3300. size_t i = 0, max = (size_t) -1, max2 = max / 10, result = 0, ndigits = 0;
  3301. while (i < str.len && (str.buf[i] == ' ' || str.buf[i] == '\t')) i++;
  3302. if (i < str.len && str.buf[i] == '-') return false;
  3303. while (i < str.len && str.buf[i] >= '0' && str.buf[i] <= '9') {
  3304. size_t digit = (size_t) (str.buf[i] - '0');
  3305. if (result > max2) return false; // Overflow
  3306. result *= 10;
  3307. if (result > max - digit) return false; // Overflow
  3308. result += digit;
  3309. i++, ndigits++;
  3310. }
  3311. while (i < str.len && (str.buf[i] == ' ' || str.buf[i] == '\t')) i++;
  3312. if (ndigits == 0) return false; // #2322: Content-Length = 1 * DIGIT
  3313. if (i != str.len) return false; // Ditto
  3314. *val = (size_t) result;
  3315. return true;
  3316. }
  3317. // Chunk deletion marker is the MSB in the "processed" counter
  3318. #define MG_DMARK ((size_t) 1 << (sizeof(size_t) * 8 - 1))
  3319. // Multipart POST example:
  3320. // --xyz
  3321. // Content-Disposition: form-data; name="val"
  3322. //
  3323. // abcdef
  3324. // --xyz
  3325. // Content-Disposition: form-data; name="foo"; filename="a.txt"
  3326. // Content-Type: text/plain
  3327. //
  3328. // hello world
  3329. //
  3330. // --xyz--
  3331. size_t mg_http_next_multipart(struct mg_str body, size_t ofs,
  3332. struct mg_http_part *part) {
  3333. struct mg_str cd = mg_str_n("Content-Disposition", 19);
  3334. const char *s = body.buf;
  3335. size_t b = ofs, h1, h2, b1, b2, max = body.len;
  3336. // Init part params
  3337. if (part != NULL) part->name = part->filename = part->body = mg_str_n(0, 0);
  3338. // Skip boundary
  3339. while (b + 2 < max && !(s[b] == '\r' && s[b + 1] == '\n')) b++;
  3340. if (b <= ofs || b + 2 >= max) return 0;
  3341. // MG_INFO(("B: %zu %zu [%.*s]", ofs, b - ofs, (int) (b - ofs), s));
  3342. // Skip headers
  3343. h1 = h2 = b + 2;
  3344. for (;;) {
  3345. while (h2 + 2 < max && !(s[h2] == '\r' && s[h2 + 1] == '\n')) h2++;
  3346. if (h2 == h1) break;
  3347. if (h2 + 2 >= max) return 0;
  3348. // MG_INFO(("Header: [%.*s]", (int) (h2 - h1), &s[h1]));
  3349. if (part != NULL && h1 + cd.len + 2 < h2 && s[h1 + cd.len] == ':' &&
  3350. mg_ncasecmp(&s[h1], cd.buf, cd.len) == 0) {
  3351. struct mg_str v = mg_str_n(&s[h1 + cd.len + 2], h2 - (h1 + cd.len + 2));
  3352. part->name = mg_http_get_header_var(v, mg_str_n("name", 4));
  3353. part->filename = mg_http_get_header_var(v, mg_str_n("filename", 8));
  3354. }
  3355. h1 = h2 = h2 + 2;
  3356. }
  3357. b1 = b2 = h2 + 2;
  3358. while (b2 + 2 + (b - ofs) + 2 < max && !(s[b2] == '\r' && s[b2 + 1] == '\n' &&
  3359. memcmp(&s[b2 + 2], s, b - ofs) == 0))
  3360. b2++;
  3361. if (b2 + 2 >= max) return 0;
  3362. if (part != NULL) part->body = mg_str_n(&s[b1], b2 - b1);
  3363. // MG_INFO(("Body: [%.*s]", (int) (b2 - b1), &s[b1]));
  3364. return b2 + 2;
  3365. }
  3366. void mg_http_bauth(struct mg_connection *c, const char *user,
  3367. const char *pass) {
  3368. struct mg_str u = mg_str(user), p = mg_str(pass);
  3369. size_t need = c->send.len + 36 + (u.len + p.len) * 2;
  3370. if (c->send.size < need) mg_iobuf_resize(&c->send, need);
  3371. if (c->send.size >= need) {
  3372. size_t i, n = 0;
  3373. char *buf = (char *) &c->send.buf[c->send.len];
  3374. memcpy(buf, "Authorization: Basic ", 21); // DON'T use mg_send!
  3375. for (i = 0; i < u.len; i++) {
  3376. n = mg_base64_update(((unsigned char *) u.buf)[i], buf + 21, n);
  3377. }
  3378. if (p.len > 0) {
  3379. n = mg_base64_update(':', buf + 21, n);
  3380. for (i = 0; i < p.len; i++) {
  3381. n = mg_base64_update(((unsigned char *) p.buf)[i], buf + 21, n);
  3382. }
  3383. }
  3384. n = mg_base64_final(buf + 21, n);
  3385. c->send.len += 21 + (size_t) n + 2;
  3386. memcpy(&c->send.buf[c->send.len - 2], "\r\n", 2);
  3387. } else {
  3388. MG_ERROR(("%lu oom %d->%d ", c->id, (int) c->send.size, (int) need));
  3389. }
  3390. }
  3391. struct mg_str mg_http_var(struct mg_str buf, struct mg_str name) {
  3392. struct mg_str entry, k, v, result = mg_str_n(NULL, 0);
  3393. while (mg_span(buf, &entry, &buf, '&')) {
  3394. if (mg_span(entry, &k, &v, '=') && name.len == k.len &&
  3395. mg_ncasecmp(name.buf, k.buf, k.len) == 0) {
  3396. result = v;
  3397. break;
  3398. }
  3399. }
  3400. return result;
  3401. }
  3402. int mg_http_get_var(const struct mg_str *buf, const char *name, char *dst,
  3403. size_t dst_len) {
  3404. int len;
  3405. if (dst != NULL && dst_len > 0) {
  3406. dst[0] = '\0'; // If destination buffer is valid, always nul-terminate it
  3407. }
  3408. if (dst == NULL || dst_len == 0) {
  3409. len = -2; // Bad destination
  3410. } else if (buf->buf == NULL || name == NULL || buf->len == 0) {
  3411. len = -1; // Bad source
  3412. } else {
  3413. struct mg_str v = mg_http_var(*buf, mg_str(name));
  3414. if (v.buf == NULL) {
  3415. len = -4; // Name does not exist
  3416. } else {
  3417. len = mg_url_decode(v.buf, v.len, dst, dst_len, 1);
  3418. if (len < 0) len = -3; // Failed to decode
  3419. }
  3420. }
  3421. return len;
  3422. }
  3423. static bool isx(int c) {
  3424. return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
  3425. (c >= 'A' && c <= 'F');
  3426. }
  3427. int mg_url_decode(const char *src, size_t src_len, char *dst, size_t dst_len,
  3428. int is_form_url_encoded) {
  3429. size_t i, j;
  3430. for (i = j = 0; i < src_len && j + 1 < dst_len; i++, j++) {
  3431. if (src[i] == '%') {
  3432. // Use `i + 2 < src_len`, not `i < src_len - 2`, note small src_len
  3433. if (i + 2 < src_len && isx(src[i + 1]) && isx(src[i + 2])) {
  3434. mg_str_to_num(mg_str_n(src + i + 1, 2), 16, &dst[j], sizeof(uint8_t));
  3435. i += 2;
  3436. } else {
  3437. return -1;
  3438. }
  3439. } else if (is_form_url_encoded && src[i] == '+') {
  3440. dst[j] = ' ';
  3441. } else {
  3442. dst[j] = src[i];
  3443. }
  3444. }
  3445. if (j < dst_len) dst[j] = '\0'; // Null-terminate the destination
  3446. return i >= src_len && j < dst_len ? (int) j : -1;
  3447. }
  3448. static bool isok(uint8_t c) {
  3449. return c == '\n' || c == '\r' || c == '\t' || c >= ' ';
  3450. }
  3451. int mg_http_get_request_len(const unsigned char *buf, size_t buf_len) {
  3452. size_t i;
  3453. for (i = 0; i < buf_len; i++) {
  3454. if (!isok(buf[i])) return -1;
  3455. if ((i > 0 && buf[i] == '\n' && buf[i - 1] == '\n') ||
  3456. (i > 3 && buf[i] == '\n' && buf[i - 1] == '\r' && buf[i - 2] == '\n'))
  3457. return (int) i + 1;
  3458. }
  3459. return 0;
  3460. }
  3461. struct mg_str *mg_http_get_header(struct mg_http_message *h, const char *name) {
  3462. size_t i, n = strlen(name), max = sizeof(h->headers) / sizeof(h->headers[0]);
  3463. for (i = 0; i < max && h->headers[i].name.len > 0; i++) {
  3464. struct mg_str *k = &h->headers[i].name, *v = &h->headers[i].value;
  3465. if (n == k->len && mg_ncasecmp(k->buf, name, n) == 0) return v;
  3466. }
  3467. return NULL;
  3468. }
  3469. // Is it a valid utf-8 continuation byte
  3470. static bool vcb(uint8_t c) {
  3471. return (c & 0xc0) == 0x80;
  3472. }
  3473. // Get character length (valid utf-8). Used to parse method, URI, headers
  3474. static size_t clen(const char *s, const char *end) {
  3475. const unsigned char *u = (unsigned char *) s, c = *u;
  3476. long n = (long) (end - s);
  3477. if (c > ' ' && c <= '~') return 1; // Usual ascii printed char
  3478. if ((c & 0xe0) == 0xc0 && n > 1 && vcb(u[1])) return 2; // 2-byte UTF8
  3479. if ((c & 0xf0) == 0xe0 && n > 2 && vcb(u[1]) && vcb(u[2])) return 3;
  3480. if ((c & 0xf8) == 0xf0 && n > 3 && vcb(u[1]) && vcb(u[2]) && vcb(u[3]))
  3481. return 4;
  3482. return 0;
  3483. }
  3484. // Skip until the newline. Return advanced `s`, or NULL on error
  3485. static const char *skiptorn(const char *s, const char *end, struct mg_str *v) {
  3486. v->buf = (char *) s;
  3487. while (s < end && s[0] != '\n' && s[0] != '\r') s++, v->len++; // To newline
  3488. if (s >= end || (s[0] == '\r' && s[1] != '\n')) return NULL; // Stray \r
  3489. if (s < end && s[0] == '\r') s++; // Skip \r
  3490. if (s >= end || *s++ != '\n') return NULL; // Skip \n
  3491. return s;
  3492. }
  3493. static bool mg_http_parse_headers(const char *s, const char *end,
  3494. struct mg_http_header *h, size_t max_hdrs) {
  3495. size_t i, n;
  3496. int cl_count = 0, te_count = 0, auth_count = 0;
  3497. int conn_count = 0, cookie_count = 0;
  3498. for (i = 0; i < max_hdrs; i++) {
  3499. struct mg_str k = {NULL, 0}, v = {NULL, 0};
  3500. if (s >= end) return false;
  3501. if (s[0] == '\n' || (s[0] == '\r' && s[1] == '\n')) break;
  3502. k.buf = (char *) s;
  3503. while (s < end && s[0] != ':' && (n = clen(s, end)) > 0) s += n, k.len += n;
  3504. if (k.len == 0) return false; // Empty name
  3505. if (s >= end || clen(s, end) == 0) return false; // Invalid UTF-8
  3506. if (*s++ != ':') return false; // Invalid, not followed by :
  3507. // if (clen(s, end) == 0) return false; // Invalid UTF-8
  3508. while (s < end && (s[0] == ' ' || s[0] == '\t')) s++; // Skip spaces
  3509. if ((s = skiptorn(s, end, &v)) == NULL) return false;
  3510. while (v.len > 0 && (v.buf[v.len - 1] == ' ' || v.buf[v.len - 1] == '\t')) {
  3511. v.len--; // Trim spaces
  3512. }
  3513. // detect duplicated headers -> discard
  3514. if (((mg_strcasecmp(k, mg_str("Content-Length")) == 0) &&
  3515. (++cl_count > 1)) ||
  3516. ((mg_strcasecmp(k, mg_str("Transfer-Encoding")) == 0) &&
  3517. (++te_count > 1)) ||
  3518. ((mg_strcasecmp(k, mg_str("Authorization")) == 0) &&
  3519. (++auth_count > 1)) ||
  3520. ((mg_strcasecmp(k, mg_str("Cookie")) == 0) && (++cookie_count > 1)) ||
  3521. ((mg_strcasecmp(k, mg_str("Connection")) == 0) && (++conn_count > 1)))
  3522. return false;
  3523. // MG_INFO(("--HH [%.*s] [%.*s]", (int) k.len, k.buf, (int) v.len, v.buf));
  3524. h[i].name = k, h[i].value = v; // Success. Assign values
  3525. }
  3526. return true;
  3527. }
  3528. int mg_http_parse(const char *s, size_t len, struct mg_http_message *hm) {
  3529. int is_response, req_len = mg_http_get_request_len((unsigned char *) s, len);
  3530. const char *end = s == NULL ? NULL : s + req_len, *qs; // Cannot add to NULL
  3531. const struct mg_str *cl;
  3532. size_t n;
  3533. bool version_prefix_valid;
  3534. memset(hm, 0, sizeof(*hm));
  3535. if (req_len <= 0) return req_len;
  3536. hm->message.buf = hm->head.buf = (char *) s;
  3537. hm->body.buf = (char *) end;
  3538. hm->head.len = (size_t) req_len;
  3539. hm->message.len = hm->body.len = (size_t) -1; // Set body length to infinite
  3540. // Parse request line
  3541. hm->method.buf = (char *) s;
  3542. while (s < end && (n = clen(s, end)) > 0) s += n, hm->method.len += n;
  3543. while (s < end && s[0] == ' ') s++; // Skip spaces
  3544. hm->uri.buf = (char *) s;
  3545. while (s < end && (n = clen(s, end)) > 0) s += n, hm->uri.len += n;
  3546. while (s < end && s[0] == ' ') s++; // Skip spaces
  3547. is_response =
  3548. hm->method.len > 5 && (mg_ncasecmp(hm->method.buf, "HTTP/", 5) == 0);
  3549. if ((s = skiptorn(s, end, &hm->proto)) == NULL) return false;
  3550. // If we're given a version, check that it is HTTP/x.x
  3551. version_prefix_valid =
  3552. hm->proto.len > 5 && (mg_ncasecmp(hm->proto.buf, "HTTP/", 5) == 0);
  3553. if (!is_response && !version_prefix_valid)
  3554. return -1; // no version detected in request
  3555. if (!is_response && hm->proto.len > 0 &&
  3556. (!version_prefix_valid || hm->proto.len != 8 ||
  3557. (hm->proto.buf[5] < '0' || hm->proto.buf[5] > '9') ||
  3558. (hm->proto.buf[6] != '.') ||
  3559. (hm->proto.buf[7] < '0' || hm->proto.buf[7] > '9'))) {
  3560. return -1;
  3561. }
  3562. // If URI contains '?' character, setup query string
  3563. if ((qs = (const char *) memchr(hm->uri.buf, '?', hm->uri.len)) != NULL) {
  3564. hm->query.buf = (char *) qs + 1;
  3565. hm->query.len = (size_t) (&hm->uri.buf[hm->uri.len] - (qs + 1));
  3566. hm->uri.len = (size_t) (qs - hm->uri.buf);
  3567. }
  3568. // Sanity check. Allow protocol/reason to be empty
  3569. // Do this check after hm->method.len and hm->uri.len are finalised
  3570. if (hm->method.len == 0 || hm->uri.len == 0) return -1;
  3571. if (!mg_http_parse_headers(s, end, hm->headers,
  3572. sizeof(hm->headers) / sizeof(hm->headers[0])))
  3573. return -1; // error when parsing
  3574. cl = mg_http_get_header(hm, "Content-Length");
  3575. if (cl != NULL && mg_http_get_header(hm, "Transfer-Encoding") != NULL)
  3576. return -1; // cannot contain both CL and TE
  3577. if (cl != NULL) {
  3578. if (mg_to_size_t(*cl, &hm->body.len) == false) return -1;
  3579. hm->message.len = (size_t) req_len + hm->body.len;
  3580. }
  3581. // mg_http_parse() is used to parse both HTTP requests and HTTP
  3582. // responses. If HTTP response does not have Content-Length set, then
  3583. // body is read until socket is closed, i.e. body.len is infinite (~0).
  3584. //
  3585. // For HTTP requests though, if Content-Length is not specified
  3586. // set body length to 0.
  3587. if (hm->body.len == (size_t) ~0 && !is_response) {
  3588. hm->body.len = 0;
  3589. hm->message.len = (size_t) req_len;
  3590. }
  3591. // The 204 (No content) responses also have 0 body length
  3592. if (hm->body.len == (size_t) ~0 && is_response &&
  3593. mg_strcasecmp(hm->uri, mg_str("204")) == 0) {
  3594. hm->body.len = 0;
  3595. hm->message.len = (size_t) req_len;
  3596. }
  3597. if (hm->message.len < (size_t) req_len) return -1; // Overflow protection
  3598. return req_len;
  3599. }
  3600. static void mg_http_vprintf_chunk(struct mg_connection *c, const char *fmt,
  3601. va_list *ap) {
  3602. size_t len = c->send.len;
  3603. if (!mg_send(c, " \r\n", 10)) mg_error(c, "OOM");
  3604. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
  3605. if (c->send.len >= len + 10) {
  3606. mg_snprintf((char *) c->send.buf + len, 9, "%08lx", c->send.len - len - 10);
  3607. c->send.buf[len + 8] = '\r';
  3608. if (c->send.len == len + 10) c->is_resp = 0; // Last chunk, reset marker
  3609. }
  3610. if (!mg_send(c, "\r\n", 2)) mg_error(c, "OOM");
  3611. }
  3612. void mg_http_printf_chunk(struct mg_connection *c, const char *fmt, ...) {
  3613. va_list ap;
  3614. va_start(ap, fmt);
  3615. mg_http_vprintf_chunk(c, fmt, &ap);
  3616. va_end(ap);
  3617. }
  3618. void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len) {
  3619. mg_printf(c, "%lx\r\n", (unsigned long) len);
  3620. if (!mg_send(c, buf, len) || !mg_send(c, "\r\n", 2)) mg_error(c, "OOM");
  3621. if (len == 0) c->is_resp = 0;
  3622. }
  3623. // clang-format off
  3624. static const char *mg_http_status_code_str(int status_code) {
  3625. switch (status_code) {
  3626. case 100: return "Continue";
  3627. case 101: return "Switching Protocols";
  3628. case 102: return "Processing";
  3629. case 200: return "OK";
  3630. case 201: return "Created";
  3631. case 202: return "Accepted";
  3632. case 203: return "Non-authoritative Information";
  3633. case 204: return "No Content";
  3634. case 205: return "Reset Content";
  3635. case 206: return "Partial Content";
  3636. case 207: return "Multi-Status";
  3637. case 208: return "Already Reported";
  3638. case 226: return "IM Used";
  3639. case 300: return "Multiple Choices";
  3640. case 301: return "Moved Permanently";
  3641. case 302: return "Found";
  3642. case 303: return "See Other";
  3643. case 304: return "Not Modified";
  3644. case 305: return "Use Proxy";
  3645. case 307: return "Temporary Redirect";
  3646. case 308: return "Permanent Redirect";
  3647. case 400: return "Bad Request";
  3648. case 401: return "Unauthorized";
  3649. case 402: return "Payment Required";
  3650. case 403: return "Forbidden";
  3651. case 404: return "Not Found";
  3652. case 405: return "Method Not Allowed";
  3653. case 406: return "Not Acceptable";
  3654. case 407: return "Proxy Authentication Required";
  3655. case 408: return "Request Timeout";
  3656. case 409: return "Conflict";
  3657. case 410: return "Gone";
  3658. case 411: return "Length Required";
  3659. case 412: return "Precondition Failed";
  3660. case 413: return "Payload Too Large";
  3661. case 414: return "Request-URI Too Long";
  3662. case 415: return "Unsupported Media Type";
  3663. case 416: return "Requested Range Not Satisfiable";
  3664. case 417: return "Expectation Failed";
  3665. case 418: return "I'm a teapot";
  3666. case 421: return "Misdirected Request";
  3667. case 422: return "Unprocessable Entity";
  3668. case 423: return "Locked";
  3669. case 424: return "Failed Dependency";
  3670. case 426: return "Upgrade Required";
  3671. case 428: return "Precondition Required";
  3672. case 429: return "Too Many Requests";
  3673. case 431: return "Request Header Fields Too Large";
  3674. case 444: return "Connection Closed Without Response";
  3675. case 451: return "Unavailable For Legal Reasons";
  3676. case 499: return "Client Closed Request";
  3677. case 500: return "Internal Server Error";
  3678. case 501: return "Not Implemented";
  3679. case 502: return "Bad Gateway";
  3680. case 503: return "Service Unavailable";
  3681. case 504: return "Gateway Timeout";
  3682. case 505: return "HTTP Version Not Supported";
  3683. case 506: return "Variant Also Negotiates";
  3684. case 507: return "Insufficient Storage";
  3685. case 508: return "Loop Detected";
  3686. case 510: return "Not Extended";
  3687. case 511: return "Network Authentication Required";
  3688. case 599: return "Network Connect Timeout Error";
  3689. default: return "";
  3690. }
  3691. }
  3692. // clang-format on
  3693. void mg_http_reply(struct mg_connection *c, int code, const char *headers,
  3694. const char *fmt, ...) {
  3695. va_list ap;
  3696. size_t len;
  3697. mg_printf(c, "HTTP/1.1 %d %s\r\n%sContent-Length: \r\n\r\n", code,
  3698. mg_http_status_code_str(code), headers == NULL ? "" : headers);
  3699. len = c->send.len;
  3700. va_start(ap, fmt);
  3701. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
  3702. va_end(ap);
  3703. if (c->send.len > 16) {
  3704. size_t n = mg_snprintf((char *) &c->send.buf[len - 15], 11, "%-10lu",
  3705. (unsigned long) (c->send.len - len));
  3706. c->send.buf[len - 15 + n] = ' '; // Change ending 0 to space
  3707. }
  3708. c->is_resp = 0;
  3709. }
  3710. static void http_cb(struct mg_connection *, int, void *);
  3711. static void restore_http_cb(struct mg_connection *c) {
  3712. mg_fs_close((struct mg_fd *) c->pfn_data);
  3713. c->pfn_data = NULL;
  3714. c->pfn = http_cb;
  3715. c->is_resp = 0;
  3716. }
  3717. char *mg_http_etag(char *buf, size_t len, size_t size, time_t mtime);
  3718. char *mg_http_etag(char *buf, size_t len, size_t size, time_t mtime) {
  3719. mg_snprintf(buf, len, "\"%lld.%lld\"", (int64_t) mtime, (int64_t) size);
  3720. return buf;
  3721. }
  3722. static void static_cb(struct mg_connection *c, int ev, void *ev_data) {
  3723. if (ev == MG_EV_WRITE || ev == MG_EV_POLL) {
  3724. struct mg_fd *fd = (struct mg_fd *) c->pfn_data;
  3725. // Read to send IO buffer directly, avoid extra on-stack buffer
  3726. size_t n, max = MG_IO_SIZE, space;
  3727. size_t *cl = (size_t *) &c->data[(sizeof(c->data) - sizeof(size_t)) /
  3728. sizeof(size_t) * sizeof(size_t)];
  3729. if (c->send.size < max) mg_iobuf_resize(&c->send, max);
  3730. if (c->send.len >= c->send.size) return; // Rate limit
  3731. if ((space = c->send.size - c->send.len) > *cl) space = *cl;
  3732. n = fd->fs->rd(fd->fd, c->send.buf + c->send.len, space);
  3733. c->send.len += n;
  3734. *cl -= n;
  3735. if (n == 0) restore_http_cb(c);
  3736. } else if (ev == MG_EV_CLOSE) {
  3737. restore_http_cb(c);
  3738. }
  3739. (void) ev_data;
  3740. }
  3741. // Known mime types. Keep it outside guess_content_type() function, since
  3742. // some environments don't like it defined there.
  3743. // clang-format off
  3744. #define MG_C_STR(a) { (char *) (a), sizeof(a) - 1 }
  3745. static struct mg_str s_known_types[] = {
  3746. MG_C_STR("html"), MG_C_STR("text/html; charset=utf-8"),
  3747. MG_C_STR("htm"), MG_C_STR("text/html; charset=utf-8"),
  3748. MG_C_STR("css"), MG_C_STR("text/css; charset=utf-8"),
  3749. MG_C_STR("js"), MG_C_STR("text/javascript; charset=utf-8"),
  3750. MG_C_STR("mjs"), MG_C_STR("text/javascript; charset=utf-8"),
  3751. MG_C_STR("gif"), MG_C_STR("image/gif"),
  3752. MG_C_STR("png"), MG_C_STR("image/png"),
  3753. MG_C_STR("jpg"), MG_C_STR("image/jpeg"),
  3754. MG_C_STR("jpeg"), MG_C_STR("image/jpeg"),
  3755. MG_C_STR("woff"), MG_C_STR("font/woff"),
  3756. MG_C_STR("ttf"), MG_C_STR("font/ttf"),
  3757. MG_C_STR("svg"), MG_C_STR("image/svg+xml"),
  3758. MG_C_STR("txt"), MG_C_STR("text/plain; charset=utf-8"),
  3759. MG_C_STR("avi"), MG_C_STR("video/x-msvideo"),
  3760. MG_C_STR("csv"), MG_C_STR("text/csv"),
  3761. MG_C_STR("doc"), MG_C_STR("application/msword"),
  3762. MG_C_STR("exe"), MG_C_STR("application/octet-stream"),
  3763. MG_C_STR("gz"), MG_C_STR("application/gzip"),
  3764. MG_C_STR("ico"), MG_C_STR("image/x-icon"),
  3765. MG_C_STR("json"), MG_C_STR("application/json"),
  3766. MG_C_STR("mov"), MG_C_STR("video/quicktime"),
  3767. MG_C_STR("mp3"), MG_C_STR("audio/mpeg"),
  3768. MG_C_STR("mp4"), MG_C_STR("video/mp4"),
  3769. MG_C_STR("mpeg"), MG_C_STR("video/mpeg"),
  3770. MG_C_STR("pdf"), MG_C_STR("application/pdf"),
  3771. MG_C_STR("shtml"), MG_C_STR("text/html; charset=utf-8"),
  3772. MG_C_STR("tgz"), MG_C_STR("application/tar-gz"),
  3773. MG_C_STR("wav"), MG_C_STR("audio/wav"),
  3774. MG_C_STR("webp"), MG_C_STR("image/webp"),
  3775. MG_C_STR("zip"), MG_C_STR("application/zip"),
  3776. MG_C_STR("3gp"), MG_C_STR("video/3gpp"),
  3777. {0, 0},
  3778. };
  3779. // clang-format on
  3780. static struct mg_str guess_content_type(struct mg_str path, const char *extra) {
  3781. struct mg_str entry, k, v, s = mg_str(extra), asterisk = mg_str_n("*", 1);
  3782. size_t i = 0;
  3783. // Shrink path to its extension only
  3784. while (i < path.len && path.buf[path.len - i - 1] != '.') i++;
  3785. path.buf += path.len - i;
  3786. path.len = i;
  3787. // Process user-provided mime type overrides, if any
  3788. while (mg_span(s, &entry, &s, ',')) {
  3789. if (mg_span(entry, &k, &v, '=') &&
  3790. (mg_strcmp(asterisk, k) == 0 || mg_strcmp(path, k) == 0))
  3791. return v;
  3792. }
  3793. // Process built-in mime types
  3794. for (i = 0; s_known_types[i].buf != NULL; i += 2) {
  3795. if (mg_strcmp(path, s_known_types[i]) == 0) return s_known_types[i + 1];
  3796. }
  3797. return mg_str("text/plain; charset=utf-8");
  3798. }
  3799. static int getrange(struct mg_str *s, size_t *a, size_t *b) {
  3800. size_t i, numparsed = 0;
  3801. for (i = 0; i + 6 < s->len; i++) {
  3802. struct mg_str k, v = mg_str_n(s->buf + i + 6, s->len - i - 6);
  3803. if (memcmp(&s->buf[i], "bytes=", 6) != 0) continue;
  3804. if (mg_span(v, &k, &v, '-')) {
  3805. if (mg_to_size_t(k, a)) numparsed++;
  3806. if (v.len > 0 && mg_to_size_t(v, b)) numparsed++;
  3807. } else {
  3808. if (mg_to_size_t(v, a)) numparsed++;
  3809. }
  3810. break;
  3811. }
  3812. return (int) numparsed;
  3813. }
  3814. void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
  3815. const char *path,
  3816. const struct mg_http_serve_opts *opts) {
  3817. char etag[64], tmp[MG_PATH_MAX];
  3818. struct mg_fs *fs = opts && opts->fs ? opts->fs : &mg_fs_posix;
  3819. struct mg_fd *fd = NULL;
  3820. size_t size = 0;
  3821. time_t mtime = 0;
  3822. const char *mime_types = opts && opts->mime_types ? opts->mime_types : NULL;
  3823. const char *hdrs = opts && opts->extra_headers ? opts->extra_headers : "";
  3824. struct mg_str *inm = NULL;
  3825. struct mg_str mime = guess_content_type(mg_str(path), mime_types);
  3826. bool gzip = false;
  3827. if (path != NULL) {
  3828. // If a browser sends us "Accept-Encoding: gzip", try to open .gz first
  3829. struct mg_str *ae = mg_http_get_header(hm, "Accept-Encoding");
  3830. if (ae != NULL) {
  3831. if (mg_match(*ae, mg_str("*gzip*"), NULL)) {
  3832. mg_snprintf(tmp, sizeof(tmp), "%s.gz", path);
  3833. fd = mg_fs_open(fs, tmp, MG_FS_READ);
  3834. if (fd != NULL) gzip = true, path = tmp;
  3835. }
  3836. }
  3837. // No luck opening .gz? Open what we've told to open
  3838. if (fd == NULL) fd = mg_fs_open(fs, path, MG_FS_READ);
  3839. }
  3840. // Failed to open, and page404 is configured? Open it, then
  3841. if (fd == NULL && opts && opts->page404) {
  3842. fd = mg_fs_open(fs, opts->page404, MG_FS_READ);
  3843. path = opts->page404;
  3844. mime = guess_content_type(mg_str(path), mime_types);
  3845. }
  3846. if (fd == NULL || fs->st(path, &size, &mtime) == 0) {
  3847. mg_http_reply(c, 404, hdrs, "Not found\n");
  3848. mg_fs_close(fd);
  3849. // NOTE: mg_http_etag() call should go first!
  3850. } else if (mg_http_etag(etag, sizeof(etag), size, mtime) != NULL &&
  3851. (inm = mg_http_get_header(hm, "If-None-Match")) != NULL &&
  3852. mg_strcasecmp(*inm, mg_str(etag)) == 0) {
  3853. mg_fs_close(fd);
  3854. mg_http_reply(c, 304, hdrs, "");
  3855. } else {
  3856. int n, status = 200;
  3857. char range[100];
  3858. size_t r1 = 0, r2 = 0, cl = size;
  3859. // Handle Range header
  3860. struct mg_str *rh = mg_http_get_header(hm, "Range");
  3861. range[0] = '\0';
  3862. if (rh != NULL && (n = getrange(rh, &r1, &r2)) > 0) {
  3863. // If range is specified like "400-", set second limit to content len
  3864. if (n == 1) r2 = cl - 1;
  3865. if (r1 > r2 || r2 >= cl) {
  3866. status = 416;
  3867. cl = 0;
  3868. mg_snprintf(range, sizeof(range), "Content-Range: bytes */%lld\r\n",
  3869. (int64_t) size);
  3870. } else {
  3871. status = 206;
  3872. cl = r2 - r1 + 1;
  3873. mg_snprintf(range, sizeof(range),
  3874. "Content-Range: bytes %llu-%llu/%llu\r\n", (uint64_t) r1,
  3875. (uint64_t) (r1 + cl - 1), (uint64_t) size);
  3876. fs->sk(fd->fd, r1);
  3877. }
  3878. }
  3879. mg_printf(c,
  3880. "HTTP/1.1 %d %s\r\n"
  3881. "Content-Type: %.*s\r\n"
  3882. "Etag: %s\r\n"
  3883. "Content-Length: %llu\r\n"
  3884. "%s%s%s\r\n",
  3885. status, mg_http_status_code_str(status), (int) mime.len, mime.buf,
  3886. etag, (uint64_t) cl, gzip ? "Content-Encoding: gzip\r\n" : "",
  3887. range, hdrs);
  3888. if (mg_strcasecmp(hm->method, mg_str("HEAD")) == 0 || c->is_closing) {
  3889. c->is_resp = 0;
  3890. mg_fs_close(fd);
  3891. } else { // start serving static content only if not closing, see #3354
  3892. // Track to-be-sent content length at the end of c->data, aligned
  3893. size_t *clp = (size_t *) &c->data[(sizeof(c->data) - sizeof(size_t)) /
  3894. sizeof(size_t) * sizeof(size_t)];
  3895. c->pfn = static_cb;
  3896. c->pfn_data = fd;
  3897. *clp = cl;
  3898. }
  3899. }
  3900. }
  3901. struct printdirentrydata {
  3902. struct mg_connection *c;
  3903. struct mg_http_message *hm;
  3904. const struct mg_http_serve_opts *opts;
  3905. const char *dir;
  3906. };
  3907. #if MG_ENABLE_DIRLIST
  3908. // Print file name, escaping HTML chars
  3909. static size_t html_esc(void (*fn)(char, void *), void *arg, va_list *ap) {
  3910. const char *s = va_arg(*ap, const char *);
  3911. size_t i, len = 0;
  3912. for (i = 0; s[i] != '\0'; i++) {
  3913. if (s[i] == '<') {
  3914. len += mg_xprintf(fn, arg, "%s", "&lt;");
  3915. } else if (s[i] == '>') {
  3916. len += mg_xprintf(fn, arg, "%s", "&gt;");
  3917. } else if (s[i] == '&') {
  3918. len += mg_xprintf(fn, arg, "%s", "&amp;");
  3919. } else {
  3920. len += mg_xprintf(fn, arg, "%c", s[i]);
  3921. }
  3922. }
  3923. return len;
  3924. }
  3925. static void printdirentry(const char *name, void *userdata) {
  3926. struct printdirentrydata *d = (struct printdirentrydata *) userdata;
  3927. struct mg_fs *fs = d->opts->fs == NULL ? &mg_fs_posix : d->opts->fs;
  3928. size_t size = 0;
  3929. time_t t = 0;
  3930. char path[MG_PATH_MAX], sz[40], mod[40];
  3931. int flags, n = 0;
  3932. // MG_DEBUG(("[%s] [%s]", d->dir, name));
  3933. if (mg_snprintf(path, sizeof(path), "%s%c%s", d->dir, '/', name) >
  3934. sizeof(path)) {
  3935. MG_ERROR(("%s truncated", name));
  3936. } else if ((flags = fs->st(path, &size, &t)) == 0) {
  3937. MG_ERROR(("%lu stat(%s)", d->c->id, path));
  3938. } else {
  3939. const char *slash = flags & MG_FS_DIR ? "/" : "";
  3940. if (flags & MG_FS_DIR) {
  3941. mg_snprintf(sz, sizeof(sz), "%s", "[DIR]");
  3942. } else {
  3943. mg_snprintf(sz, sizeof(sz), "%lld", (uint64_t) size);
  3944. }
  3945. #if defined(MG_HTTP_DIRLIST_TIME_FMT)
  3946. {
  3947. char time_str[40];
  3948. struct tm *time_info = localtime(&t);
  3949. strftime(time_str, sizeof time_str, "%Y/%m/%d %H:%M:%S", time_info);
  3950. mg_snprintf(mod, sizeof(mod), "%s", time_str);
  3951. }
  3952. #else
  3953. mg_snprintf(mod, sizeof(mod), "%lu", (unsigned long) t);
  3954. #endif
  3955. n = (int) mg_url_encode(name, strlen(name), path, sizeof(path));
  3956. mg_printf(d->c,
  3957. " <tr><td><a href=\"%.*s%s\">%M%s</a></td>"
  3958. "<td name=%lu>%s</td><td name=%lld>%s</td></tr>\n",
  3959. n, path, slash, html_esc, name, slash, (unsigned long) t, mod,
  3960. flags & MG_FS_DIR ? (int64_t) -1 : (int64_t) size, sz);
  3961. }
  3962. }
  3963. static void listdir(struct mg_connection *c, struct mg_http_message *hm,
  3964. const struct mg_http_serve_opts *opts, char *dir) {
  3965. const char *sort_js_code =
  3966. "<script>function srt(tb, sc, so, d) {"
  3967. "var tr = Array.prototype.slice.call(tb.rows, 0),"
  3968. "tr = tr.sort(function (a, b) { var c1 = a.cells[sc], c2 = b.cells[sc],"
  3969. "n1 = c1.getAttribute('name'), n2 = c2.getAttribute('name'), "
  3970. "t1 = a.cells[2].getAttribute('name'), "
  3971. "t2 = b.cells[2].getAttribute('name'); "
  3972. "return so * (t1 < 0 && t2 >= 0 ? -1 : t2 < 0 && t1 >= 0 ? 1 : "
  3973. "n1 ? parseInt(n2) - parseInt(n1) : "
  3974. "c1.textContent.trim().localeCompare(c2.textContent.trim())); });";
  3975. const char *sort_js_code2 =
  3976. "for (var i = 0; i < tr.length; i++) tb.appendChild(tr[i]); "
  3977. "if (!d) window.location.hash = ('sc=' + sc + '&so=' + so); "
  3978. "};"
  3979. "window.onload = function() {"
  3980. "var tb = document.getElementById('tb');"
  3981. "var m = /sc=([012]).so=(1|-1)/.exec(window.location.hash) || [0, 2, 1];"
  3982. "var sc = m[1], so = m[2]; document.onclick = function(ev) { "
  3983. "var c = ev.target.rel; if (c) {if (c == sc) so *= -1; srt(tb, c, so); "
  3984. "sc = c; ev.preventDefault();}};"
  3985. "srt(tb, sc, so, true);"
  3986. "}"
  3987. "</script>";
  3988. struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  3989. struct printdirentrydata d = {c, hm, opts, dir};
  3990. char tmp[10], buf[MG_PATH_MAX];
  3991. size_t off, n;
  3992. int len = mg_url_decode(hm->uri.buf, hm->uri.len, buf, sizeof(buf), 0);
  3993. struct mg_str uri = len > 0 ? mg_str_n(buf, (size_t) len) : hm->uri;
  3994. mg_printf(c,
  3995. "HTTP/1.1 200 OK\r\n"
  3996. "Content-Type: text/html; charset=utf-8\r\n"
  3997. "%s"
  3998. "Content-Length: \r\n\r\n",
  3999. opts->extra_headers == NULL ? "" : opts->extra_headers);
  4000. off = c->send.len; // Start of body
  4001. mg_printf(c,
  4002. "<!DOCTYPE html><html><head><title>Index of %M</title>%s%s"
  4003. "<style>th,td {text-align: left; padding-right: 1em; "
  4004. "font-family: monospace; }</style></head>"
  4005. "<body><h1>Index of %M</h1><table cellpadding=\"0\"><thead>"
  4006. "<tr><th><a href=\"#\" rel=\"0\">Name</a></th><th>"
  4007. "<a href=\"#\" rel=\"1\">Modified</a></th>"
  4008. "<th><a href=\"#\" rel=\"2\">Size</a></th></tr>"
  4009. "<tr><td colspan=\"3\"><hr></td></tr>"
  4010. "</thead>"
  4011. "<tbody id=\"tb\">\n",
  4012. mg_print_html_esc, (int) uri.len, uri.buf, sort_js_code, sort_js_code2,
  4013. mg_print_html_esc, (int) uri.len, uri.buf);
  4014. mg_printf(c, "%s",
  4015. " <tr><td><a href=\"..\">..</a></td>"
  4016. "<td name=-1></td><td name=-1>[DIR]</td></tr>\n");
  4017. fs->ls(dir, printdirentry, &d);
  4018. mg_printf(c,
  4019. "</tbody><tfoot><tr><td colspan=\"3\"><hr></td></tr></tfoot>"
  4020. "</table><address>Mongoose v.%s</address></body></html>\n",
  4021. MG_VERSION);
  4022. n = mg_snprintf(tmp, sizeof(tmp), "%lu", (unsigned long) (c->send.len - off));
  4023. if (n > sizeof(tmp)) n = 0;
  4024. memcpy(c->send.buf + off - 12, tmp, n); // Set content length
  4025. c->is_resp = 0; // Mark response end
  4026. }
  4027. #endif
  4028. // Resolve requested file into `path` and return its fs->st() result
  4029. static int uri_to_path2(struct mg_connection *c, struct mg_http_message *hm,
  4030. struct mg_fs *fs, struct mg_str url, struct mg_str dir,
  4031. char *path, size_t path_size) {
  4032. int flags, tmp;
  4033. // Append URI to the root_dir, and sanitize it
  4034. size_t n = mg_snprintf(path, path_size, "%.*s", (int) dir.len, dir.buf);
  4035. if (n + 2 >= path_size) {
  4036. mg_http_reply(c, 400, "", "Exceeded path size");
  4037. return -1;
  4038. }
  4039. path[path_size - 1] = '\0';
  4040. // Terminate root dir with slash
  4041. if (n > 0 && path[n - 1] != '/') path[n++] = '/', path[n] = '\0';
  4042. if (url.len < hm->uri.len) {
  4043. mg_url_decode(hm->uri.buf + url.len, hm->uri.len - url.len, path + n,
  4044. path_size - n, 0);
  4045. }
  4046. path[path_size - 1] = '\0'; // Double-check
  4047. n = strlen(path);
  4048. if (!mg_path_is_sane(mg_str_n(path, n))) {
  4049. mg_http_reply(c, 400, "", "Invalid path");
  4050. return -1;
  4051. }
  4052. while (n > 1 && path[n - 1] == '/') path[--n] = 0; // Trim trailing slashes
  4053. flags = mg_strcmp(hm->uri, mg_str("/")) == 0 ? MG_FS_DIR
  4054. : fs->st(path, NULL, NULL);
  4055. MG_VERBOSE(("%lu %.*s -> %s %d", c->id, (int) hm->uri.len, hm->uri.buf, path,
  4056. flags));
  4057. if (flags == 0) {
  4058. // Do nothing - let's caller decide
  4059. } else if ((flags & MG_FS_DIR) && hm->uri.len > 0 &&
  4060. hm->uri.buf[hm->uri.len - 1] != '/') {
  4061. mg_printf(c,
  4062. "HTTP/1.1 301 Moved\r\n"
  4063. "Location: %.*s/\r\n"
  4064. "Content-Length: 0\r\n"
  4065. "\r\n",
  4066. (int) hm->uri.len, hm->uri.buf);
  4067. c->is_resp = 0;
  4068. flags = -1;
  4069. } else if (flags & MG_FS_DIR) {
  4070. if (((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX) > 0 &&
  4071. (tmp = fs->st(path, NULL, NULL)) != 0) ||
  4072. (mg_snprintf(path + n, path_size - n, "/index.shtml") > 0 &&
  4073. (tmp = fs->st(path, NULL, NULL)) != 0))) {
  4074. flags = tmp;
  4075. } else if ((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX ".gz") >
  4076. 0 &&
  4077. (tmp = fs->st(path, NULL, NULL)) !=
  4078. 0)) { // check for gzipped index
  4079. flags = tmp;
  4080. path[n + 1 + strlen(MG_HTTP_INDEX)] =
  4081. '\0'; // Remove appended .gz in index file name
  4082. } else {
  4083. path[n] = '\0'; // Remove appended index file name
  4084. }
  4085. }
  4086. return flags;
  4087. }
  4088. static int uri_to_path(struct mg_connection *c, struct mg_http_message *hm,
  4089. const struct mg_http_serve_opts *opts, char *path,
  4090. size_t path_size) {
  4091. struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  4092. struct mg_str k, v, part, s = mg_str(opts->root_dir), u = {NULL, 0}, p = u;
  4093. while (mg_span(s, &part, &s, ',')) {
  4094. if (!mg_span(part, &k, &v, '=')) k = part, v = mg_str_n(NULL, 0);
  4095. if (v.len == 0) v = k, k = mg_str("/"), u = k, p = v;
  4096. if (hm->uri.len < k.len) continue;
  4097. if (mg_strcmp(k, mg_str_n(hm->uri.buf, k.len)) != 0) continue;
  4098. u = k, p = v;
  4099. }
  4100. return uri_to_path2(c, hm, fs, u, p, path, path_size);
  4101. }
  4102. void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
  4103. const struct mg_http_serve_opts *opts) {
  4104. char path[MG_PATH_MAX];
  4105. const char *sp = opts->ssi_pattern;
  4106. int flags = uri_to_path(c, hm, opts, path, sizeof(path));
  4107. if (flags < 0) {
  4108. // Do nothing: the response has already been sent by uri_to_path()
  4109. } else if (flags & MG_FS_DIR) {
  4110. #if MG_ENABLE_DIRLIST
  4111. listdir(c, hm, opts, path);
  4112. #else
  4113. mg_http_reply(c, 403, "", "Forbidden\n");
  4114. #endif
  4115. } else if (flags && sp != NULL && mg_match(mg_str(path), mg_str(sp), NULL)) {
  4116. mg_http_serve_ssi(c, opts->root_dir, path);
  4117. } else {
  4118. mg_http_serve_file(c, hm, path, opts);
  4119. }
  4120. }
  4121. static bool mg_is_url_safe(int c) {
  4122. return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
  4123. (c >= 'A' && c <= 'Z') || c == '.' || c == '_' || c == '-' || c == '~';
  4124. }
  4125. size_t mg_url_encode(const char *s, size_t sl, char *buf, size_t len) {
  4126. size_t i, n = 0;
  4127. for (i = 0; i < sl; i++) {
  4128. int c = *(unsigned char *) &s[i];
  4129. if (n + 4 >= len) return 0;
  4130. if (mg_is_url_safe(c)) {
  4131. buf[n++] = s[i];
  4132. } else {
  4133. mg_snprintf(&buf[n], 4, "%%%M", mg_print_hex, 1, &s[i]);
  4134. n += 3;
  4135. }
  4136. }
  4137. if (len > 0 && n < len - 1) buf[n] = '\0'; // Null-terminate the destination
  4138. if (len > 0) buf[len - 1] = '\0'; // Always.
  4139. return n;
  4140. }
  4141. void mg_http_creds(struct mg_http_message *hm, char *user, size_t userlen,
  4142. char *pass, size_t passlen) {
  4143. struct mg_str *v = mg_http_get_header(hm, "Authorization");
  4144. user[0] = pass[0] = '\0';
  4145. if (v != NULL && v->len > 6 && memcmp(v->buf, "Basic ", 6) == 0) {
  4146. char buf[256];
  4147. size_t n = mg_base64_decode(v->buf + 6, v->len - 6, buf, sizeof(buf));
  4148. const char *p = (const char *) memchr(buf, ':', n > 0 ? n : 0);
  4149. if (p != NULL) {
  4150. mg_snprintf(user, userlen, "%.*s", p - buf, buf);
  4151. mg_snprintf(pass, passlen, "%.*s", n - (size_t) (p - buf) - 1, p + 1);
  4152. }
  4153. } else if (v != NULL && v->len > 7 && memcmp(v->buf, "Bearer ", 7) == 0) {
  4154. mg_snprintf(pass, passlen, "%.*s", (int) v->len - 7, v->buf + 7);
  4155. } else if ((v = mg_http_get_header(hm, "Cookie")) != NULL) {
  4156. struct mg_str t = mg_http_get_header_var(*v, mg_str_n("access_token", 12));
  4157. if (t.len > 0) mg_snprintf(pass, passlen, "%.*s", (int) t.len, t.buf);
  4158. } else {
  4159. mg_http_get_var(&hm->query, "access_token", pass, passlen);
  4160. }
  4161. }
  4162. static struct mg_str stripquotes(struct mg_str s) {
  4163. return s.len > 1 && s.buf[0] == '"' && s.buf[s.len - 1] == '"'
  4164. ? mg_str_n(s.buf + 1, s.len - 2)
  4165. : s;
  4166. }
  4167. struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v) {
  4168. size_t i;
  4169. for (i = 0; v.len > 0 && i + v.len + 2 < s.len; i++) {
  4170. if (s.buf[i + v.len] == '=' && memcmp(&s.buf[i], v.buf, v.len) == 0) {
  4171. const char *p = &s.buf[i + v.len + 1], *b = p, *x = &s.buf[s.len];
  4172. int q = p < x && *p == '"' ? 1 : 0;
  4173. while (p < x &&
  4174. (q ? p == b || *p != '"' : *p != ';' && *p != ' ' && *p != ','))
  4175. p++;
  4176. // MG_INFO(("[%.*s] [%.*s] [%.*s]", (int) s.len, s.buf, (int) v.len,
  4177. // v.buf, (int) (p - b), b));
  4178. return stripquotes(mg_str_n(b,
  4179. (size_t) (p - b + (q && p < x && *p == '"' ? 1 : 0))));
  4180. }
  4181. }
  4182. return mg_str_n(NULL, 0);
  4183. }
  4184. long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
  4185. struct mg_fs *fs, const char *dir, size_t max_size) {
  4186. char buf[20] = "0", file[MG_PATH_MAX], path[MG_PATH_MAX];
  4187. long res = 0, offset;
  4188. mg_http_get_var(&hm->query, "offset", buf, sizeof(buf));
  4189. mg_http_get_var(&hm->query, "file", file, sizeof(file));
  4190. offset = strtol(buf, NULL, 0);
  4191. mg_snprintf(path, sizeof(path), "%s%c%s", dir, MG_DIRSEP, file);
  4192. if (hm->body.len == 0) {
  4193. mg_http_reply(c, 200, "", "%ld", res); // Nothing to write
  4194. } else if (file[0] == '\0') {
  4195. mg_http_reply(c, 400, "", "file required");
  4196. res = -1;
  4197. } else if (mg_path_is_sane(mg_str(file)) == false) {
  4198. mg_http_reply(c, 400, "", "%s: invalid file", file);
  4199. res = -2;
  4200. } else if (offset < 0) {
  4201. mg_http_reply(c, 400, "", "offset required");
  4202. res = -3;
  4203. } else if ((size_t) offset + hm->body.len > max_size) {
  4204. mg_http_reply(c, 400, "", "%s: over max size of %lu", path,
  4205. (unsigned long) max_size);
  4206. res = -4;
  4207. } else {
  4208. struct mg_fd *fd;
  4209. size_t current_size = 0;
  4210. MG_DEBUG(("%s -> %lu bytes @ %ld", path, hm->body.len, offset));
  4211. if (offset == 0) fs->rm(path); // If offset if 0, truncate file
  4212. fs->st(path, &current_size, NULL);
  4213. if (offset > 0 && current_size != (size_t) offset) {
  4214. mg_http_reply(c, 400, "", "%s: offset mismatch", path);
  4215. res = -5;
  4216. } else if ((fd = mg_fs_open(fs, path, MG_FS_WRITE)) == NULL) {
  4217. mg_http_reply(c, 400, "", "open(%s)", path);
  4218. res = -6;
  4219. } else {
  4220. res = offset + (long) fs->wr(fd->fd, hm->body.buf, hm->body.len);
  4221. mg_fs_close(fd);
  4222. mg_http_reply(c, 200, "", "%ld", res);
  4223. }
  4224. }
  4225. return res;
  4226. }
  4227. int mg_http_status(const struct mg_http_message *hm) {
  4228. return atoi(hm->uri.buf);
  4229. }
  4230. struct mg_upload_priv {
  4231. size_t expected;
  4232. size_t received;
  4233. struct mg_fd *fd; // non-NULL: file upload; NULL: OTA
  4234. void (*fn)(struct mg_connection *, const char *);
  4235. };
  4236. static void mg_upload_handler(struct mg_connection *c, int ev, void *ev_data) {
  4237. struct mg_upload_priv *p = (struct mg_upload_priv *) c->data;
  4238. if (p->fn == NULL) return;
  4239. if (ev == MG_EV_READ && c->recv.len > 0) {
  4240. size_t alignment = 512;
  4241. size_t left = p->expected > p->received ? p->expected - p->received : 0;
  4242. size_t aligned = c->recv.len < left ? MG_ROUND_DOWN(c->recv.len, alignment)
  4243. : left;
  4244. bool ok = true;
  4245. if (aligned > 0) {
  4246. if (p->fd != NULL) {
  4247. ok = p->fd->fs->wr(p->fd->fd, c->recv.buf, aligned) == aligned;
  4248. } else {
  4249. ok = mg_ota_write(c->recv.buf, aligned);
  4250. }
  4251. }
  4252. p->received += aligned;
  4253. mg_iobuf_del(&c->recv, 0, aligned);
  4254. if (!ok) {
  4255. if (p->fd != NULL) { mg_fs_close(p->fd); p->fd = NULL; }
  4256. else mg_ota_end();
  4257. p->fn(c, "write error");
  4258. mg_free(c->pfn_data); c->pfn_data = NULL; p->fn = NULL;
  4259. } else if (p->received >= p->expected) {
  4260. const char *errmsg = NULL;
  4261. if (p->fd != NULL) { mg_fs_close(p->fd); p->fd = NULL; }
  4262. else if (!mg_ota_end()) errmsg = "OTA finalize failed";
  4263. p->fn(c, errmsg);
  4264. mg_free(c->pfn_data); c->pfn_data = NULL; p->fn = NULL;
  4265. }
  4266. } else if (ev == MG_EV_ERROR || ev == MG_EV_CLOSE) {
  4267. if (p->fd != NULL) { mg_fs_close(p->fd); p->fd = NULL; }
  4268. else mg_ota_end();
  4269. p->fn(c, ev == MG_EV_ERROR ? (const char *) ev_data : "connection closed");
  4270. mg_free(c->pfn_data); c->pfn_data = NULL; p->fn = NULL;
  4271. }
  4272. (void) ev_data;
  4273. }
  4274. static void mg_upload_default_cb(struct mg_connection *c, const char *status) {
  4275. MG_INFO(("%lu %s", c->id, status ? status : "ok"));
  4276. mg_http_reply(c, status ? 500 : 200, "", "%s\n", status ? status : "ok");
  4277. }
  4278. void mg_http_start_upload(struct mg_connection *c, struct mg_http_message *hm,
  4279. struct mg_str name, struct mg_str dir,
  4280. struct mg_fs *fs,
  4281. void (*fn)(struct mg_connection *, const char *)) {
  4282. struct mg_upload_priv *p = (struct mg_upload_priv *) c->data;
  4283. char path[MG_PATH_MAX];
  4284. struct mg_fd *fd;
  4285. if (fn == NULL) fn = mg_upload_default_cb;
  4286. if (sizeof(*p) > sizeof(c->data)) { fn(c, "data too small"); return; }
  4287. if (!mg_path_is_sane(name)) { fn(c, "bad name"); return; }
  4288. mg_snprintf(path, sizeof(path), "%.*s%c%.*s", (int) dir.len, dir.buf,
  4289. MG_DIRSEP, (int) name.len, name.buf);
  4290. fd = mg_fs_open(fs, path, MG_FS_WRITE);
  4291. if (fd == NULL) { fn(c, "open failed"); return; }
  4292. p->expected = hm->body.len;
  4293. p->received = 0;
  4294. p->fd = fd;
  4295. p->fn = fn;
  4296. c->fn = mg_upload_handler;
  4297. c->pfn_data = strdup(path);
  4298. c->pfn = NULL;
  4299. mg_iobuf_del(&c->recv, 0, hm->head.len);
  4300. mg_call(c, MG_EV_READ, &c->recv.len);
  4301. }
  4302. void mg_http_start_ota(struct mg_connection *c, struct mg_http_message *hm,
  4303. void (*fn)(struct mg_connection *, const char *)) {
  4304. struct mg_upload_priv *p = (struct mg_upload_priv *) c->data;
  4305. if (fn == NULL) fn = mg_upload_default_cb;
  4306. if (sizeof(*p) > sizeof(c->data)) { fn(c, "data too small"); return; }
  4307. if (!mg_ota_begin(hm->body.len)) { fn(c, "ota begin failed"); return; }
  4308. p->expected = hm->body.len;
  4309. p->received = 0;
  4310. p->fd = NULL;
  4311. p->fn = fn;
  4312. c->fn = mg_upload_handler;
  4313. c->pfn = NULL;
  4314. mg_iobuf_del(&c->recv, 0, hm->head.len);
  4315. mg_call(c, MG_EV_READ, &c->recv.len);
  4316. }
  4317. static bool is_hex_digit(int c) {
  4318. return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
  4319. (c >= 'A' && c <= 'F');
  4320. }
  4321. static int skip_chunk(const char *buf, int len, int *pl, int *dl) {
  4322. int i = 0, n = 0; // pass int to mg_str_to_num, treats as unsigned
  4323. if (len < 3) return 0;
  4324. while (i < len && is_hex_digit(buf[i])) i++;
  4325. if (i == 0) return -1; // Error, no length specified
  4326. if (len < i + 2 || buf[i] != '\r' || buf[i + 1] != '\n') return -1; // Error
  4327. if (mg_str_to_num(mg_str_n(buf, (size_t) i), 16, &n, sizeof(n)) == false)
  4328. return -1; // Decode chunk length, overflow
  4329. if (n < 0) return -1; // Chunk length is too big <0 = >0x80000000
  4330. if (n > len - i - 4) return 0; // Chunk not yet fully buffered
  4331. if (buf[i + n + 2] != '\r' || buf[i + n + 3] != '\n') return -1; // Error
  4332. *pl = i + 2, *dl = n;
  4333. return i + 2 + n + 2;
  4334. }
  4335. static void http_cb(struct mg_connection *c, int ev, void *ev_data) {
  4336. if (ev == MG_EV_READ || ev == MG_EV_CLOSE ||
  4337. (ev == MG_EV_POLL && c->is_accepted && !c->is_draining &&
  4338. c->recv.len > 0)) { // see #2796
  4339. struct mg_http_message hm;
  4340. size_t ofs = 0; // Parsing offset
  4341. while (c->is_resp == 0 && ofs < c->recv.len) {
  4342. const char *buf = (char *) c->recv.buf + ofs;
  4343. int n = mg_http_parse(buf, c->recv.len - ofs, &hm);
  4344. struct mg_str *te; // Transfer - encoding header
  4345. bool is_chunked = false, is_http_1_0 = false;
  4346. size_t old_len = c->recv.len;
  4347. if (n < 0) {
  4348. // We don't use mg_error() here, to avoid closing pipelined requests
  4349. // prematurely, see #2592
  4350. MG_ERROR(("HTTP parse, %lu bytes", c->recv.len));
  4351. c->is_draining = 1;
  4352. mg_hexdump(buf, c->recv.len - ofs > 16 ? 16 : c->recv.len - ofs);
  4353. c->recv.len = 0;
  4354. return;
  4355. }
  4356. if (n == 0) break; // Request is not buffered yet
  4357. mg_call(c, MG_EV_HTTP_HDRS, &hm); // Got all HTTP headers
  4358. if (c->recv.len != old_len) {
  4359. // User manipulated received data. Wash our hands
  4360. MG_DEBUG(("%lu detaching HTTP handler", c->id));
  4361. c->pfn = NULL;
  4362. return;
  4363. }
  4364. if (ev == MG_EV_CLOSE) { // If client did not set Content-Length
  4365. hm.message.len = c->recv.len - ofs; // and closes now, deliver MSG
  4366. hm.body.len = hm.message.len - (size_t) (hm.body.buf - hm.message.buf);
  4367. }
  4368. is_http_1_0 =
  4369. hm.proto.len == 8 && mg_ncasecmp(hm.proto.buf, "HTTP/1.0", 8) == 0;
  4370. // HTTP/1.0 does not use "Transfer-Encoding: chunked"
  4371. if (!is_http_1_0 &&
  4372. (te = mg_http_get_header(&hm, "Transfer-Encoding")) != NULL) {
  4373. if (mg_strcasecmp(*te, mg_str("chunked")) == 0) {
  4374. is_chunked = true;
  4375. } else {
  4376. mg_error(c, "Invalid Transfer-Encoding"); // See #2460
  4377. return;
  4378. }
  4379. } else if (mg_http_get_header(&hm, "Content-length") == NULL) {
  4380. // #2593: HTTP packets must contain either Transfer-Encoding or
  4381. // Content-length
  4382. bool is_response = mg_ncasecmp(hm.method.buf, "HTTP/", 5) == 0;
  4383. bool require_content_len = false;
  4384. if (!is_response && (mg_strcasecmp(hm.method, mg_str("POST")) == 0 ||
  4385. mg_strcasecmp(hm.method, mg_str("PUT")) == 0)) {
  4386. // POST and PUT should include an entity body. Therefore, they should
  4387. // contain a Content-length header (unless the body length is 0, in
  4388. // which case it can be omitted). Other requests can also contain a
  4389. // body, but their content has no defined semantics (RFC 7231)
  4390. if (hm.body.len != 0) require_content_len = true;
  4391. ofs += (size_t) n; // this request has been processed
  4392. } else if (is_response) {
  4393. // HTTP spec 7.2 Entity body: All other responses must include a body
  4394. // or Content-Length header field defined with a value of 0.
  4395. int status = mg_http_status(&hm);
  4396. require_content_len = status >= 200 && status != 204 && status != 304;
  4397. }
  4398. if (require_content_len) {
  4399. if (!c->is_client) mg_http_reply(c, 411, "", "");
  4400. MG_ERROR(("Content length missing from %s",
  4401. is_response ? "response" : "request"));
  4402. }
  4403. }
  4404. if (is_chunked) {
  4405. // For chunked data, strip off prefixes and suffixes from chunks
  4406. // and relocate them right after the headers, then report a message
  4407. char *s = (char *) c->recv.buf + ofs + n;
  4408. int o = 0, pl, dl, cl, len = (int) (c->recv.len - ofs - (size_t) n);
  4409. // Find zero-length chunk (the end of the body)
  4410. while ((cl = skip_chunk(s + o, len - o, &pl, &dl)) > 0 && dl) o += cl;
  4411. if (cl == 0) break; // No zero-len chunk, buffer more data
  4412. if (cl < 0) {
  4413. mg_error(c, "Invalid chunk");
  4414. break;
  4415. }
  4416. // Zero chunk found. Second pass: strip + relocate
  4417. o = 0, hm.body.len = 0, hm.message.len = (size_t) n;
  4418. while ((cl = skip_chunk(s + o, len - o, &pl, &dl)) > 0) {
  4419. memmove(s + hm.body.len, s + o + pl, (size_t) dl);
  4420. o += cl, hm.body.len += (size_t) dl, hm.message.len += (size_t) dl;
  4421. if (dl == 0) break;
  4422. }
  4423. ofs += (size_t) (n + o);
  4424. } else { // Normal, non-chunked data
  4425. size_t len = c->recv.len - ofs - (size_t) n;
  4426. if (hm.body.len > len) break; // Buffer more data
  4427. ofs += (size_t) n + hm.body.len;
  4428. }
  4429. if (c->is_accepted) c->is_resp = 1; // Start generating response
  4430. mg_call(c, MG_EV_HTTP_MSG, &hm); // User handler can clear is_resp
  4431. if (c->is_accepted && !c->is_resp) {
  4432. struct mg_str *cc = mg_http_get_header(&hm, "Connection");
  4433. if (cc != NULL && mg_strcasecmp(*cc, mg_str("close")) == 0) {
  4434. c->is_draining = 1; // honor "Connection: close"
  4435. break;
  4436. }
  4437. }
  4438. }
  4439. if (ofs > 0) mg_iobuf_del(&c->recv, 0, ofs); // Delete processed data
  4440. }
  4441. (void) ev_data;
  4442. }
  4443. struct mg_connection *mg_http_connect(struct mg_mgr *mgr, const char *url,
  4444. mg_event_handler_t fn, void *fn_data) {
  4445. return mg_connect_svc(mgr, url, fn, fn_data, http_cb, NULL);
  4446. }
  4447. struct mg_connection *mg_http_listen(struct mg_mgr *mgr, const char *url,
  4448. mg_event_handler_t fn, void *fn_data) {
  4449. struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
  4450. if (c != NULL) c->pfn = http_cb;
  4451. return c;
  4452. }
  4453. #ifdef MG_ENABLE_LINES
  4454. #line 1 "src/iobuf.c"
  4455. #endif
  4456. static size_t roundup(size_t size, size_t align) {
  4457. return align == 0 ? size : (size + align - 1) / align * align;
  4458. }
  4459. bool mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) {
  4460. bool ok = true;
  4461. new_size = roundup(new_size, io->align);
  4462. if (new_size == 0) {
  4463. mg_bzero(io->buf, io->size);
  4464. mg_free(io->buf);
  4465. io->buf = NULL;
  4466. io->len = io->size = 0;
  4467. } else if (new_size != io->size) {
  4468. // NOTE(lsm): do not use realloc here. Use mg_calloc/mg_free only
  4469. void *p = mg_calloc(1, new_size);
  4470. if (p != NULL) {
  4471. size_t len = new_size < io->len ? new_size : io->len;
  4472. if (len > 0 && io->buf != NULL) memmove(p, io->buf, len);
  4473. mg_bzero(io->buf, io->size);
  4474. mg_free(io->buf);
  4475. io->buf = (unsigned char *) p;
  4476. io->size = new_size;
  4477. io->len = len;
  4478. } else {
  4479. ok = false;
  4480. MG_ERROR(("%lld->%lld", (uint64_t) io->size, (uint64_t) new_size));
  4481. }
  4482. }
  4483. return ok;
  4484. }
  4485. bool mg_iobuf_init(struct mg_iobuf *io, size_t size, size_t align) {
  4486. io->buf = NULL;
  4487. io->align = align;
  4488. io->size = io->len = 0;
  4489. return mg_iobuf_resize(io, size);
  4490. }
  4491. size_t mg_iobuf_add(struct mg_iobuf *io, size_t ofs, const void *buf,
  4492. size_t len) {
  4493. size_t new_size = roundup(io->len + len, io->align);
  4494. mg_iobuf_resize(io, new_size); // Attempt to resize
  4495. if (new_size != io->size) len = 0; // Resize failure, append nothing
  4496. if (ofs < io->len) memmove(io->buf + ofs + len, io->buf + ofs, io->len - ofs);
  4497. if (buf != NULL) memmove(io->buf + ofs, buf, len);
  4498. if (ofs > io->len) io->len += ofs - io->len;
  4499. io->len += len;
  4500. return len;
  4501. }
  4502. size_t mg_iobuf_del(struct mg_iobuf *io, size_t ofs, size_t len) {
  4503. if (ofs > io->len) ofs = io->len;
  4504. if (ofs + len > io->len) len = io->len - ofs;
  4505. if (io->buf) memmove(io->buf + ofs, io->buf + ofs + len, io->len - ofs - len);
  4506. if (io->buf) mg_bzero(io->buf + io->len - len, len);
  4507. io->len -= len;
  4508. return len;
  4509. }
  4510. void mg_iobuf_free(struct mg_iobuf *io) {
  4511. mg_iobuf_resize(io, 0);
  4512. }
  4513. #ifdef MG_ENABLE_LINES
  4514. #line 1 "src/json.c"
  4515. #endif
  4516. static const char *escapeseq(int esc) {
  4517. return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\"";
  4518. }
  4519. static char json_esc(int c, int esc) {
  4520. const char *p, *esc1 = escapeseq(esc), *esc2 = escapeseq(!esc);
  4521. for (p = esc1; *p != '\0'; p++) {
  4522. if (*p == c) return esc2[p - esc1];
  4523. }
  4524. return 0;
  4525. }
  4526. static int mg_pass_string(const char *s, int len) {
  4527. int i;
  4528. for (i = 0; i < len; i++) {
  4529. if (s[i] == '\\' && i + 1 < len && json_esc(s[i + 1], 1)) {
  4530. i++;
  4531. } else if (s[i] == '\0') {
  4532. return MG_JSON_INVALID;
  4533. } else if (s[i] == '"') {
  4534. return i;
  4535. }
  4536. }
  4537. return MG_JSON_INVALID;
  4538. }
  4539. static double mg_atod(const char *p, int len, int *numlen) {
  4540. double d = 0.0;
  4541. int i = 0, sign = 1;
  4542. // Sign
  4543. if (i < len && *p == '-') {
  4544. sign = -1, i++;
  4545. } else if (i < len && *p == '+') {
  4546. i++;
  4547. }
  4548. // Decimal
  4549. for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
  4550. d *= 10.0;
  4551. d += p[i] - '0';
  4552. }
  4553. d *= sign;
  4554. // Fractional
  4555. if (i < len && p[i] == '.') {
  4556. double frac = 0.0, base = 0.1;
  4557. i++;
  4558. for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
  4559. frac += base * (p[i] - '0');
  4560. base /= 10.0;
  4561. }
  4562. d += frac * sign;
  4563. }
  4564. // Exponential
  4565. if (i < len && (p[i] == 'e' || p[i] == 'E')) {
  4566. int exp = 0, minus = 0;
  4567. i++;
  4568. if (i < len && p[i] == '-') minus = 1, i++;
  4569. if (i < len && p[i] == '+') i++;
  4570. while (i < len && p[i] >= '0' && p[i] <= '9' && exp < 308)
  4571. exp = exp * 10 + (p[i++] - '0');
  4572. // use fast exponentiation
  4573. // https://en.wikipedia.org/wiki/Exponentiation_by_squaring
  4574. if (exp != 0) {
  4575. double x = 10, y = 1;
  4576. if (exp > 308) exp = 308;
  4577. if (minus) x = 0.1;
  4578. while (exp > 1) {
  4579. if (exp & 1) {
  4580. y *= x;
  4581. --exp;
  4582. }
  4583. x *= x;
  4584. exp >>= 1;
  4585. }
  4586. d *= x * y;
  4587. }
  4588. }
  4589. if (numlen != NULL) *numlen = i;
  4590. return d;
  4591. }
  4592. // Iterate over object or array elements
  4593. size_t mg_json_next(struct mg_str obj, size_t ofs, struct mg_str *key,
  4594. struct mg_str *val) {
  4595. if (ofs >= obj.len) {
  4596. ofs = 0; // Out of boundaries, stop scanning
  4597. } else if (obj.len < 2 || (*obj.buf != '{' && *obj.buf != '[')) {
  4598. ofs = 0; // Not an array or object, stop
  4599. } else {
  4600. struct mg_str sub = mg_str_n(obj.buf + ofs, obj.len - ofs);
  4601. if (ofs == 0) ofs++, sub.buf++, sub.len--;
  4602. if (*obj.buf == '[') { // Iterate over an array
  4603. int n = 0, o = mg_json_get(sub, "$", &n);
  4604. if (n < 0 || o < 0 || (size_t) (o + n) > sub.len) {
  4605. ofs = 0; // Error parsing key, stop scanning
  4606. } else {
  4607. if (key) *key = mg_str_n(NULL, 0);
  4608. if (val) *val = mg_str_n(sub.buf + o, (size_t) n);
  4609. ofs = (size_t) (&sub.buf[o + n] - obj.buf);
  4610. }
  4611. } else { // Iterate over an object
  4612. int n = 0, o = mg_json_get(sub, "$", &n);
  4613. if (n < 0 || o < 0 || (size_t) (o + n) > sub.len) {
  4614. ofs = 0; // Error parsing key, stop scanning
  4615. } else {
  4616. if (key) *key = mg_str_n(sub.buf + o, (size_t) n);
  4617. sub.buf += o + n, sub.len -= (size_t) (o + n);
  4618. while (sub.len > 0 && *sub.buf != ':') sub.len--, sub.buf++;
  4619. if (sub.len > 0 && *sub.buf == ':') sub.len--, sub.buf++;
  4620. n = 0, o = mg_json_get(sub, "$", &n);
  4621. if (n < 0 || o < 0 || (size_t) (o + n) > sub.len) {
  4622. ofs = 0; // Error parsing value, stop scanning
  4623. } else {
  4624. if (val) *val = mg_str_n(sub.buf + o, (size_t) n);
  4625. ofs = (size_t) (&sub.buf[o + n] - obj.buf);
  4626. }
  4627. }
  4628. }
  4629. // MG_INFO(("SUB ofs %u %.*s", ofs, sub.len, sub.buf));
  4630. while (ofs && ofs < obj.len &&
  4631. (obj.buf[ofs] == ' ' || obj.buf[ofs] == '\t' ||
  4632. obj.buf[ofs] == '\n' || obj.buf[ofs] == '\r')) {
  4633. ofs++;
  4634. }
  4635. if (ofs && ofs < obj.len && obj.buf[ofs] == ',') ofs++;
  4636. if (ofs > obj.len) ofs = 0;
  4637. }
  4638. return ofs;
  4639. }
  4640. int mg_json_get(struct mg_str json, const char *path, int *toklen) {
  4641. const char *s = json.buf;
  4642. int len = (int) json.len;
  4643. enum { S_VALUE, S_KEY, S_COLON, S_COMMA_OR_EOO } expecting = S_VALUE;
  4644. unsigned char nesting[MG_JSON_MAX_DEPTH];
  4645. int i = 0; // Current offset in `s`
  4646. int j = 0; // Offset in `s` we're looking for (return value)
  4647. int depth = 0; // Current depth (nesting level)
  4648. int ed = 0; // Expected depth
  4649. int pos = 1; // Current position in `path`
  4650. int ci = -1, ei = -1; // Current and expected index in array
  4651. if (toklen) *toklen = 0;
  4652. if (path[0] != '$') return MG_JSON_INVALID;
  4653. #define MG_CHECKRET(x) \
  4654. do { \
  4655. if (depth == ed && path[pos] == '\0' && ci == ei) { \
  4656. if (toklen) *toklen = i - j + 1; \
  4657. return j; \
  4658. } \
  4659. } while (0)
  4660. // In the ascii table, the distance between `[` and `]` is 2.
  4661. // Ditto for `{` and `}`. Hence +2 in the code below.
  4662. #define MG_EOO(x) \
  4663. do { \
  4664. if (depth == ed && ci != ei) return MG_JSON_NOT_FOUND; \
  4665. if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
  4666. depth--; \
  4667. MG_CHECKRET(x); \
  4668. } while (0)
  4669. for (i = 0; i < len; i++) {
  4670. unsigned char c = ((unsigned char *) s)[i];
  4671. if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
  4672. switch (expecting) {
  4673. case S_VALUE:
  4674. // p("V %s [%.*s] %d %d %d %d\n", path, pos, path, depth, ed, ci, ei);
  4675. if (depth == ed) j = i;
  4676. if (c == '{') {
  4677. if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
  4678. if (depth == ed && path[pos] == '.' && ci == ei) {
  4679. // If we start the object, reset array indices
  4680. ed++, pos++, ci = ei = -1;
  4681. }
  4682. nesting[depth++] = c;
  4683. expecting = S_KEY;
  4684. break;
  4685. } else if (c == '[') {
  4686. if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
  4687. if (depth == ed && path[pos] == '[' && ei == ci) {
  4688. ed++, pos++, ci = 0;
  4689. for (ei = 0; path[pos] != ']' && path[pos] != '\0'; pos++) {
  4690. ei *= 10;
  4691. ei += path[pos] - '0';
  4692. }
  4693. if (path[pos] != 0) pos++;
  4694. }
  4695. nesting[depth++] = c;
  4696. break;
  4697. } else if (c == ']' && depth > 0) { // Empty array
  4698. MG_EOO(']');
  4699. } else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) {
  4700. i += 3;
  4701. } else if (c == 'n' && i + 3 < len && memcmp(&s[i], "null", 4) == 0) {
  4702. i += 3;
  4703. } else if (c == 'f' && i + 4 < len && memcmp(&s[i], "false", 5) == 0) {
  4704. i += 4;
  4705. } else if (c == '-' || ((c >= '0' && c <= '9'))) {
  4706. int numlen = 0;
  4707. mg_atod(&s[i], len - i, &numlen);
  4708. i += numlen - 1;
  4709. } else if (c == '"') {
  4710. int n = mg_pass_string(&s[i + 1], len - i - 1);
  4711. if (n < 0) return n;
  4712. i += n + 1;
  4713. } else {
  4714. return MG_JSON_INVALID;
  4715. }
  4716. MG_CHECKRET('V');
  4717. if (depth == ed && ei >= 0) ci++;
  4718. expecting = S_COMMA_OR_EOO;
  4719. break;
  4720. case S_KEY:
  4721. if (c == '"') {
  4722. int n = mg_pass_string(&s[i + 1], len - i - 1);
  4723. if (n < 0) return n;
  4724. if (i + 1 + n >= len) return MG_JSON_NOT_FOUND;
  4725. if (depth < ed) return MG_JSON_NOT_FOUND;
  4726. if (depth == ed && path[pos - 1] != '.') return MG_JSON_NOT_FOUND;
  4727. // printf("K %s [%.*s] [%.*s] %d %d %d %d %d\n", path, pos, path, n,
  4728. // &s[i + 1], n, depth, ed, ci, ei);
  4729. // NOTE(cpq): in the check sequence below is important.
  4730. // strncmp() must go first: it fails fast if the remaining length
  4731. // of the path is smaller than `n`.
  4732. if (depth == ed && path[pos - 1] == '.' &&
  4733. strncmp(&s[i + 1], &path[pos], (size_t) n) == 0 &&
  4734. (path[pos + n] == '\0' || path[pos + n] == '.' ||
  4735. path[pos + n] == '[')) {
  4736. pos += n;
  4737. }
  4738. i += n + 1;
  4739. expecting = S_COLON;
  4740. } else if (c == '}') { // Empty object
  4741. MG_EOO('}');
  4742. expecting = S_COMMA_OR_EOO;
  4743. if (depth == ed && ei >= 0) ci++;
  4744. } else {
  4745. return MG_JSON_INVALID;
  4746. }
  4747. break;
  4748. case S_COLON:
  4749. if (c == ':') {
  4750. expecting = S_VALUE;
  4751. } else {
  4752. return MG_JSON_INVALID;
  4753. }
  4754. break;
  4755. case S_COMMA_OR_EOO:
  4756. if (depth <= 0) {
  4757. return MG_JSON_INVALID;
  4758. } else if (c == ',') {
  4759. expecting = (nesting[depth - 1] == '{') ? S_KEY : S_VALUE;
  4760. } else if (c == ']' || c == '}') {
  4761. if (depth == ed && c == '}' && path[pos - 1] == '.')
  4762. return MG_JSON_NOT_FOUND;
  4763. if (depth == ed && c == ']' && path[pos - 1] == ',')
  4764. return MG_JSON_NOT_FOUND;
  4765. MG_EOO('O');
  4766. if (depth == ed && ei >= 0) ci++;
  4767. } else {
  4768. return MG_JSON_INVALID;
  4769. }
  4770. break;
  4771. }
  4772. }
  4773. return MG_JSON_NOT_FOUND;
  4774. }
  4775. struct mg_str mg_json_get_tok(struct mg_str json, const char *path) {
  4776. int len = 0, ofs = mg_json_get(json, path, &len);
  4777. return mg_str_n(ofs < 0 ? NULL : json.buf + ofs,
  4778. (size_t) (len < 0 ? 0 : len));
  4779. }
  4780. bool mg_json_get_num(struct mg_str json, const char *path, double *v) {
  4781. int n, toklen, found = 0;
  4782. if ((n = mg_json_get(json, path, &toklen)) >= 0 &&
  4783. (json.buf[n] == '-' || (json.buf[n] >= '0' && json.buf[n] <= '9'))) {
  4784. if (v != NULL) *v = mg_atod(json.buf + n, toklen, NULL);
  4785. found = 1;
  4786. }
  4787. return found;
  4788. }
  4789. bool mg_json_get_bool(struct mg_str json, const char *path, bool *v) {
  4790. int found = 0, off = mg_json_get(json, path, NULL);
  4791. if (off >= 0 && (json.buf[off] == 't' || json.buf[off] == 'f')) {
  4792. if (v != NULL) *v = json.buf[off] == 't';
  4793. found = 1;
  4794. }
  4795. return found;
  4796. }
  4797. size_t mg_json_unescape(struct mg_str json, const char *path, char *to,
  4798. size_t n) {
  4799. struct mg_str s = mg_json_get_tok(json, path);
  4800. size_t res = 0, i, j;
  4801. if (s.len > 1 && s.buf[0] == '"') { // Is is a string?
  4802. s.len -= 2, s.buf++; // Trim surrounding double-quotes
  4803. for (i = 0, j = 0; i < s.len && j < n; i++, j++) {
  4804. if (s.buf[i] == '\\' && i + 5 < s.len && s.buf[i + 1] == 'u') {
  4805. // \uXXXX escape. We process simple one-byte chars \u00xx within ASCII
  4806. // range. More complex chars would require dragging in a UTF8 library,
  4807. // which is too much for us
  4808. if (mg_str_to_num(mg_str_n(s.buf + i + 2, 4), 16, &to[j],
  4809. sizeof(uint8_t)) == false)
  4810. break;
  4811. i += 5;
  4812. } else if (s.buf[i] == '\\' && i + 1 < s.len) {
  4813. char c = json_esc(s.buf[i + 1], 0);
  4814. if (c == 0) return false;
  4815. to[j] = c;
  4816. i++;
  4817. } else {
  4818. to[j] = s.buf[i];
  4819. }
  4820. }
  4821. if (j < n) res = j;
  4822. if (n > 0) to[j < n ? j : n - 1] = '\0';
  4823. }
  4824. return res;
  4825. }
  4826. char *mg_json_get_str(struct mg_str json, const char *path) {
  4827. char *result = NULL;
  4828. int len = 0, off = mg_json_get(json, path, &len);
  4829. if (off >= 0 && len >= 2 && json.buf[off] == '"') {
  4830. if ((result = (char *) mg_calloc(1, (size_t) len)) != NULL &&
  4831. len > 2 && mg_json_unescape(json, path, result, (size_t) len) == 0) {
  4832. mg_free(result);
  4833. result = NULL;
  4834. }
  4835. }
  4836. return result;
  4837. }
  4838. char *mg_json_get_b64(struct mg_str json, const char *path, int *slen) {
  4839. char *result = NULL;
  4840. int len = 0, off = mg_json_get(json, path, &len);
  4841. if (off >= 0 && json.buf[off] == '"' && len > 1 &&
  4842. (result = (char *) mg_calloc(1, (size_t) len)) != NULL) {
  4843. size_t k = mg_base64_decode(json.buf + off + 1, (size_t) (len - 2), result,
  4844. (size_t) len);
  4845. if (slen != NULL) *slen = (int) k;
  4846. }
  4847. return result;
  4848. }
  4849. char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) {
  4850. char *result = NULL;
  4851. int len = 0, off = mg_json_get(json, path, &len);
  4852. if (off >= 0 && json.buf[off] == '"' && len > 1 && (len - 2) % 2 == 0 &&
  4853. (result = (char *) mg_calloc(1, (size_t) len / 2)) != NULL) {
  4854. int i;
  4855. for (i = 0; i < len - 2; i += 2) {
  4856. if (!mg_str_to_num(mg_str_n(json.buf + off + 1 + i, 2), 16,
  4857. &result[i >> 1], sizeof(uint8_t))) break;
  4858. }
  4859. if (i < len - 2) mg_free(result), result = NULL;
  4860. if (result != NULL) {
  4861. result[len / 2 - 1] = '\0';
  4862. if (slen != NULL) *slen = len / 2 - 1;
  4863. }
  4864. }
  4865. return result;
  4866. }
  4867. long mg_json_get_long(struct mg_str json, const char *path, long dflt) {
  4868. double dv;
  4869. long result = dflt;
  4870. if (mg_json_get_num(json, path, &dv)) result = (long) dv;
  4871. return result;
  4872. }
  4873. #ifdef MG_ENABLE_LINES
  4874. #line 1 "src/jwt.c"
  4875. #endif
  4876. #if MG_TLS == MG_TLS_BUILTIN
  4877. #endif
  4878. static size_t jwt_split(struct mg_str jwt, struct mg_str *h, struct mg_str *p,
  4879. struct mg_str *s) {
  4880. size_t i, a = jwt.len, b = jwt.len;
  4881. for (i = 0; i < jwt.len; i++) {
  4882. if (jwt.buf[i] == '.') {
  4883. if (a == jwt.len) a = i;
  4884. if (a != i) b = i;
  4885. if (b != jwt.len) break;
  4886. }
  4887. }
  4888. if (a == jwt.len || b == jwt.len || b + 1 >= jwt.len) return 0;
  4889. *h = mg_str_n(jwt.buf, a);
  4890. *p = mg_str_n(jwt.buf + a + 1, b - a - 1);
  4891. *s = mg_str_n(jwt.buf + b + 1, jwt.len - b - 1);
  4892. return b;
  4893. }
  4894. static bool jwt_alg(struct mg_str h, const char *alg) {
  4895. char got[16];
  4896. size_t len = h.len * 3 / 4 + 2;
  4897. char *buf = (char *) mg_calloc(1, len);
  4898. bool ok;
  4899. if (buf == NULL) return false;
  4900. ok = mg_base64url_decode(h.buf, h.len, buf, len) > 0 &&
  4901. mg_json_unescape(mg_str(buf), "$.alg", got, sizeof(got)) > 0 &&
  4902. strcmp(got, alg) == 0;
  4903. mg_free(buf);
  4904. return ok;
  4905. }
  4906. static size_t jwt_header_payload(const char *alg, const struct mg_jwt_opts *opts,
  4907. char *buf, size_t len) {
  4908. char *header, *kid = NULL;
  4909. size_t n, m;
  4910. if (opts->kid.len > 0) {
  4911. kid = mg_mprintf(",%m:%m", MG_ESC("kid"), mg_print_esc,
  4912. (int) opts->kid.len, opts->kid.buf);
  4913. if (kid == NULL) return 0;
  4914. }
  4915. header = mg_mprintf("{%m:%m,%m:%m%.*s%.*s%.*s}", MG_ESC("alg"),
  4916. MG_ESC(alg), MG_ESC("typ"), MG_ESC("JWT"),
  4917. kid == NULL ? 0 : (int) strlen(kid),
  4918. kid == NULL ? "" : kid,
  4919. opts->header.len > 0 ? 1 : 0, ",",
  4920. (int) opts->header.len, opts->header.buf);
  4921. mg_free(kid);
  4922. if (header == NULL) return 0;
  4923. n = mg_base64url_encode((uint8_t *) header, strlen(header), buf, len);
  4924. mg_free(header);
  4925. if (n == 0 || n + 1 >= len) return 0;
  4926. buf[n++] = '.';
  4927. m = mg_base64url_encode((uint8_t *) opts->claims.buf, opts->claims.len,
  4928. buf + n, len - n);
  4929. return m == 0 ? 0 : n + m;
  4930. }
  4931. size_t mg_jwt_sign_hs256(const struct mg_jwt_opts *opts, char *buf,
  4932. size_t len) {
  4933. uint8_t sig[32];
  4934. size_t n = jwt_header_payload("HS256", opts, buf, len);
  4935. size_t m;
  4936. if (n == 0 || n + 1 >= len) return 0;
  4937. mg_hmac_sha256(sig, (uint8_t *) opts->secret.buf, opts->secret.len,
  4938. (uint8_t *) buf, n);
  4939. buf[n++] = '.';
  4940. m = mg_base64url_encode(sig, sizeof(sig), buf + n, len - n);
  4941. return m == 0 ? 0 : n + m;
  4942. }
  4943. size_t mg_jwt_verify_hs256(struct mg_str jwt, const struct mg_jwt_opts *opts,
  4944. char *buf, size_t len) {
  4945. struct mg_str h, p, s;
  4946. uint8_t sig[33], digest[32];
  4947. size_t n = jwt_split(jwt, &h, &p, &s);
  4948. if (n == 0 || !jwt_alg(h, "HS256")) return 0;
  4949. if (mg_base64url_decode(s.buf, s.len, (char *) sig, sizeof(sig)) !=
  4950. sizeof(digest))
  4951. return 0;
  4952. mg_hmac_sha256(digest, (uint8_t *) opts->secret.buf, opts->secret.len,
  4953. (uint8_t *) jwt.buf, n);
  4954. if (!mg_memeq(sig, digest, sizeof(digest))) return 0;
  4955. return mg_base64url_decode(p.buf, p.len, buf, len);
  4956. }
  4957. #if MG_TLS == MG_TLS_BUILTIN
  4958. typedef struct {
  4959. MG_UECC_HashContext uECC;
  4960. mg_sha256_ctx sha256;
  4961. } jwt_hash_ctx;
  4962. static void jwt_hash_init(const MG_UECC_HashContext *ctx) {
  4963. jwt_hash_ctx *c = (jwt_hash_ctx *) ctx;
  4964. mg_sha256_init(&c->sha256);
  4965. }
  4966. static void jwt_hash_update(const MG_UECC_HashContext *ctx, const uint8_t *msg,
  4967. unsigned len) {
  4968. jwt_hash_ctx *c = (jwt_hash_ctx *) ctx;
  4969. mg_sha256_update(&c->sha256, msg, len);
  4970. }
  4971. static void jwt_hash_finish(const MG_UECC_HashContext *ctx, uint8_t *hash) {
  4972. jwt_hash_ctx *c = (jwt_hash_ctx *) ctx;
  4973. mg_sha256_final(hash, &c->sha256);
  4974. }
  4975. size_t mg_jwt_sign_es256(const struct mg_jwt_opts *opts, char *buf,
  4976. size_t len) {
  4977. uint8_t hash[32], sig[64], tmp[2 * 32 + 64];
  4978. jwt_hash_ctx ctx = {
  4979. {jwt_hash_init, jwt_hash_update, jwt_hash_finish, 64, 32, tmp},
  4980. {{0}, 0, 0, {0}}};
  4981. size_t n = jwt_header_payload("ES256", opts, buf, len);
  4982. size_t m;
  4983. if (n == 0 || n + 1 >= len) return 0;
  4984. mg_sha256(hash, (uint8_t *) buf, n);
  4985. if (mg_uecc_sign_deterministic(opts->private_key, hash, sizeof(hash),
  4986. &ctx.uECC, sig, mg_uecc_secp256r1()) != 1)
  4987. return 0;
  4988. buf[n++] = '.';
  4989. m = mg_base64url_encode(sig, sizeof(sig), buf + n, len - n);
  4990. return m == 0 ? 0 : n + m;
  4991. }
  4992. size_t mg_jwt_verify_es256(struct mg_str jwt, const struct mg_jwt_opts *opts,
  4993. char *buf, size_t len) {
  4994. struct mg_str h, p, s;
  4995. uint8_t sig[65], hash[32];
  4996. size_t n = jwt_split(jwt, &h, &p, &s);
  4997. if (n == 0 || !jwt_alg(h, "ES256")) return 0;
  4998. if (mg_base64url_decode(s.buf, s.len, (char *) sig, sizeof(sig)) != 64)
  4999. return 0;
  5000. mg_sha256(hash, (uint8_t *) jwt.buf, n);
  5001. if (mg_uecc_verify(opts->public_key, hash, sizeof(hash), sig,
  5002. mg_uecc_secp256r1()) != 1)
  5003. return 0;
  5004. return mg_base64url_decode(p.buf, p.len, buf, len);
  5005. }
  5006. #else
  5007. size_t mg_jwt_sign_es256(const struct mg_jwt_opts *opts, char *buf,
  5008. size_t len) {
  5009. (void) opts, (void) buf, (void) len;
  5010. MG_ERROR(("JWT ES256 requires built-in TLS"));
  5011. return 0;
  5012. }
  5013. size_t mg_jwt_verify_es256(struct mg_str jwt, const struct mg_jwt_opts *opts,
  5014. char *buf, size_t len) {
  5015. (void) jwt, (void) opts, (void) buf, (void) len;
  5016. return mg_jwt_sign_es256(NULL, NULL, 0);
  5017. }
  5018. #endif
  5019. #ifdef MG_ENABLE_LINES
  5020. #line 1 "src/l2.c"
  5021. #endif
  5022. #if MG_ENABLE_TCPIP
  5023. // L2 API
  5024. void mg_l2_init(struct mg_tcpip_if *ifp);
  5025. bool mg_l2_poll(struct mg_tcpip_if *ifp, bool expired_1000ms);
  5026. uint8_t *mg_l2_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
  5027. uint8_t *src, uint8_t *dst, uint8_t *frame);
  5028. size_t mg_l2_trailer(struct mg_tcpip_if *ifp, size_t len, uint8_t *cur);
  5029. bool mg_l2_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
  5030. struct mg_str *pay, struct mg_str *raw);
  5031. uint8_t *mg_l2_getaddr(struct mg_tcpip_if *ifp, uint8_t *frame);
  5032. uint8_t *mg_l2_mapip(enum mg_l2type type, enum mg_l2addrtype addrtype,
  5033. struct mg_addr *ip);
  5034. #if MG_ENABLE_IPV6
  5035. bool mg_l2_genip6(enum mg_l2type type, uint64_t *ip6, uint8_t prefix_len,
  5036. uint8_t *addr);
  5037. bool mg_l2_ip6get(enum mg_l2type type, uint8_t *addr, uint8_t *opts,
  5038. uint8_t len);
  5039. uint8_t mg_l2_ip6put(enum mg_l2type type, uint8_t *addr, uint8_t *opts);
  5040. #endif
  5041. size_t mg_l2_driver_output(struct mg_tcpip_if *ifp, size_t len);
  5042. // clang-format off
  5043. extern void mg_l2_eth_init(struct mg_tcpip_if *);
  5044. extern bool mg_l2_eth_poll(struct mg_tcpip_if *, bool);
  5045. extern uint8_t *mg_l2_eth_header(struct mg_tcpip_if *, enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *);
  5046. extern size_t mg_l2_eth_trailer(struct mg_tcpip_if *, size_t, uint8_t *);
  5047. extern bool mg_l2_eth_rx(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
  5048. extern struct mg_l2addr *mg_l2_eth_getaddr(struct mg_tcpip_if *, uint8_t *);
  5049. extern struct mg_l2addr *mg_l2_eth_mapip(enum mg_l2addrtype, struct mg_addr *);
  5050. #if MG_ENABLE_IPV6
  5051. extern bool mg_l2_eth_genip6(uint64_t *, uint8_t, struct mg_l2addr *);
  5052. extern bool mg_l2_eth_ip6get(struct mg_l2addr *, uint8_t *, uint8_t);
  5053. extern uint8_t mg_l2_eth_ip6put(struct mg_l2addr *, uint8_t *);
  5054. #endif
  5055. extern void mg_l2_ppp_init(struct mg_tcpip_if *);
  5056. extern bool mg_l2_ppp_poll(struct mg_tcpip_if *, bool);
  5057. extern uint8_t *mg_l2_ppp_header(struct mg_tcpip_if *, enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *);
  5058. extern size_t mg_l2_ppp_trailer(struct mg_tcpip_if *, size_t, uint8_t *);
  5059. extern bool mg_l2_ppp_rx(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
  5060. extern struct mg_l2addr *mg_l2_ppp_getaddr(struct mg_tcpip_if *, uint8_t *);
  5061. extern struct mg_l2addr *mg_l2_ppp_mapip(enum mg_l2addrtype, struct mg_addr *);
  5062. #if MG_ENABLE_IPV6
  5063. extern bool mg_l2_ppp_genip6(uint64_t *, uint8_t, struct mg_l2addr *);
  5064. extern bool mg_l2_ppp_ip6get(struct mg_l2addr *, uint8_t *, uint8_t);
  5065. extern uint8_t mg_l2_ppp_ip6put(struct mg_l2addr *, uint8_t *);
  5066. #endif
  5067. extern void mg_l2_pppoe_init(struct mg_tcpip_if *);
  5068. extern bool mg_l2_pppoe_poll(struct mg_tcpip_if *, bool);
  5069. extern uint8_t *mg_l2_pppoe_header(struct mg_tcpip_if *, enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *);
  5070. extern size_t mg_l2_pppoe_trailer(struct mg_tcpip_if *, size_t, uint8_t *);
  5071. extern bool mg_l2_pppoe_rx(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
  5072. typedef void (*l2_init_fn)(struct mg_tcpip_if *);
  5073. typedef bool (*l2_poll_fn)(struct mg_tcpip_if *, bool);
  5074. typedef uint8_t *((*l2_header_fn)(struct mg_tcpip_if *, enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *));
  5075. typedef size_t (*l2_trailer_fn)(struct mg_tcpip_if *, size_t, uint8_t *);
  5076. typedef bool (*l2_rx_fn)(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
  5077. typedef struct mg_l2addr (*(*l2_getaddr_fn)(struct mg_tcpip_if *, uint8_t *));
  5078. typedef struct mg_l2addr (*(*l2_mapip_fn)(enum mg_l2addrtype, struct mg_addr *));
  5079. #if MG_ENABLE_IPV6
  5080. typedef bool (*l2_genip6_fn)(uint64_t *, uint8_t, struct mg_l2addr *);
  5081. typedef bool (*l2_ip6get_fn)(struct mg_l2addr *, uint8_t *, uint8_t);
  5082. typedef uint8_t (*l2_ip6put_fn)(struct mg_l2addr *, uint8_t *);
  5083. #endif
  5084. // clang-format on
  5085. static const l2_init_fn l2_init[] = {mg_l2_eth_init, mg_l2_ppp_init,
  5086. mg_l2_pppoe_init};
  5087. static const l2_poll_fn l2_poll[] = {mg_l2_eth_poll, mg_l2_ppp_poll,
  5088. mg_l2_pppoe_poll};
  5089. static const l2_header_fn l2_header[] = {mg_l2_eth_header, mg_l2_ppp_header,
  5090. mg_l2_pppoe_header};
  5091. static const l2_trailer_fn l2_trailer[] = {mg_l2_eth_trailer, mg_l2_ppp_trailer,
  5092. mg_l2_pppoe_trailer};
  5093. static const l2_rx_fn l2_rx[] = {mg_l2_eth_rx, mg_l2_ppp_rx, mg_l2_pppoe_rx};
  5094. static const l2_getaddr_fn l2_getaddr[] = {mg_l2_eth_getaddr, mg_l2_ppp_getaddr,
  5095. mg_l2_ppp_getaddr};
  5096. static const l2_mapip_fn l2_mapip[] = {mg_l2_eth_mapip, mg_l2_ppp_mapip,
  5097. mg_l2_ppp_mapip};
  5098. #if MG_ENABLE_IPV6
  5099. static const l2_genip6_fn l2_genip6[] = {mg_l2_eth_genip6, mg_l2_ppp_genip6,
  5100. mg_l2_ppp_genip6};
  5101. static const l2_ip6get_fn l2_ip6get[] = {mg_l2_eth_ip6get, mg_l2_ppp_ip6get,
  5102. mg_l2_ppp_ip6get};
  5103. static const l2_ip6put_fn l2_ip6put[] = {mg_l2_eth_ip6put, mg_l2_ppp_ip6put,
  5104. mg_l2_ppp_ip6put};
  5105. #endif
  5106. void mg_l2_init(struct mg_tcpip_if *ifp) {
  5107. l2_init[ifp->l2type](ifp);
  5108. }
  5109. bool mg_l2_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) {
  5110. return l2_poll[ifp->l2type](ifp, expired_1000ms);
  5111. }
  5112. uint8_t *mg_l2_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
  5113. uint8_t *src, uint8_t *dst, uint8_t *frame) {
  5114. return l2_header[ifp->l2type](ifp, proto, (struct mg_l2addr *) src,
  5115. (struct mg_l2addr *) dst, frame);
  5116. }
  5117. size_t mg_l2_trailer(struct mg_tcpip_if *ifp, size_t len, uint8_t *frame) {
  5118. return l2_trailer[ifp->l2type](ifp, len, frame);
  5119. }
  5120. bool mg_l2_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
  5121. struct mg_str *pay, struct mg_str *raw) {
  5122. return l2_rx[ifp->l2type](ifp, proto, pay, raw);
  5123. }
  5124. uint8_t *mg_l2_getaddr(struct mg_tcpip_if *ifp, uint8_t *frame) {
  5125. return (uint8_t *) l2_getaddr[ifp->l2type](ifp, frame);
  5126. }
  5127. struct mg_l2addr s_mapip;
  5128. uint8_t *mg_l2_mapip(enum mg_l2type type, enum mg_l2addrtype addrtype,
  5129. struct mg_addr *ip) {
  5130. return (uint8_t *) l2_mapip[type](addrtype, ip);
  5131. }
  5132. #if MG_ENABLE_IPV6
  5133. bool mg_l2_genip6(enum mg_l2type type, uint64_t *ip6, uint8_t prefix_len,
  5134. uint8_t *addr) {
  5135. return l2_genip6[type](ip6, prefix_len, (struct mg_l2addr *) addr);
  5136. }
  5137. bool mg_l2_ip6get(enum mg_l2type type, uint8_t *addr, uint8_t *opts,
  5138. uint8_t len) {
  5139. return l2_ip6get[type]((struct mg_l2addr *) addr, opts, len);
  5140. }
  5141. uint8_t mg_l2_ip6put(enum mg_l2type type, uint8_t *addr, uint8_t *opts) {
  5142. return l2_ip6put[type]((struct mg_l2addr *) addr, opts);
  5143. }
  5144. #endif
  5145. size_t mg_l2_driver_output(struct mg_tcpip_if *ifp, size_t len) {
  5146. size_t n = ifp->driver->tx(ifp->tx.buf, len, ifp);
  5147. if (n == len) ifp->nsent++;
  5148. return n;
  5149. }
  5150. #endif
  5151. #ifdef MG_ENABLE_LINES
  5152. #line 1 "src/l2_eth.c"
  5153. #endif
  5154. #if MG_ENABLE_TCPIP
  5155. #if defined(__DCC__)
  5156. #pragma pack(1)
  5157. #else
  5158. #pragma pack(push, 1)
  5159. #endif
  5160. struct eth {
  5161. uint8_t dst[6]; // Destination MAC address
  5162. uint8_t src[6]; // Source MAC address
  5163. uint16_t type; // Ethernet type
  5164. };
  5165. struct qtag {
  5166. uint16_t tpid; // Ethernet 802.1Q type
  5167. uint16_t tci; // PCP, DEI, VLAN id
  5168. #define VLAN_ID(x) ((uint16_t) ((x) &0x0FFF))
  5169. };
  5170. #if defined(__DCC__)
  5171. #pragma pack(0)
  5172. #else
  5173. #pragma pack(pop)
  5174. #endif
  5175. static const uint16_t eth_types[] = {
  5176. // order is vital, see l2.h
  5177. 0x800, // IPv4
  5178. 0x86dd, // IPv6
  5179. 0x806, // ARP
  5180. 0x8863, // PPPoE Discovery Stage
  5181. 0x8864 // PPPoE Session Stage
  5182. };
  5183. void mg_l2_eth_init(struct mg_tcpip_if *ifp) {
  5184. struct mg_l2addr *l2addr = (struct mg_l2addr *) ifp->mac;
  5185. // If MAC is not set, make a random one
  5186. if (l2addr->addr.mac[0] == 0 && l2addr->addr.mac[1] == 0 &&
  5187. l2addr->addr.mac[2] == 0 && l2addr->addr.mac[3] == 0 &&
  5188. l2addr->addr.mac[4] == 0 && l2addr->addr.mac[5] == 0) {
  5189. l2addr->addr.mac[0] = 0x02; // Locally administered, unicast
  5190. mg_random(&l2addr->addr.mac[1], sizeof(l2addr->addr.mac) - 1);
  5191. MG_INFO(
  5192. ("MAC not set. Generated random: %M", mg_print_mac, l2addr->addr.mac));
  5193. }
  5194. ifp->l2mtu = 1500;
  5195. ifp->framesize = 1540;
  5196. }
  5197. bool mg_l2_eth_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) {
  5198. (void) ifp;
  5199. (void) expired_1000ms;
  5200. return true;
  5201. }
  5202. uint8_t *mg_l2_eth_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
  5203. struct mg_l2addr *src, struct mg_l2addr *dst,
  5204. uint8_t *frame) {
  5205. struct eth_data *d = &ifp->l2data.eth;
  5206. struct eth *eth = (struct eth *) frame;
  5207. uint8_t *hlp;
  5208. hlp = (uint8_t *) (eth + 1);
  5209. memcpy(eth->src, src->addr.mac, sizeof(eth->dst));
  5210. memcpy(eth->dst, dst->addr.mac, sizeof(eth->dst));
  5211. if (d->vlan_id == 0) { // Traditional plain frame
  5212. eth->type = mg_htons(eth_types[(unsigned int) proto]);
  5213. } else { // Add 802.1Q tag
  5214. struct qtag *qtag = (struct qtag *) &eth->type;
  5215. qtag->tpid = mg_htons(0x8100);
  5216. qtag->tci = mg_htons(d->vlan_id); // PCP = default (best-effort)
  5217. hlp += sizeof(*qtag);
  5218. MG_STORE_BE16(qtag + 1, eth_types[(unsigned int) proto]);
  5219. }
  5220. return hlp;
  5221. }
  5222. size_t mg_l2_eth_trailer(struct mg_tcpip_if *ifp, size_t len, uint8_t *cur) {
  5223. struct eth_data *d = &ifp->l2data.eth;
  5224. // there is no len field in Ethernet, CRC is hw-calculated; pad to 64 - CRC
  5225. size_t ethlen =
  5226. len + sizeof(struct eth) + (d->vlan_id != 0 ? sizeof(struct qtag) : 0);
  5227. (void) cur;
  5228. return ethlen >= 60 ? ethlen : 60;
  5229. }
  5230. struct mg_l2addr *mg_l2_eth_mapip(enum mg_l2addrtype addrtype,
  5231. struct mg_addr *addr);
  5232. // Read an unaligned little-endian value from byte pointer p into a native integer.
  5233. // Safe on architectures that forbid unaligned access (e.g. Cortex-M0).
  5234. #define MG_LOAD_LE32(p) \
  5235. ((uint32_t) (((uint32_t) MG_U8P(p)[3] << 24U) | \
  5236. ((uint32_t) MG_U8P(p)[2] << 16U) | \
  5237. ((uint32_t) MG_U8P(p)[1] << 8U) | MG_U8P(p)[0]))
  5238. bool mg_l2_eth_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
  5239. struct mg_str *pay, struct mg_str *raw) {
  5240. struct eth *eth = (struct eth *) raw->buf;
  5241. struct eth_data *d = &ifp->l2data.eth;
  5242. uint16_t type, len;
  5243. unsigned int i;
  5244. size_t hdrlen =
  5245. sizeof(struct eth) + (d->vlan_id != 0 ? sizeof(struct qtag) : 0);
  5246. if (raw->len < hdrlen) return false; // Truncated - runt?
  5247. len = (uint16_t) raw->len;
  5248. if (d->vlan_id == 0) { // We don't handle VLANs
  5249. type = mg_ntohs(eth->type);
  5250. } else { // We do, check 802.1Q tag
  5251. struct qtag *qtag = (struct qtag *) &eth->type;
  5252. if (qtag->tpid != mg_htons(0x8100)) return false; // Untagged frame
  5253. if (VLAN_ID(mg_ntohs(qtag->tci)) != VLAN_ID(d->vlan_id))
  5254. return false; // Not our VLAN
  5255. type = MG_LOAD_BE16(qtag + 1);
  5256. }
  5257. if (ifp->enable_mac_check &&
  5258. memcmp(eth->dst, ifp->mac, sizeof(eth->dst)) != 0 &&
  5259. memcmp(eth->dst, mg_l2_eth_mapip(MG_TCPIP_L2ADDR_BCAST, NULL),
  5260. sizeof(eth->dst)) != 0)
  5261. return false; // TODO(): add multicast addresses
  5262. if (ifp->enable_fcs_check && len > hdrlen + 4) {
  5263. uint32_t crc, crc_rx;
  5264. len -= 4;
  5265. crc = mg_crc32(0, (const char *) raw->buf, len);
  5266. crc_rx = MG_LOAD_LE32(raw->buf + len);
  5267. if (crc_rx != crc)
  5268. return false;
  5269. }
  5270. pay->buf = ((char *) eth) + hdrlen;
  5271. pay->len = len - hdrlen;
  5272. for (i = 0; i < sizeof(eth_types) / sizeof(uint16_t); i++) {
  5273. if (type == eth_types[i]) break;
  5274. }
  5275. if (i == sizeof(eth_types) / sizeof(eth_types[0])) {
  5276. MG_DEBUG(("Unknown eth type %x", type));
  5277. if (mg_log_level >= MG_LL_VERBOSE)
  5278. mg_hexdump(raw->buf, raw->len >= 32 ? 32 : raw->len);
  5279. return false;
  5280. }
  5281. *proto = (enum mg_l2proto) i;
  5282. return true;
  5283. }
  5284. struct mg_l2addr *mg_l2_eth_getaddr(struct mg_tcpip_if *ifp, uint8_t *frame) {
  5285. struct eth *eth = (struct eth *) frame;
  5286. (void) ifp; // address field is before a possible 802.1Q tag
  5287. return (struct mg_l2addr *) &eth->src;
  5288. }
  5289. extern struct mg_l2addr s_mapip;
  5290. struct mg_l2addr *mg_l2_eth_mapip(enum mg_l2addrtype addrtype,
  5291. struct mg_addr *addr) {
  5292. switch (addrtype) {
  5293. case MG_TCPIP_L2ADDR_BCAST:
  5294. memset(s_mapip.addr.mac, 0xff, sizeof(s_mapip.addr.mac));
  5295. break;
  5296. case MG_TCPIP_L2ADDR_MCAST: {
  5297. uint8_t *ip = (uint8_t *) &addr->addr.ip4;
  5298. // IP multicast group MAC, RFC-1112 6.4
  5299. s_mapip.addr.mac[0] = 0x01, s_mapip.addr.mac[1] = 0x00,
  5300. s_mapip.addr.mac[2] = 0x5E;
  5301. s_mapip.addr.mac[3] = ip[1] & 0x7F; // 23 LSb
  5302. s_mapip.addr.mac[4] = ip[2];
  5303. s_mapip.addr.mac[5] = ip[3];
  5304. break;
  5305. }
  5306. case MG_TCPIP_L2ADDR_MCAST6: {
  5307. // IPv6 multicast address mapping, RFC-2464 7
  5308. uint8_t *ip = (uint8_t *) &addr->addr.ip6;
  5309. s_mapip.addr.mac[0] = 0x33, s_mapip.addr.mac[1] = 0x33;
  5310. s_mapip.addr.mac[2] = ip[12], s_mapip.addr.mac[3] = ip[13],
  5311. s_mapip.addr.mac[4] = ip[14], s_mapip.addr.mac[5] = ip[15];
  5312. break;
  5313. }
  5314. }
  5315. return &s_mapip;
  5316. }
  5317. #if MG_ENABLE_IPV6
  5318. static void meui64(uint8_t *addr, uint8_t *mac) {
  5319. *addr++ = *mac++ ^ (uint8_t) 0x02, *addr++ = *mac++, *addr++ = *mac++;
  5320. *addr++ = 0xff, *addr++ = 0xfe;
  5321. *addr++ = *mac++, *addr++ = *mac++, *addr = *mac;
  5322. }
  5323. bool mg_l2_eth_genip6(uint64_t *ip6, uint8_t prefix_len,
  5324. struct mg_l2addr *l2addr) {
  5325. if (prefix_len > 64) {
  5326. MG_ERROR(("Prefix length > 64, UNSUPPORTED"));
  5327. return false;
  5328. }
  5329. ip6[0] = 0;
  5330. meui64(((uint8_t *) &ip6[1]), l2addr->addr.mac); // RFC-4291 2.5.4, 2.5.1
  5331. return true;
  5332. }
  5333. bool mg_l2_eth_ip6get(struct mg_l2addr *l2addr, uint8_t *opts, uint8_t len) {
  5334. if (len != 1) return false;
  5335. memcpy(l2addr->addr.mac, opts, 6);
  5336. return true;
  5337. }
  5338. uint8_t mg_l2_eth_ip6put(struct mg_l2addr *l2addr, uint8_t *opts) {
  5339. memcpy(opts, l2addr->addr.mac, 6);
  5340. return 1;
  5341. }
  5342. #endif
  5343. #endif
  5344. #ifdef MG_ENABLE_LINES
  5345. #line 1 "src/l2_ppp.c"
  5346. #endif
  5347. #if MG_ENABLE_TCPIP
  5348. #if defined(__DCC__)
  5349. #pragma pack(1)
  5350. #else
  5351. #pragma pack(push, 1)
  5352. #endif
  5353. // all in network order
  5354. struct ppp { // RFC-1661
  5355. uint16_t proto;
  5356. };
  5357. struct lcp { // RFC-1661
  5358. uint8_t code, id;
  5359. uint16_t len;
  5360. };
  5361. struct ipcp { // RFC-1332
  5362. uint8_t code, id;
  5363. uint16_t len;
  5364. };
  5365. struct ipv6cp { // RFC-5072
  5366. uint8_t code, id;
  5367. uint16_t len;
  5368. };
  5369. struct hdlc_ { // RFC-1662, "PPP in HDLC-like Framing"
  5370. uint8_t addr, ctrl;
  5371. };
  5372. struct pppoe { // RFC-2516, "A Method for Transmitting PPP Over Ethernet
  5373. // (PPPoE)"
  5374. uint8_t vertype, code;
  5375. uint16_t id, len;
  5376. };
  5377. #if defined(__DCC__)
  5378. #pragma pack(0)
  5379. #else
  5380. #pragma pack(pop)
  5381. #endif
  5382. #define MG_PPP_ADDR 0xff
  5383. #define MG_PPP_CTRL 0x03
  5384. #define MG_PPP_PROTO_IP 0x0021
  5385. #define MG_PPP_PROTO_IPV6 0x0057
  5386. #define MG_PPP_PROTO_LCP 0xc021
  5387. #define MG_PPP_PROTO_IPCP 0x8021
  5388. #define MG_PPP_PROTO_IPV6CP 0x8057
  5389. #define MG_PPP_PROTO_PAP 0xc023
  5390. #define MG_PPP_PROTO_CHAP 0xc223
  5391. #define MG_PPP_LCP_CFG_REQ 1
  5392. #define MG_PPP_LCP_CFG_ACK 2
  5393. #define MG_PPP_LCP_CFG_NACK 3
  5394. #define MG_PPP_LCP_CFG_REJECT 4
  5395. #define MG_PPP_LCP_CFG_TERM_REQ 5
  5396. #define MG_PPP_LCP_CFG_TERM_ACK 6
  5397. #define MG_PPP_LCP_REJECT 8
  5398. #define MG_PPP_LCP_ECHO_REQ 9
  5399. #define MG_PPP_LCP_ECHO_REPLY 10
  5400. #define MG_PPP_IPCP_CFG_REQ 1
  5401. #define MG_PPP_IPCP_CFG_ACK 2
  5402. #define MG_PPP_IPCP_CFG_NACK 3
  5403. #define MG_PPP_IPCP_CFG_REJECT 4
  5404. #define MG_PPP_IPCP_OPT_IPADDR 3
  5405. #define MG_PPP_IPV6CP_CFG_REQ 1
  5406. #define MG_PPP_IPV6CP_CFG_ACK 2
  5407. #define MG_PPP_IPV6CP_CFG_NACK 3
  5408. #define MG_PPP_IPV6CP_CFG_REJECT 4
  5409. #define MG_PPP_IPV6CP_OPT_IFCID 1
  5410. #define MG_PPPoE_PADI 0x09
  5411. #define MG_PPPoE_PADO 0x07
  5412. #define MG_PPPoE_PADR 0x19
  5413. #define MG_PPPoE_PADS 0x65
  5414. #define MG_PPPoE_PADT 0xa7
  5415. #define MG_PPPoE_ST_DISC 0 // Discovery phase, see what servers are out there
  5416. #define MG_PPPoE_ST_REQ 1 // Chose a server, request a session and wait
  5417. #define MG_PPPoE_ST_SESS 2 // Session established, PPP traffic is exchanged
  5418. #define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
  5419. static bool s_lcpup = false; // ************ THESE SHOULD MOVE TO A struct
  5420. // mg_l2data *******************************
  5421. static uint8_t s_state = MG_PPPoE_ST_DISC;
  5422. static uint16_t s_id;
  5423. void mg_l2_ppp_init(struct mg_tcpip_if *ifp) {
  5424. ifp->l2mtu = 1500;
  5425. ifp->framesize = 1500 + sizeof(struct ppp) + sizeof(struct hdlc_);
  5426. }
  5427. extern void mg_l2_eth_init(struct mg_tcpip_if *);
  5428. void mg_l2_pppoe_init(struct mg_tcpip_if *ifp) {
  5429. mg_l2_eth_init(ifp);
  5430. ifp->l2mtu = ifp->l2mtu - (uint16_t) (sizeof(struct pppoe) +
  5431. sizeof(struct ppp)); // 1500 --> 1492
  5432. }
  5433. bool mg_l2_ppp_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) {
  5434. if (expired_1000ms && ifp->state == MG_TCPIP_STATE_DOWN) s_lcpup = false;
  5435. return s_lcpup;
  5436. }
  5437. static uint8_t *hdlc_header(uint8_t *p) {
  5438. struct hdlc_ *hdlc = (struct hdlc_ *) p;
  5439. hdlc->addr = MG_PPP_ADDR;
  5440. hdlc->ctrl = MG_PPP_CTRL;
  5441. return (uint8_t *) (hdlc + 1);
  5442. }
  5443. static uint8_t *ppp_header(uint16_t proto, uint8_t *p) {
  5444. struct ppp *ppp = (struct ppp *) p;
  5445. ppp->proto = mg_htons(proto);
  5446. return (uint8_t *) (ppp + 1);
  5447. }
  5448. static uint8_t *l2_ppp_header(enum mg_l2proto proto, uint8_t *p) {
  5449. uint16_t ppp_proto = proto == MG_TCPIP_L2PROTO_IPV4 ? MG_PPP_PROTO_IP
  5450. : proto == MG_TCPIP_L2PROTO_IPV4 ? MG_PPP_PROTO_IPV6
  5451. : 0;
  5452. return ppp_header(ppp_proto, p);
  5453. }
  5454. uint8_t *mg_l2_ppp_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
  5455. struct mg_l2addr *src, struct mg_l2addr *dst,
  5456. uint8_t *frame) {
  5457. (void) ifp;
  5458. (void) src;
  5459. (void) dst;
  5460. return l2_ppp_header(proto, hdlc_header(frame));
  5461. }
  5462. extern uint8_t *mg_l2_eth_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
  5463. struct mg_l2addr *src, struct mg_l2addr *dst,
  5464. uint8_t *frame);
  5465. static uint8_t *pppoe_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
  5466. uint8_t code, uint16_t id, struct mg_l2addr *src,
  5467. struct mg_l2addr *dst, uint8_t *frame) {
  5468. struct pppoe *pppoe =
  5469. (struct pppoe *) mg_l2_eth_header(ifp, proto, src, dst, frame);
  5470. pppoe->vertype = 0x11;
  5471. pppoe->code = code;
  5472. pppoe->id = id;
  5473. return (uint8_t *) (pppoe + 1);
  5474. }
  5475. uint8_t *mg_l2_pppoe_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
  5476. struct mg_l2addr *src, struct mg_l2addr *dst,
  5477. uint8_t *frame) {
  5478. (void) dst;
  5479. return l2_ppp_header(proto, pppoe_header(ifp, MG_TCPIP_L2PROTO_PPPoE_SESS, 0,
  5480. s_id, src, dst, frame));
  5481. }
  5482. size_t mg_l2_ppp_trailer(struct mg_tcpip_if *ifp, size_t len, uint8_t *cur) {
  5483. uint16_t crc;
  5484. uint8_t *frame;
  5485. len += sizeof(struct ppp) + sizeof(struct hdlc_);
  5486. frame = cur - len;
  5487. crc = mg_crc16(0, (const char *) frame, len);
  5488. *cur++ = (uint8_t) crc; // add CRC, note the byte order
  5489. *cur++ = (uint8_t) (crc >> 8);
  5490. // there is no len field in PPP
  5491. (void) ifp;
  5492. return len + 2;
  5493. }
  5494. extern size_t mg_l2_eth_trailer(struct mg_tcpip_if *, size_t, uint8_t *);
  5495. static size_t pppoe_trailer(struct mg_tcpip_if *ifp, size_t len, uint8_t *cur) {
  5496. struct pppoe *pppoe = (struct pppoe *) (cur - len - sizeof(struct pppoe));
  5497. pppoe->len = mg_htons((uint16_t) len);
  5498. return mg_l2_eth_trailer(ifp, PDIFF(pppoe, cur), cur);
  5499. }
  5500. size_t mg_l2_pppoe_trailer(struct mg_tcpip_if *ifp, size_t len, uint8_t *cur) {
  5501. return pppoe_trailer(ifp, len + sizeof(struct ppp), cur);
  5502. }
  5503. size_t mg_l2_driver_output(struct mg_tcpip_if *ifp, size_t len);
  5504. static uint8_t *ppp_tx_frame_header(struct mg_tcpip_if *ifp, uint16_t proto) {
  5505. uint8_t *l2p = (uint8_t *) ifp->tx.buf;
  5506. if (ifp->l2type == MG_TCPIP_L2_PPP)
  5507. return ppp_header(proto, hdlc_header(l2p));
  5508. return ppp_header(proto, pppoe_header(ifp, MG_TCPIP_L2PROTO_PPPoE_SESS, 0,
  5509. s_id, (struct mg_l2addr *) ifp->mac,
  5510. (struct mg_l2addr *) ifp->gwmac, l2p));
  5511. }
  5512. static size_t ppp_tx_frame_trailer(struct mg_tcpip_if *ifp, size_t len,
  5513. uint8_t *cur) {
  5514. return mg_l2_driver_output(ifp, ifp->l2type == MG_TCPIP_L2_PPPoE
  5515. ? mg_l2_pppoe_trailer(ifp, len, cur)
  5516. : mg_l2_ppp_trailer(ifp, len, cur));
  5517. }
  5518. // Transmit a single PPP frame for the given protocol
  5519. static size_t ppp_tx_frame(struct mg_tcpip_if *ifp, uint16_t proto,
  5520. uint8_t *data, size_t datasz) {
  5521. uint8_t *pay = ppp_tx_frame_header(ifp, proto);
  5522. memcpy(pay, data, datasz);
  5523. return ppp_tx_frame_trailer(ifp, datasz, pay + datasz);
  5524. }
  5525. static void ppp_handle_lcp(struct mg_tcpip_if *ifp, uint8_t *lcpp,
  5526. size_t lcpsz) {
  5527. uint8_t id;
  5528. uint16_t len;
  5529. struct lcp *lcp = (struct lcp *) lcpp;
  5530. if (lcpsz < sizeof(*lcp)) return;
  5531. id = lcp->id;
  5532. len = mg_ntohs(lcp->len);
  5533. if (len < sizeof(*lcp) || len > lcpsz) return;
  5534. switch (lcp->code) {
  5535. case MG_PPP_LCP_CFG_REQ: {
  5536. if (len == sizeof(*lcp)) {
  5537. MG_DEBUG(("LCP config request of %d bytes, acknowledging...", len));
  5538. lcp->code = MG_PPP_LCP_CFG_ACK;
  5539. ppp_tx_frame(ifp, MG_PPP_PROTO_LCP, lcpp, len);
  5540. lcp->code = MG_PPP_LCP_CFG_REQ;
  5541. ppp_tx_frame(ifp, MG_PPP_PROTO_LCP, lcpp, len);
  5542. } else {
  5543. MG_DEBUG(("LCP config request of %d bytes, rejecting...", len));
  5544. lcp->code = MG_PPP_LCP_CFG_REJECT;
  5545. ppp_tx_frame(ifp, MG_PPP_PROTO_LCP, lcpp, len);
  5546. }
  5547. } break;
  5548. case MG_PPP_LCP_CFG_ACK:
  5549. s_lcpup = true;
  5550. break;
  5551. case MG_PPP_LCP_CFG_TERM_REQ: {
  5552. uint8_t ack[4] = {MG_PPP_LCP_CFG_TERM_ACK, id, 0, 4};
  5553. MG_DEBUG(("LCP termination request, acknowledging..."));
  5554. ppp_tx_frame(ifp, MG_PPP_PROTO_LCP, ack, sizeof(ack));
  5555. s_lcpup = false;
  5556. } break;
  5557. case MG_PPP_LCP_ECHO_REQ: // RFC-1661 5.8: must respond
  5558. MG_DEBUG(("LCP echo request of %d bytes, replying...", len));
  5559. lcp->code = MG_PPP_LCP_ECHO_REPLY;
  5560. ppp_tx_frame(ifp, MG_PPP_PROTO_LCP, lcpp, len);
  5561. break;
  5562. }
  5563. }
  5564. static bool find_opt(const uint8_t opt, const uint8_t optlen,
  5565. const uint8_t *opts, size_t optslen, uint8_t *dest) {
  5566. uint8_t *p = (uint8_t *) opts;
  5567. while (optslen >= 2) { // parse options for requested one
  5568. if (p[1] > optslen || p[1] < 2) return false; // truncated / malformed
  5569. if (p[0] == opt && p[1] == optlen) {
  5570. memcpy(dest, p + 2, optlen - 2);
  5571. return true;
  5572. }
  5573. optslen -= p[1];
  5574. p += p[1];
  5575. }
  5576. return false;
  5577. }
  5578. static void ppp_handle_ipcp(struct mg_tcpip_if *ifp, uint8_t *ipcpp,
  5579. size_t ipcpsz) {
  5580. uint16_t len;
  5581. uint8_t id;
  5582. struct ipcp *ipcp = (struct ipcp *) ipcpp;
  5583. uint8_t req[] = {
  5584. MG_PPP_IPCP_CFG_REQ, 0, 0, 10, MG_PPP_IPCP_OPT_IPADDR, 6, 0, 0, 0, 0};
  5585. if (ipcpsz < sizeof(*ipcp)) return;
  5586. id = ipcp->id;
  5587. len = mg_ntohs(ipcp->len);
  5588. if (len < sizeof(*ipcp) || len > ipcpsz) return;
  5589. switch (ipcp->code) {
  5590. case MG_PPP_IPCP_CFG_REQ:
  5591. MG_VERBOSE(("got IPCP config request, acknowledging..."));
  5592. if (len >= 10 &&
  5593. find_opt(MG_PPP_IPCP_OPT_IPADDR, 6, (const uint8_t *) (ipcp + 1),
  5594. len - sizeof(*ipcp), (uint8_t *) &ifp->gw)) {
  5595. MG_DEBUG(("IPCP cfg, GW IP: %M", mg_print_ip4, &ifp->gw));
  5596. ipcp->code = MG_PPP_IPCP_CFG_ACK;
  5597. } else if (ifp->gw == 0) {
  5598. MG_ERROR(("Peer did not provide its IP address"));
  5599. // NOTE: We should NACK with an added option, probably we can just store
  5600. // the incoming address and offer a statically configured ifp->gw when
  5601. // theirs == 0, but it is unlikely to find such a dumb PPP server and it
  5602. // will complicate our config and this protocol state machine
  5603. ipcp->code = MG_PPP_IPCP_CFG_REJECT;
  5604. ppp_tx_frame(ifp, MG_PPP_PROTO_IPCP, ipcpp, len);
  5605. }
  5606. ppp_tx_frame(ifp, MG_PPP_PROTO_IPCP, ipcpp, len);
  5607. req[1] = id;
  5608. memcpy(req + 6, &ifp->ip, 4); // Request config IP address or 0.0.0.0
  5609. ppp_tx_frame(ifp, MG_PPP_PROTO_IPCP, req, sizeof(req));
  5610. break;
  5611. case MG_PPP_IPCP_CFG_ACK:
  5612. // Our peer accepted our IP address
  5613. MG_VERBOSE(("got IPCP config ack"));
  5614. ifp->mask = 0xffffffff; // send to gw
  5615. ifp->state = MG_TCPIP_STATE_IP;
  5616. ifp->gw_ready = true;
  5617. break;
  5618. case MG_PPP_IPCP_CFG_NACK:
  5619. MG_VERBOSE(("got IPCP config nack"));
  5620. // NACK contains our "suggested" IP address, use it
  5621. if (len >= 10 &&
  5622. find_opt(MG_PPP_IPCP_OPT_IPADDR, 6, (const uint8_t *) (ipcp + 1),
  5623. len - sizeof(*ipcp), (uint8_t *) &ifp->ip)) {
  5624. MG_DEBUG(("IPCP cfg, IP: %M", mg_print_ip4, &ifp->ip));
  5625. ipcp->code = MG_PPP_IPCP_CFG_REQ;
  5626. ppp_tx_frame(ifp, MG_PPP_PROTO_IPCP, ipcpp, len);
  5627. }
  5628. break;
  5629. case MG_PPP_IPCP_CFG_REJECT:
  5630. MG_ERROR(("Peer rejected our IP address, need to properly set ifp->ip"));
  5631. break;
  5632. }
  5633. }
  5634. #if MG_ENABLE_IPV6
  5635. static void ppp_handle_ipv6cp(struct mg_tcpip_if *ifp, uint8_t *ipv6cpp,
  5636. size_t ipv6cpsz) {
  5637. uint16_t len;
  5638. uint8_t id;
  5639. struct ipv6cp *ipv6cp = (struct ipv6cp *) ipv6cpp;
  5640. uint8_t req[14];
  5641. memset(req, 0, sizeof(req));
  5642. req[0] = MG_PPP_IPV6CP_CFG_REQ, req[3] = 14, req[4] = MG_PPP_IPV6CP_OPT_IFCID,
  5643. req[5] = 10;
  5644. if (ipv6cpsz < sizeof(*ipv6cp)) return;
  5645. id = ipv6cp->id;
  5646. len = mg_ntohs(ipv6cp->len);
  5647. if (len < sizeof(*ipv6cp) || len > ipv6cpsz) return;
  5648. switch (ipv6cp->code) {
  5649. case MG_PPP_IPV6CP_CFG_REQ:
  5650. MG_VERBOSE(("got IPV6CP config request..."));
  5651. if (len >= 10 &&
  5652. find_opt(
  5653. MG_PPP_IPV6CP_OPT_IFCID, 10, (const uint8_t *) (ipv6cp + 1),
  5654. len - sizeof(*ipv6cp),
  5655. (uint8_t *) &((struct mg_l2addr *) (ifp->gw6mac))->addr.ieee64)) {
  5656. if (((struct mg_l2addr *) (ifp->gw6mac))->addr.ieee64 != 0) {
  5657. MG_DEBUG(("IPV6CP cfg, GW IFCID: %M", mg_print_ieee64,
  5658. &((struct mg_l2addr *) (ifp->gw6mac))->addr.ieee64));
  5659. ipv6cp->code = MG_PPP_IPV6CP_CFG_ACK;
  5660. ppp_tx_frame(ifp, MG_PPP_PROTO_IPV6CP, ipv6cpp, len);
  5661. req[1] = id;
  5662. ifp->ip6ll[0] = 0, ifp->ip6ll[1] = 0; // clear any former ll address
  5663. memset(req + 6, 0, 8); // Inform ifc id 0
  5664. ppp_tx_frame(ifp, MG_PPP_PROTO_IPV6CP, req, sizeof(req));
  5665. } else {
  5666. MG_ERROR(("Peer is not able to provide its interface id"));
  5667. ipv6cp->code = MG_PPP_IPV6CP_CFG_REJECT;
  5668. ppp_tx_frame(ifp, MG_PPP_PROTO_IPV6CP, ipv6cpp, len);
  5669. }
  5670. } else {
  5671. MG_ERROR(("Peer did not provide its interface id"));
  5672. // We should NACK with an added option, but we can't provide one for
  5673. // them
  5674. ipv6cp->code = MG_PPP_IPV6CP_CFG_REJECT;
  5675. ppp_tx_frame(ifp, MG_PPP_PROTO_IPV6CP, ipv6cpp, len);
  5676. }
  5677. break;
  5678. case MG_PPP_IPV6CP_CFG_ACK:
  5679. // Our peer accepted our ifc id
  5680. MG_VERBOSE(("got IPV6CP config ack"));
  5681. break;
  5682. case MG_PPP_IPV6CP_CFG_NACK: {
  5683. struct mg_l2addr l2;
  5684. MG_VERBOSE(("got IPV6CP config nack"));
  5685. // NACK contains our "suggested" IFC id, use it
  5686. if (len >= 10 &&
  5687. find_opt(MG_PPP_IPV6CP_OPT_IFCID, 10, (const uint8_t *) (ipv6cp + 1),
  5688. len - sizeof(*ipv6cp), (uint8_t *) &l2.addr.ieee64)) {
  5689. MG_DEBUG(("IPV6CP cfg, IFCID: %M", mg_print_ieee64, &l2.addr.ieee64));
  5690. ifp->ip6ll[1] = l2.addr.ieee64; // RFC-5072 5, signal L3 we're ready
  5691. ipv6cp->code = MG_PPP_IPV6CP_CFG_REQ;
  5692. ppp_tx_frame(ifp, MG_PPP_PROTO_IPV6CP, ipv6cpp, len);
  5693. } else {
  5694. MG_ERROR(("Peer is not able to offer an interface id"));
  5695. }
  5696. } break;
  5697. case MG_PPP_IPV6CP_CFG_REJECT:
  5698. MG_ERROR(("Peer rejected our interface id"));
  5699. break;
  5700. }
  5701. }
  5702. #endif
  5703. static bool ppp_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
  5704. struct mg_str *pay, struct mg_str *raw) {
  5705. struct ppp *ppp = (struct ppp *) pay->buf;
  5706. if (pay->len < sizeof(*ppp)) return false; // Truncated
  5707. pay->buf = (char *) (ppp + 1);
  5708. pay->len = pay->len - sizeof(*ppp);
  5709. switch (mg_ntohs(ppp->proto)) {
  5710. case MG_PPP_PROTO_LCP:
  5711. ppp_handle_lcp(ifp, (uint8_t *) pay->buf, pay->len);
  5712. return false;
  5713. case MG_PPP_PROTO_IPCP:
  5714. if (s_lcpup) ppp_handle_ipcp(ifp, (uint8_t *) pay->buf, pay->len);
  5715. return false;
  5716. case MG_PPP_PROTO_IP:
  5717. if (!s_lcpup) return false;
  5718. MG_VERBOSE(("got IP packet of %d bytes", pay->len));
  5719. *proto = MG_TCPIP_L2PROTO_IPV4;
  5720. break;
  5721. #if MG_ENABLE_IPV6
  5722. case MG_PPP_PROTO_IPV6CP:
  5723. if (s_lcpup) ppp_handle_ipv6cp(ifp, (uint8_t *) pay->buf, pay->len);
  5724. return false;
  5725. case MG_PPP_PROTO_IPV6:
  5726. if (!s_lcpup) return false;
  5727. MG_VERBOSE(("got IPv6 packet of %d bytes", pay->len));
  5728. *proto = MG_TCPIP_L2PROTO_IPV6;
  5729. break;
  5730. #endif
  5731. default: {
  5732. struct lcp rej;
  5733. uint8_t *p;
  5734. size_t msglen;
  5735. MG_DEBUG(("unknown %u-byte PPP frame with proto 0x%04x:",
  5736. pay->len + sizeof(*ppp), mg_ntohs(ppp->proto)));
  5737. if (mg_log_level >= MG_LL_DEBUG)
  5738. mg_hexdump(ppp, pay->len > 14 ? 16 : pay->len + sizeof(*ppp));
  5739. if (!s_lcpup) return false; // RFC-1661 5.7: must reject on link down
  5740. if (pay->len > (size_t) (ifp->mtu - 20))
  5741. pay->len = (size_t) (ifp->mtu - 20); // truncate to some safe limit
  5742. rej.code = MG_PPP_LCP_REJECT;
  5743. mg_random(&rej.id, sizeof(rej.id));
  5744. msglen = pay->len + sizeof(*ppp);
  5745. rej.len = mg_htons((uint16_t) (msglen + sizeof(rej)));
  5746. p = ppp_tx_frame_header(ifp, MG_PPP_PROTO_LCP);
  5747. memmove(p, &rej, sizeof(rej)); // LCP reject
  5748. memmove(p + sizeof(rej), ppp, msglen); // rejected PPP message
  5749. ppp_tx_frame_trailer(ifp, msglen + sizeof(rej), p + msglen + sizeof(rej));
  5750. }
  5751. return false;
  5752. }
  5753. (void) raw;
  5754. return true;
  5755. }
  5756. bool mg_l2_ppp_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
  5757. struct mg_str *pay, struct mg_str *raw) {
  5758. struct hdlc_ *hdlc = (struct hdlc_ *) raw->buf;
  5759. if (raw->len < sizeof(*hdlc) + 2) return false; // Truncated
  5760. if (hdlc->addr == MG_PPP_ADDR && hdlc->ctrl == MG_PPP_CTRL) {
  5761. pay->buf = (char *) (hdlc + 1);
  5762. pay->len = raw->len - sizeof(*hdlc) - 2;
  5763. } else { // Address-and-Control-Field-Compressed PPP header
  5764. pay->buf = (char *) raw->buf;
  5765. pay->len = raw->len - 2;
  5766. }
  5767. return ppp_rx(ifp, proto, pay, raw);
  5768. }
  5769. extern struct mg_l2addr s_mapip;
  5770. struct mg_l2addr *mg_l2_ppp_getaddr(struct mg_tcpip_if *ifp, uint8_t *frame) {
  5771. (void) ifp;
  5772. (void) frame;
  5773. return &s_mapip; // bogus
  5774. }
  5775. extern struct mg_l2addr *mg_l2_eth_mapip(enum mg_l2addrtype, struct mg_addr *);
  5776. struct mg_l2addr *mg_l2_ppp_mapip(enum mg_l2addrtype addrtype,
  5777. struct mg_addr *addr) {
  5778. return mg_l2_eth_mapip(addrtype, addr);
  5779. }
  5780. #if MG_ENABLE_IPV6
  5781. bool mg_l2_ppp_genip6(uint64_t *ip6, uint8_t prefix_len,
  5782. struct mg_l2addr *l2addr) {
  5783. if (prefix_len > 64) {
  5784. MG_ERROR(("Prefix length > 64, UNSUPPORTED"));
  5785. return false;
  5786. }
  5787. ip6[0] = 0;
  5788. ip6[1] = l2addr->addr.ieee64;
  5789. return false;
  5790. }
  5791. bool mg_l2_ppp_ip6get(struct mg_l2addr *l2addr, uint8_t *opts, uint8_t len) {
  5792. (void) l2addr;
  5793. (void) opts;
  5794. (void) len;
  5795. return true;
  5796. }
  5797. uint8_t mg_l2_ppp_ip6put(struct mg_l2addr *l2addr, uint8_t *opts) {
  5798. (void) l2addr;
  5799. (void) opts;
  5800. return 0;
  5801. }
  5802. #endif
  5803. // Transmit a single PPPoE frame for the discovery phase
  5804. static size_t pppoe_tx_frame(struct mg_tcpip_if *ifp, uint8_t code, uint16_t id,
  5805. uint8_t *data, size_t datasz,
  5806. struct mg_l2addr *dst) {
  5807. uint8_t *l2p = (uint8_t *) ifp->tx.buf;
  5808. uint8_t *p = pppoe_header(ifp, MG_TCPIP_L2PROTO_PPPoE_DISC, code, id,
  5809. (struct mg_l2addr *) ifp->mac, dst, l2p);
  5810. memmove(p, data, datasz);
  5811. return mg_l2_driver_output(ifp, pppoe_trailer(ifp, datasz, p + datasz));
  5812. }
  5813. bool mg_l2_pppoe_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) {
  5814. if (expired_1000ms && s_state == MG_PPPoE_ST_DISC &&
  5815. ifp->state == MG_TCPIP_STATE_LINK_UP) {
  5816. uint16_t tags[2];
  5817. tags[0] = mg_htons(0x0101); // Service Request
  5818. tags[1] = mg_htons(0x0000); // Any
  5819. pppoe_tx_frame(ifp, MG_PPPoE_PADI, 0, (uint8_t *) tags, sizeof(tags),
  5820. mg_l2_eth_mapip(MG_TCPIP_L2ADDR_BCAST, NULL));
  5821. MG_DEBUG(("Sent PADI"));
  5822. } else if (expired_1000ms && (s_state != MG_PPPoE_ST_SESS ||
  5823. ifp->state == MG_TCPIP_STATE_DOWN)) {
  5824. s_state = MG_PPPoE_ST_DISC;
  5825. }
  5826. return mg_l2_ppp_poll(ifp, expired_1000ms);
  5827. }
  5828. extern bool mg_l2_eth_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
  5829. struct mg_str *pay, struct mg_str *raw);
  5830. extern struct mg_l2addr *mg_l2_eth_getaddr(struct mg_tcpip_if *, uint8_t *);
  5831. bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
  5832. struct mg_str *pay, struct mg_str *raw) {
  5833. enum mg_l2proto eth_proto; // raw is handled by eth
  5834. struct pppoe *pppoe;
  5835. if (!mg_l2_eth_rx(ifp, &eth_proto, pay, raw)) return false;
  5836. pppoe = (struct pppoe *) pay->buf; // here we handle pay, not raw
  5837. if (pay->len < sizeof(*pppoe)) return false; // Truncated
  5838. if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_DISC) {
  5839. MG_VERBOSE(("PPPoE_DISC"));
  5840. if (s_state == MG_PPPoE_ST_DISC && pppoe->code == MG_PPPoE_PADO &&
  5841. pppoe->id == 0) {
  5842. uint16_t tags[2];
  5843. bool has_cookie = false;
  5844. size_t len = pay->len - sizeof(*pppoe);
  5845. uint8_t *p = (uint8_t *) (pppoe + 1);
  5846. uint16_t taglen;
  5847. while (len >= 4) { // parse tags for a possible AC-Cookie
  5848. uint16_t curtag = MG_LOAD_BE16(p);
  5849. taglen = MG_LOAD_BE16(p + 2);
  5850. if (taglen > len - 4) return false; // truncated / malformed
  5851. if (curtag == 0x0104) {
  5852. has_cookie = true;
  5853. break;
  5854. }
  5855. len -= 4 + taglen;
  5856. p += 4 + taglen;
  5857. }
  5858. tags[0] = mg_htons(0x0101); // Service Request
  5859. tags[1] = mg_htons(0x0000); // Any
  5860. if (has_cookie) { // copy tags to before AC-Cookie tag in rx buffer
  5861. memcpy(p -= sizeof(tags), tags, sizeof(tags)); // point to all tags
  5862. taglen += 4 + sizeof(tags); // account for tags
  5863. } else {
  5864. p = (uint8_t *) tags;
  5865. taglen = sizeof(tags);
  5866. }
  5867. pppoe_tx_frame(ifp, MG_PPPoE_PADR, 0, p, taglen,
  5868. mg_l2_eth_getaddr(ifp, (uint8_t *) raw->buf));
  5869. MG_DEBUG(("Sent PADR"));
  5870. s_state = MG_PPPoE_ST_REQ;
  5871. } else if (s_state == MG_PPPoE_ST_REQ && pppoe->code == MG_PPPoE_PADS) {
  5872. s_id = pppoe->id;
  5873. memcpy(&ifp->gwmac,
  5874. mg_l2_eth_getaddr(ifp, (uint8_t *) raw->buf)->addr.mac, 6);
  5875. MG_DEBUG(("PPPoE session 0x%04x started", mg_ntohs(s_id)));
  5876. s_state = MG_PPPoE_ST_SESS;
  5877. } else if (s_state == MG_PPPoE_ST_SESS && pppoe->code == MG_PPPoE_PADT &&
  5878. pppoe->id == s_id) {
  5879. MG_ERROR(("Got PADT"));
  5880. s_id = 0;
  5881. s_lcpup = false;
  5882. s_state = MG_PPPoE_ST_DISC;
  5883. }
  5884. } else if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_SESS &&
  5885. s_state == MG_PPPoE_ST_SESS) {
  5886. pay->buf = (char *) (pppoe + 1);
  5887. pay->len = pay->len - sizeof(*pppoe);
  5888. return ppp_rx(ifp, proto, pay, raw);
  5889. }
  5890. return false;
  5891. }
  5892. #endif
  5893. #ifdef MG_ENABLE_LINES
  5894. #line 1 "src/lfs.c"
  5895. #endif
  5896. // Copyright (c) 2023 Cesanta Software Limited
  5897. // SPDX-License-Identifier: GPL-2.0-only or commercial
  5898. #if MG_ENABLE_LFS
  5899. #include <fcntl.h>
  5900. #include <littlefs/lfs.h>
  5901. #include <string.h>
  5902. #include <sys/stat.h>
  5903. #include <sys/types.h>
  5904. #ifndef LFS_USE_RAM
  5905. #define LFS_USE_RAM 0 // If 1, use RAM FS. If 0, use flash
  5906. #endif
  5907. #ifndef MG_LFS_BUF_SIZE
  5908. #define MG_LFS_BUF_SIZE 64 // Buffer size used for reads, writes, and cache
  5909. #endif
  5910. #ifndef MG_LFS_FD_BASE
  5911. #define MG_LFS_FD_BASE 12000 // Starting file descriptor number
  5912. #endif
  5913. #if LFS_USE_RAM && !defined(MG_LFS_BLOCK_SIZE)
  5914. #define MG_LFS_BLOCK_SIZE 8192
  5915. #endif
  5916. #ifndef DT_DIR
  5917. #define DT_DIR 4
  5918. #endif
  5919. #ifndef DT_REG
  5920. #define DT_REG 8
  5921. #endif
  5922. typedef struct mg_lfs_fd DIR;
  5923. struct dirent {
  5924. char d_name[LFS_NAME_MAX + 1];
  5925. unsigned char d_type;
  5926. };
  5927. struct mg_lfs_fd {
  5928. struct mg_lfs_fd *next;
  5929. bool isopen;
  5930. lfs_file_t file;
  5931. lfs_dir_t dir;
  5932. int fd;
  5933. };
  5934. static lfs_t s_lfs;
  5935. static struct mg_lfs_fd *s_fds;
  5936. static uint8_t *s_fs;
  5937. static int s_next_fd = MG_LFS_FD_BASE;
  5938. static bool s_lfs_ready;
  5939. #if LFS_USE_RAM
  5940. static uint8_t *s_ram_fs;
  5941. #endif
  5942. static int lfs_driver_read(const struct lfs_config *cfg, lfs_block_t block,
  5943. lfs_off_t off, void *buf, lfs_size_t len);
  5944. static int lfs_driver_prog(const struct lfs_config *cfg, lfs_block_t block,
  5945. lfs_off_t off, const void *buf, lfs_size_t len);
  5946. static int lfs_driver_erase(const struct lfs_config *cfg, lfs_block_t block);
  5947. static int lfs_driver_sync(const struct lfs_config *cfg);
  5948. static struct lfs_config s_cfg = {
  5949. .read = lfs_driver_read,
  5950. .prog = lfs_driver_prog,
  5951. .erase = lfs_driver_erase,
  5952. .sync = lfs_driver_sync,
  5953. .block_cycles = 200,
  5954. .cache_size = MG_LFS_BUF_SIZE,
  5955. .read_size = MG_LFS_BUF_SIZE,
  5956. .prog_size = MG_LFS_BUF_SIZE,
  5957. .lookahead_size = MG_LFS_BUF_SIZE / 8,
  5958. };
  5959. static bool flash_write_buf(void *addr, const void *buf, size_t len) {
  5960. #if LFS_USE_RAM
  5961. memmove(addr, buf, len);
  5962. return true;
  5963. #else
  5964. return mg_flash != NULL && mg_flash->write_fn(addr, buf, len);
  5965. #endif
  5966. }
  5967. static int lfs_driver_read(const struct lfs_config *cfg, lfs_block_t block,
  5968. lfs_off_t off, void *buf, lfs_size_t len) {
  5969. memmove(buf, &s_fs[block * cfg->block_size + off], len);
  5970. return 0;
  5971. }
  5972. static int lfs_driver_prog(const struct lfs_config *cfg, lfs_block_t block,
  5973. lfs_off_t off, const void *buf, lfs_size_t len) {
  5974. uint8_t *dst = &s_fs[block * cfg->block_size + off];
  5975. if (!flash_write_buf(dst, buf, len)) return LFS_ERR_IO;
  5976. return 0;
  5977. }
  5978. static int lfs_driver_erase(const struct lfs_config *cfg, lfs_block_t block) {
  5979. (void) cfg, (void) block;
  5980. return 0;
  5981. }
  5982. static int lfs_driver_sync(const struct lfs_config *cfg) {
  5983. (void) cfg;
  5984. return 0;
  5985. }
  5986. bool mg_lfs_init(size_t size) {
  5987. int result = 0;
  5988. if (s_lfs_ready) return true;
  5989. if (size == 0) return false;
  5990. #if LFS_USE_RAM
  5991. s_cfg.block_size = MG_LFS_BLOCK_SIZE;
  5992. if (s_ram_fs == NULL) s_ram_fs = (uint8_t *) mg_calloc(1, size);
  5993. s_fs = s_ram_fs;
  5994. #else
  5995. if (mg_flash == NULL || mg_flash->secsz == 0 || mg_flash->size < size) return false;
  5996. if (mg_flash->write_fn == NULL) return false;
  5997. s_cfg.block_size = mg_flash->secsz;
  5998. s_fs = (uint8_t *) mg_flash->start + mg_flash->size - size;
  5999. #endif
  6000. if (s_fs == NULL || s_cfg.block_size == 0 || size % s_cfg.block_size != 0) {
  6001. return false;
  6002. }
  6003. s_cfg.block_count = (lfs_size_t) (size / s_cfg.block_size);
  6004. if (s_cfg.block_count == 0) return false;
  6005. if (lfs_mount(&s_lfs, &s_cfg) != 0) {
  6006. lfs_format(&s_lfs, &s_cfg);
  6007. if (lfs_mount(&s_lfs, &s_cfg) != 0) result = -1;
  6008. }
  6009. s_lfs_ready = result == 0;
  6010. return s_lfs_ready;
  6011. }
  6012. static struct mg_lfs_fd *find_fd(int fd) {
  6013. struct mg_lfs_fd *f;
  6014. for (f = s_fds; f != NULL; f = f->next) {
  6015. if (f->isopen && f->fd == fd) return f;
  6016. }
  6017. return NULL;
  6018. }
  6019. static struct mg_lfs_fd *open_fd(void) {
  6020. struct mg_lfs_fd *f = NULL;
  6021. if (s_lfs_ready) {
  6022. f = (struct mg_lfs_fd *) mg_calloc(1, sizeof(*f));
  6023. if (f != NULL) {
  6024. f->isopen = true;
  6025. f->fd = s_next_fd++;
  6026. f->next = s_fds;
  6027. s_fds = f;
  6028. if (s_next_fd < MG_LFS_FD_BASE) s_next_fd = MG_LFS_FD_BASE;
  6029. }
  6030. }
  6031. return f;
  6032. }
  6033. static int close_fd(struct mg_lfs_fd *fd) {
  6034. struct mg_lfs_fd **f = &s_fds;
  6035. while (*f != NULL && *f != fd) f = &(*f)->next;
  6036. if (*f == NULL) return -1;
  6037. *f = fd->next;
  6038. fd->isopen = false;
  6039. mg_free(fd);
  6040. return 0;
  6041. }
  6042. int _open(const char *path, int flags, mode_t mode) {
  6043. int err, lfs_flags = 0, fd = -1;
  6044. struct mg_lfs_fd *f = open_fd();
  6045. (void) mode;
  6046. if (f == NULL) return -1;
  6047. fd = f->fd;
  6048. if ((flags & 3) == O_RDONLY) lfs_flags |= LFS_O_RDONLY;
  6049. if ((flags & 3) == O_WRONLY) lfs_flags |= LFS_O_WRONLY;
  6050. if ((flags & 3) == O_RDWR) lfs_flags |= LFS_O_RDWR;
  6051. if (flags & O_CREAT) lfs_flags |= LFS_O_CREAT;
  6052. if (flags & O_TRUNC) lfs_flags |= LFS_O_TRUNC;
  6053. if (flags & O_APPEND) lfs_flags |= LFS_O_APPEND;
  6054. err = lfs_file_open(&s_lfs, &f->file, path, lfs_flags);
  6055. if (err < 0) close_fd(f), fd = -1;
  6056. return fd;
  6057. }
  6058. int _close(int fd) {
  6059. struct mg_lfs_fd *f = find_fd(fd);
  6060. if (fd < 3) return 0;
  6061. if (f == NULL) return -1;
  6062. lfs_file_close(&s_lfs, &f->file);
  6063. close_fd(f);
  6064. return 0;
  6065. }
  6066. int _write(int fd, char *ptr, int len) {
  6067. struct mg_lfs_fd *f = find_fd(fd);
  6068. return fd < 3 ? len
  6069. : f == NULL ? -1 : lfs_file_write(&s_lfs, &f->file, ptr, len);
  6070. }
  6071. int _read(int fd, char *ptr, int len) {
  6072. struct mg_lfs_fd *f = find_fd(fd);
  6073. return fd < 3 ? 0 : f == NULL ? -1 : lfs_file_read(&s_lfs, &f->file, ptr, len);
  6074. }
  6075. int _lseek(int fd, int offset, int whence) {
  6076. struct mg_lfs_fd *f = find_fd(fd);
  6077. return fd < 3 ? 0
  6078. : f == NULL ? -1 : lfs_file_seek(&s_lfs, &f->file, offset,
  6079. whence);
  6080. }
  6081. int _rename(const char *oldname, const char *newname) {
  6082. return s_lfs_ready ? lfs_rename(&s_lfs, oldname, newname) : -1;
  6083. }
  6084. int _unlink_r(void *r, const char *a) {
  6085. (void) r;
  6086. return s_lfs_ready ? lfs_remove(&s_lfs, a) : -1;
  6087. }
  6088. DIR *opendir(const char *name) {
  6089. struct mg_lfs_fd *f = open_fd();
  6090. if (f == NULL) return NULL;
  6091. if (lfs_dir_open(&s_lfs, &f->dir, name) != 0) {
  6092. close_fd(f);
  6093. return NULL;
  6094. }
  6095. return (DIR *) f;
  6096. }
  6097. int closedir(DIR *dir) {
  6098. struct mg_lfs_fd *f = (struct mg_lfs_fd *) dir;
  6099. if (f == NULL || find_fd(f->fd) != f) return -1;
  6100. lfs_dir_close(&s_lfs, &f->dir);
  6101. return close_fd(f);
  6102. }
  6103. struct dirent *readdir(DIR *dir) {
  6104. static struct dirent dirent;
  6105. struct mg_lfs_fd *f = (struct mg_lfs_fd *) dir;
  6106. struct lfs_info info;
  6107. if (f == NULL || !f->isopen) return NULL;
  6108. if (lfs_dir_read(&s_lfs, &f->dir, &info) < 1) return NULL;
  6109. memset(&dirent, 0, sizeof(dirent));
  6110. strncpy(dirent.d_name, info.name, sizeof(dirent.d_name) - 1);
  6111. if (info.type == LFS_TYPE_DIR) dirent.d_type |= DT_DIR;
  6112. if (info.type == LFS_TYPE_REG) dirent.d_type |= DT_REG;
  6113. return &dirent;
  6114. }
  6115. int _stat(const char *path, struct stat *st) {
  6116. struct lfs_info info;
  6117. if (!s_lfs_ready || lfs_stat(&s_lfs, path, &info) != 0) return -1;
  6118. st->st_mode = info.type == LFS_TYPE_DIR ? S_IFDIR : S_IFREG;
  6119. st->st_size = info.size;
  6120. return 0;
  6121. }
  6122. int _fstat(int fd, struct stat *st) {
  6123. if (fd >= 3 && find_fd(fd) == NULL) return -1;
  6124. st->st_mode = S_IFCHR;
  6125. return 0;
  6126. }
  6127. int mkdir(const char *path, mode_t mode) {
  6128. (void) mode;
  6129. return s_lfs_ready ? lfs_mkdir(&s_lfs, path) : -1;
  6130. }
  6131. #endif
  6132. #ifdef MG_ENABLE_LINES
  6133. #line 1 "src/log.c"
  6134. #endif
  6135. int mg_log_level = MG_LL_DEBUG;
  6136. static mg_pfn_t s_log_func = mg_pfn_stdout;
  6137. static void *s_log_func_param = NULL;
  6138. void mg_log_set_fn(mg_pfn_t fn, void *param) {
  6139. s_log_func = fn;
  6140. s_log_func_param = param;
  6141. }
  6142. static void logc(unsigned char c) {
  6143. s_log_func((char) c, s_log_func_param);
  6144. }
  6145. static void logs(const char *buf, size_t len) {
  6146. size_t i;
  6147. for (i = 0; i < len; i++) logc(((unsigned char *) buf)[i]);
  6148. }
  6149. #if MG_ENABLE_CUSTOM_LOG
  6150. // Let user define their own mg_log_prefix() and mg_log()
  6151. #else
  6152. void mg_log_prefix(int level, const char *file, int line, const char *fname) {
  6153. const char *p = strrchr(file, '/');
  6154. char buf[41];
  6155. size_t n;
  6156. if (p == NULL) p = strrchr(file, '\\');
  6157. n = mg_snprintf(buf, sizeof(buf), "%-6llx %d %s:%d:%s", mg_millis(), level,
  6158. p == NULL ? file : p + 1, line, fname);
  6159. if (n > sizeof(buf) - 2) n = sizeof(buf) - 2;
  6160. while (n < sizeof(buf)) buf[n++] = ' ';
  6161. logs(buf, n - 1);
  6162. }
  6163. void mg_log(const char *fmt, ...) {
  6164. va_list ap;
  6165. va_start(ap, fmt);
  6166. mg_vxprintf(s_log_func, s_log_func_param, fmt, &ap);
  6167. va_end(ap);
  6168. logs("\r\n", 2);
  6169. }
  6170. #endif
  6171. static unsigned char nibble(unsigned c) {
  6172. return (unsigned char) (c < 10 ? c + '0' : c + 'W');
  6173. }
  6174. #define ISPRINT(x) ((x) >= ' ' && (x) <= '~')
  6175. void mg_hexdump(const void *buf, size_t len) {
  6176. const unsigned char *p = (const unsigned char *) buf;
  6177. unsigned char ascii[16], alen = 0;
  6178. size_t i;
  6179. for (i = 0; i < len; i++) {
  6180. if ((i % 16) == 0) {
  6181. // Print buffered ascii chars
  6182. if (i > 0)
  6183. logs(" ", 2), logs((char *) ascii, 16), logs("\r\n", 2), alen = 0;
  6184. // Print hex address, then \t
  6185. logc(nibble((i >> 12) & 15)), logc(nibble((i >> 8) & 15)),
  6186. logc(nibble((i >> 4) & 15)), logc('0'), logs(" ", 3);
  6187. }
  6188. logc(nibble(p[i] >> 4)), logc(nibble(p[i] & 15)); // Two nibbles, e.g. c5
  6189. logc(' '); // Space after hex number
  6190. ascii[alen++] = ISPRINT(p[i]) ? p[i] : '.'; // Add to the ascii buf
  6191. }
  6192. while (alen < 16) logs(" ", 3), ascii[alen++] = ' ';
  6193. logs(" ", 2), logs((char *) ascii, 16), logs("\r\n", 2);
  6194. }
  6195. #ifdef MG_ENABLE_LINES
  6196. #line 1 "src/md5.c"
  6197. #endif
  6198. // This code implements the MD5 message-digest algorithm.
  6199. // The algorithm is due to Ron Rivest. This code was
  6200. // written by Colin Plumb in 1993, no copyright is claimed.
  6201. // This code is in the public domain; do with it what you wish.
  6202. //
  6203. // Equivalent code is available from RSA Data Security, Inc.
  6204. // This code has been tested against that, and is equivalent,
  6205. // except that you don't need to include two pages of legalese
  6206. // with every copy.
  6207. //
  6208. // To compute the message digest of a chunk of bytes, declare an
  6209. // MD5Context structure, pass it to MD5Init, call MD5Update as
  6210. // needed on buffers full of bytes, and then call MD5Final, which
  6211. // will fill a supplied 16-byte array with the digest.
  6212. #if defined(MG_ENABLE_MD5) && MG_ENABLE_MD5
  6213. static void mg_byte_reverse(unsigned char *buf, unsigned longs) {
  6214. if (MG_BIG_ENDIAN) {
  6215. do {
  6216. uint32_t t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
  6217. ((unsigned) buf[1] << 8 | buf[0]);
  6218. *(uint32_t *) buf = t;
  6219. buf += 4;
  6220. } while (--longs);
  6221. } else {
  6222. (void) buf, (void) longs; // Little endian. Do nothing
  6223. }
  6224. }
  6225. #define F1(x, y, z) (z ^ (x & (y ^ z)))
  6226. #define F2(x, y, z) F1(z, x, y)
  6227. #define F3(x, y, z) (x ^ y ^ z)
  6228. #define F4(x, y, z) (y ^ (x | ~z))
  6229. #define MD5STEP(f, w, x, y, z, data, s) \
  6230. (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
  6231. /*
  6232. * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
  6233. * initialization constants.
  6234. */
  6235. void mg_md5_init(mg_md5_ctx *ctx) {
  6236. ctx->buf[0] = 0x67452301;
  6237. ctx->buf[1] = 0xefcdab89;
  6238. ctx->buf[2] = 0x98badcfe;
  6239. ctx->buf[3] = 0x10325476;
  6240. ctx->bits[0] = 0;
  6241. ctx->bits[1] = 0;
  6242. }
  6243. static void mg_md5_transform(uint32_t buf[4], uint32_t const in[16]) {
  6244. uint32_t a, b, c, d;
  6245. a = buf[0];
  6246. b = buf[1];
  6247. c = buf[2];
  6248. d = buf[3];
  6249. MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  6250. MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  6251. MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  6252. MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  6253. MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  6254. MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  6255. MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  6256. MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  6257. MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  6258. MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  6259. MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  6260. MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  6261. MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  6262. MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  6263. MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  6264. MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  6265. MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  6266. MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  6267. MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  6268. MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  6269. MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  6270. MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  6271. MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  6272. MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  6273. MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  6274. MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  6275. MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  6276. MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  6277. MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  6278. MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  6279. MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  6280. MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  6281. MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  6282. MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  6283. MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  6284. MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  6285. MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  6286. MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  6287. MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  6288. MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  6289. MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  6290. MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  6291. MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  6292. MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  6293. MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  6294. MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  6295. MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  6296. MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  6297. MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  6298. MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  6299. MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  6300. MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  6301. MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  6302. MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  6303. MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  6304. MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  6305. MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  6306. MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  6307. MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  6308. MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  6309. MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  6310. MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  6311. MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  6312. MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  6313. buf[0] += a;
  6314. buf[1] += b;
  6315. buf[2] += c;
  6316. buf[3] += d;
  6317. }
  6318. void mg_md5_update(mg_md5_ctx *ctx, const unsigned char *buf, size_t len) {
  6319. uint32_t t;
  6320. t = ctx->bits[0];
  6321. if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++;
  6322. ctx->bits[1] += (uint32_t) len >> 29;
  6323. t = (t >> 3) & 0x3f;
  6324. if (t) {
  6325. unsigned char *p = (unsigned char *) ctx->in + t;
  6326. t = 64 - t;
  6327. if (len < t) {
  6328. memcpy(p, buf, len);
  6329. return;
  6330. }
  6331. memcpy(p, buf, t);
  6332. mg_byte_reverse(ctx->in, 16);
  6333. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  6334. buf += t;
  6335. len -= t;
  6336. }
  6337. while (len >= 64) {
  6338. memcpy(ctx->in, buf, 64);
  6339. mg_byte_reverse(ctx->in, 16);
  6340. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  6341. buf += 64;
  6342. len -= 64;
  6343. }
  6344. memcpy(ctx->in, buf, len);
  6345. }
  6346. void mg_md5_final(mg_md5_ctx *ctx, unsigned char digest[16]) {
  6347. unsigned count;
  6348. unsigned char *p;
  6349. uint32_t *a;
  6350. count = (ctx->bits[0] >> 3) & 0x3F;
  6351. p = ctx->in + count;
  6352. *p++ = 0x80;
  6353. count = 64 - 1 - count;
  6354. if (count < 8) {
  6355. memset(p, 0, count);
  6356. mg_byte_reverse(ctx->in, 16);
  6357. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  6358. memset(ctx->in, 0, 56);
  6359. } else {
  6360. memset(p, 0, count - 8);
  6361. }
  6362. mg_byte_reverse(ctx->in, 14);
  6363. a = (uint32_t *) ctx->in;
  6364. a[14] = ctx->bits[0];
  6365. a[15] = ctx->bits[1];
  6366. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  6367. mg_byte_reverse((unsigned char *) ctx->buf, 4);
  6368. memcpy(digest, ctx->buf, 16);
  6369. memset((char *) ctx, 0, sizeof(*ctx));
  6370. }
  6371. #endif
  6372. #ifdef MG_ENABLE_LINES
  6373. #line 1 "src/modbus.c"
  6374. #endif
  6375. #define MG_MODBUS_MIN_PAYLOAD_LEN 12
  6376. #define MG_MODBUS_HEADER_LEN 7
  6377. static void mg_modbus_send_mbap(struct mg_connection *c, uint16_t txid,
  6378. uint16_t pdu_len, uint8_t unit_id) {
  6379. uint8_t hdr[7];
  6380. memset(hdr, 0, sizeof(hdr));
  6381. MG_STORE_BE16(&hdr[0], txid & 0xFFFFU);
  6382. MG_STORE_BE16(&hdr[4], (pdu_len + 1) & 0xFFFFU);
  6383. hdr[6] = unit_id;
  6384. mg_send(c, hdr, sizeof(hdr));
  6385. }
  6386. static void mg_modbus_send_response(struct mg_connection *c,
  6387. struct mg_modbus_req *req,
  6388. uint16_t txid, uint8_t unit_id) {
  6389. uint8_t buf[5];
  6390. uint8_t out;
  6391. uint16_t reg;
  6392. uint16_t i, nbytes;
  6393. memset(buf, 0, sizeof(buf));
  6394. if (req == NULL) return;
  6395. if (req->error != MG_MODBUS_ERR_NONE) {
  6396. mg_modbus_send_mbap(c, txid, 2, unit_id);
  6397. buf[0] = (uint8_t) (req->func | 0x80);
  6398. buf[1] = req->error;
  6399. mg_send(c, buf, 2);
  6400. return;
  6401. }
  6402. switch (req->func) {
  6403. case MG_MODBUS_FUNC_READ_COILS:
  6404. case MG_MODBUS_FUNC_READ_DISCRETE_INPUTS:
  6405. if (req->u.bits == NULL) return;
  6406. nbytes = (uint16_t) ((req->len + 7) / 8);
  6407. mg_modbus_send_mbap(c, txid, (uint16_t) (nbytes + 2), unit_id);
  6408. buf[0] = req->func;
  6409. buf[1] = (uint8_t) nbytes;
  6410. mg_send(c, buf, 2);
  6411. memset(buf, 0, sizeof(buf));
  6412. for (i = 0; i < req->len; i++) {
  6413. if (i % 8 == 0) out = 0;
  6414. if (req->u.bits[i]) out |= (uint8_t) (1 << (i % 8));
  6415. if ((i % 8) == 7 || i + 1 == req->len) {
  6416. mg_send(c, &out, 1);
  6417. }
  6418. }
  6419. break;
  6420. case MG_MODBUS_FUNC_READ_HOLDING_REGISTERS:
  6421. case MG_MODBUS_FUNC_READ_INPUT_REGISTERS:
  6422. if (req->u.regs == NULL) return;
  6423. nbytes = (uint16_t) (req->len * 2);
  6424. mg_modbus_send_mbap(c, txid, (uint16_t) (nbytes + 2), unit_id);
  6425. buf[0] = req->func;
  6426. buf[1] = (uint8_t) nbytes;
  6427. mg_send(c, buf, 2);
  6428. for (i = 0; i < req->len; i++) {
  6429. MG_STORE_BE16(&reg, req->u.regs[i] & 0xFFFFU);
  6430. mg_send(c, &reg, 2);
  6431. }
  6432. break;
  6433. case MG_MODBUS_FUNC_WRITE_SINGLE_COIL:
  6434. if (req->len != 1 || req->u.bits == NULL) return;
  6435. mg_modbus_send_mbap(c, txid, 5, unit_id);
  6436. buf[0] = req->func;
  6437. MG_STORE_BE16(&buf[1], req->addr & 0xFFFFu);
  6438. MG_STORE_BE16(&buf[3], req->u.bits[0] ? 0xFF00U : 0x0000U);
  6439. mg_send(c, buf, 5);
  6440. break;
  6441. case MG_MODBUS_FUNC_WRITE_SINGLE_REGISTER:
  6442. if (req->len != 1 || req->u.regs == NULL) return;
  6443. mg_modbus_send_mbap(c, txid, 5, unit_id);
  6444. buf[0] = req->func;
  6445. MG_STORE_BE16(&buf[1], req->addr & 0xFFFFU);
  6446. MG_STORE_BE16(&buf[3], req->u.regs[0] & 0xFFFFU);
  6447. mg_send(c, buf, 5);
  6448. break;
  6449. case MG_MODBUS_FUNC_WRITE_MULTIPLE_COILS:
  6450. case MG_MODBUS_FUNC_WRITE_MULTIPLE_REGISTERS:
  6451. mg_modbus_send_mbap(c, txid, 5, unit_id);
  6452. buf[0] = req->func;
  6453. MG_STORE_BE16(&buf[1], req->addr & 0xFFFFU);
  6454. MG_STORE_BE16(&buf[3], req->len & 0xFFFFU);
  6455. mg_send(c, buf, 5);
  6456. break;
  6457. default:
  6458. break;
  6459. }
  6460. }
  6461. static void handle_pdu(struct mg_connection *c, uint8_t *buf, size_t len) {
  6462. uint16_t max_len, val, txid, addr, quantity;
  6463. uint8_t func, unit_id, byte_count, packed;
  6464. int i;
  6465. size_t pdu_len = len - MG_MODBUS_HEADER_LEN, len_check;
  6466. struct mg_modbus_req mr;
  6467. if (len < MG_MODBUS_MIN_PAYLOAD_LEN) return;
  6468. memset(&mr, 0, sizeof(mr));
  6469. txid = MG_LOAD_BE16(&buf[0]);
  6470. unit_id = buf[6];
  6471. func = buf[7];
  6472. addr = MG_LOAD_BE16(&buf[8]);
  6473. mr.func = func;
  6474. mr.addr = addr;
  6475. mr.error = MG_MODBUS_ERR_NONE;
  6476. mr.len = 0;
  6477. mr.u.bits = NULL;
  6478. switch (func) {
  6479. case MG_MODBUS_FUNC_READ_COILS:
  6480. case MG_MODBUS_FUNC_READ_DISCRETE_INPUTS:
  6481. if (pdu_len != 5) goto modbus_illegal_value;
  6482. quantity = MG_LOAD_BE16(&buf[10]);
  6483. max_len = 0x07D0; // 2000 bits
  6484. if (quantity == 0 || quantity > max_len) goto modbus_illegal_value;
  6485. mr.len = quantity;
  6486. mr.u.bits = (bool *) mg_calloc((size_t) mr.len, sizeof(bool));
  6487. if (mr.u.bits == NULL) goto modbus_oom;
  6488. break;
  6489. case MG_MODBUS_FUNC_READ_HOLDING_REGISTERS:
  6490. case MG_MODBUS_FUNC_READ_INPUT_REGISTERS:
  6491. if (pdu_len != 5) goto modbus_illegal_value;
  6492. quantity = MG_LOAD_BE16(&buf[10]);
  6493. max_len = 0x007D; // 125 registers
  6494. if (quantity == 0 || quantity > max_len) goto modbus_illegal_value;
  6495. mr.len = quantity;
  6496. mr.u.regs = (uint16_t *) mg_calloc((size_t) mr.len, sizeof(uint16_t));
  6497. if (mr.u.regs == NULL) goto modbus_oom;
  6498. break;
  6499. case MG_MODBUS_FUNC_WRITE_SINGLE_COIL:
  6500. if (pdu_len != 5) goto modbus_illegal_value;
  6501. mr.len = 1;
  6502. mr.u.bits = (bool *) mg_calloc(1, sizeof(bool));
  6503. if (mr.u.bits == NULL) goto modbus_oom;
  6504. val = MG_LOAD_BE16(&buf[10]);
  6505. if (val != 0x0000 && val != 0xFF00) goto modbus_illegal_value;
  6506. mr.u.bits[0] = (val == 0xFF00);
  6507. break;
  6508. case MG_MODBUS_FUNC_WRITE_SINGLE_REGISTER:
  6509. if (pdu_len != 5) goto modbus_illegal_value;
  6510. mr.len = 1;
  6511. mr.u.regs = (uint16_t *) mg_calloc(1, sizeof(uint16_t));
  6512. if (mr.u.regs == NULL) goto modbus_oom;
  6513. mr.u.regs[0] = MG_LOAD_BE16(&buf[10]);
  6514. break;
  6515. case MG_MODBUS_FUNC_WRITE_MULTIPLE_COILS: {
  6516. quantity = MG_LOAD_BE16(&buf[10]);
  6517. if (quantity == 0 || quantity > 0x07B0) goto modbus_illegal_value;
  6518. if (pdu_len < 6) goto modbus_illegal_value;
  6519. byte_count = buf[12];
  6520. if (byte_count != (uint8_t) ((quantity + 7) / 8)) goto modbus_illegal_value;
  6521. len_check = (size_t) (6 + byte_count);
  6522. if (len_check != pdu_len) goto modbus_illegal_value;
  6523. mr.len = quantity;
  6524. mr.u.bits = (bool *) mg_calloc((size_t) mr.len, sizeof(bool));
  6525. if (mr.u.bits == NULL) goto modbus_oom;
  6526. for (i = 0; i < mr.len; i++) {
  6527. packed = buf[13 + (i / 8)];
  6528. mr.u.bits[i] = ((packed >> (i % 8)) & 1) != 0;
  6529. }
  6530. break;
  6531. }
  6532. case MG_MODBUS_FUNC_WRITE_MULTIPLE_REGISTERS: {
  6533. quantity = MG_LOAD_BE16(&buf[10]);
  6534. if (quantity == 0 || quantity > 0x007B) goto modbus_illegal_value;
  6535. if (pdu_len < 6) goto modbus_illegal_value;
  6536. byte_count = buf[12];
  6537. if (byte_count != (uint8_t) (quantity * 2)) goto modbus_illegal_value;
  6538. len_check = (size_t) (6 + quantity * 2);
  6539. if (len_check != pdu_len) goto modbus_illegal_value;
  6540. mr.len = quantity;
  6541. mr.u.regs = (uint16_t *) mg_calloc((size_t) mr.len, sizeof(uint16_t));
  6542. if (mr.u.regs == NULL) goto modbus_oom;
  6543. for (i = 0; i < mr.len; i++) {
  6544. mr.u.regs[i] = MG_LOAD_BE16(&buf[13 + i * 2]);
  6545. }
  6546. break;
  6547. }
  6548. default:
  6549. MG_ERROR(("Unsupported modbus function"));
  6550. mr.error = MG_MODBUS_ERR_ILLEGAL_FUNCTION;
  6551. mg_modbus_send_response(c, &mr, txid, unit_id);
  6552. return;
  6553. }
  6554. mg_call(c, MG_EV_MODBUS_REQ, &mr);
  6555. goto modbus_exit;
  6556. modbus_illegal_value:
  6557. MG_ERROR(("Invalid data"));
  6558. mr.error = MG_MODBUS_ERR_ILLEGAL_VALUE;
  6559. goto modbus_exit;
  6560. modbus_oom:
  6561. MG_ERROR(("OOM"));
  6562. mr.error = MG_MODBUS_ERR_DEVICE_FAILURE;
  6563. modbus_exit:
  6564. mg_modbus_send_response(c, &mr, txid, unit_id);
  6565. if (mr.u.bits != NULL) mg_free(mr.u.bits);
  6566. }
  6567. static void modbus_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
  6568. if (ev == MG_EV_READ) {
  6569. while (c->recv.len >= MG_MODBUS_MIN_PAYLOAD_LEN) {
  6570. uint16_t len = MG_LOAD_BE16(&c->recv.buf[4]); // PDU length
  6571. uint16_t proto_id = MG_LOAD_BE16(&c->recv.buf[2]);
  6572. if (len < 6 || proto_id != 0) {
  6573. mg_error(c, "invalid pdu");
  6574. break;
  6575. } else if (c->recv.len < len + 6U) {
  6576. break; // Partial frame, buffer more
  6577. } else {
  6578. handle_pdu(c, c->recv.buf, len + 6); // Parse PDU and call user
  6579. mg_iobuf_del(&c->recv, 0, len + 6); // Delete received PDU
  6580. }
  6581. }
  6582. }
  6583. (void) ev_data;
  6584. }
  6585. struct mg_connection *mg_modbus_listen(struct mg_mgr *mgr, const char *url,
  6586. mg_event_handler_t fn, void *fn_data) {
  6587. struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
  6588. if (c != NULL) c->pfn = modbus_ev_handler;
  6589. return c;
  6590. }
  6591. #ifdef MG_ENABLE_LINES
  6592. #line 1 "src/mqtt.c"
  6593. #endif
  6594. #define MQTT_CLEAN_SESSION 0x02
  6595. #define MQTT_HAS_WILL 0x04
  6596. #define MQTT_WILL_RETAIN 0x20
  6597. #define MQTT_HAS_PASSWORD 0x40
  6598. #define MQTT_HAS_USER_NAME 0x80
  6599. struct mg_mqtt_pmap {
  6600. uint8_t id;
  6601. uint8_t type;
  6602. };
  6603. static const struct mg_mqtt_pmap s_prop_map[] = {
  6604. {MQTT_PROP_PAYLOAD_FORMAT_INDICATOR, MQTT_PROP_TYPE_BYTE},
  6605. {MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, MQTT_PROP_TYPE_INT},
  6606. {MQTT_PROP_CONTENT_TYPE, MQTT_PROP_TYPE_STRING},
  6607. {MQTT_PROP_RESPONSE_TOPIC, MQTT_PROP_TYPE_STRING},
  6608. {MQTT_PROP_CORRELATION_DATA, MQTT_PROP_TYPE_BINARY_DATA},
  6609. {MQTT_PROP_SUBSCRIPTION_IDENTIFIER, MQTT_PROP_TYPE_VARIABLE_INT},
  6610. {MQTT_PROP_SESSION_EXPIRY_INTERVAL, MQTT_PROP_TYPE_INT},
  6611. {MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER, MQTT_PROP_TYPE_STRING},
  6612. {MQTT_PROP_SERVER_KEEP_ALIVE, MQTT_PROP_TYPE_SHORT},
  6613. {MQTT_PROP_AUTHENTICATION_METHOD, MQTT_PROP_TYPE_STRING},
  6614. {MQTT_PROP_AUTHENTICATION_DATA, MQTT_PROP_TYPE_BINARY_DATA},
  6615. {MQTT_PROP_REQUEST_PROBLEM_INFORMATION, MQTT_PROP_TYPE_BYTE},
  6616. {MQTT_PROP_WILL_DELAY_INTERVAL, MQTT_PROP_TYPE_INT},
  6617. {MQTT_PROP_REQUEST_RESPONSE_INFORMATION, MQTT_PROP_TYPE_BYTE},
  6618. {MQTT_PROP_RESPONSE_INFORMATION, MQTT_PROP_TYPE_STRING},
  6619. {MQTT_PROP_SERVER_REFERENCE, MQTT_PROP_TYPE_STRING},
  6620. {MQTT_PROP_REASON_STRING, MQTT_PROP_TYPE_STRING},
  6621. {MQTT_PROP_RECEIVE_MAXIMUM, MQTT_PROP_TYPE_SHORT},
  6622. {MQTT_PROP_TOPIC_ALIAS_MAXIMUM, MQTT_PROP_TYPE_SHORT},
  6623. {MQTT_PROP_TOPIC_ALIAS, MQTT_PROP_TYPE_SHORT},
  6624. {MQTT_PROP_MAXIMUM_QOS, MQTT_PROP_TYPE_BYTE},
  6625. {MQTT_PROP_RETAIN_AVAILABLE, MQTT_PROP_TYPE_BYTE},
  6626. {MQTT_PROP_USER_PROPERTY, MQTT_PROP_TYPE_STRING_PAIR},
  6627. {MQTT_PROP_MAXIMUM_PACKET_SIZE, MQTT_PROP_TYPE_INT},
  6628. {MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE, MQTT_PROP_TYPE_BYTE},
  6629. {MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE, MQTT_PROP_TYPE_BYTE},
  6630. {MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE, MQTT_PROP_TYPE_BYTE}};
  6631. static bool mqtt_send_header(struct mg_connection *c, uint8_t cmd,
  6632. uint8_t flags, uint32_t len) {
  6633. uint8_t buf[1 + sizeof(len)], *vlen = &buf[1];
  6634. buf[0] = (uint8_t) ((cmd << 4) | flags);
  6635. do {
  6636. *vlen = len % 0x80;
  6637. len /= 0x80;
  6638. if (len > 0) *vlen |= 0x80;
  6639. vlen++;
  6640. } while (len > 0 && vlen < &buf[sizeof(buf)]);
  6641. return mg_send(c, buf, (size_t) (vlen - buf));
  6642. }
  6643. void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags,
  6644. uint32_t len) {
  6645. if (!mqtt_send_header(c, cmd, flags, len)) mg_error(c, "OOM");
  6646. }
  6647. static bool mg_send_u16(struct mg_connection *c, uint16_t value) {
  6648. return mg_send(c, &value, sizeof(value));
  6649. }
  6650. static bool mg_send_u32(struct mg_connection *c, uint32_t value) {
  6651. return mg_send(c, &value, sizeof(value));
  6652. }
  6653. static uint8_t varint_size(size_t length) {
  6654. uint8_t bytes_needed = 0;
  6655. do {
  6656. bytes_needed++;
  6657. length /= 0x80;
  6658. } while (length > 0);
  6659. return bytes_needed;
  6660. }
  6661. static size_t encode_varint(uint8_t *buf, size_t value) {
  6662. size_t len = 0;
  6663. do {
  6664. uint8_t b = (uint8_t) (value % 128);
  6665. value /= 128;
  6666. if (value > 0) b |= 0x80;
  6667. buf[len++] = b;
  6668. } while (value > 0);
  6669. return len;
  6670. }
  6671. static size_t decode_varint(const uint8_t *buf, size_t len, uint32_t *value) {
  6672. uint32_t mul = 1, ofs;
  6673. *value = 0;
  6674. for (ofs = 0; ofs < 4 && ofs < len; ofs++) {
  6675. uint8_t enc_byte = buf[ofs];
  6676. *value += (enc_byte & 0x7f) * mul;
  6677. mul *= 128;
  6678. if ((enc_byte & 0x80) == 0) return ofs + 1;
  6679. }
  6680. return 0;
  6681. }
  6682. static int mqtt_prop_type_by_id(uint8_t prop_id) {
  6683. size_t i, num_properties = sizeof(s_prop_map) / sizeof(s_prop_map[0]);
  6684. for (i = 0; i < num_properties; ++i) {
  6685. if (s_prop_map[i].id == prop_id) return s_prop_map[i].type;
  6686. }
  6687. return -1; // Property ID not found
  6688. }
  6689. // Returns the size of the properties section, without the
  6690. // size of the content's length
  6691. static size_t get_properties_length(struct mg_mqtt_prop *props, size_t count) {
  6692. size_t i, size = 0;
  6693. for (i = 0; i < count; i++) {
  6694. size++; // identifier
  6695. switch (mqtt_prop_type_by_id(props[i].id)) {
  6696. case MQTT_PROP_TYPE_STRING_PAIR:
  6697. size += (uint32_t) (props[i].val.len + props[i].key.len +
  6698. 2 * sizeof(uint16_t));
  6699. break;
  6700. case MQTT_PROP_TYPE_STRING:
  6701. size += (uint32_t) (props[i].val.len + sizeof(uint16_t));
  6702. break;
  6703. case MQTT_PROP_TYPE_BINARY_DATA:
  6704. size += (uint32_t) (props[i].val.len + sizeof(uint16_t));
  6705. break;
  6706. case MQTT_PROP_TYPE_VARIABLE_INT:
  6707. size += varint_size((uint32_t) props[i].iv);
  6708. break;
  6709. case MQTT_PROP_TYPE_INT: size += (uint32_t) sizeof(uint32_t); break;
  6710. case MQTT_PROP_TYPE_SHORT: size += (uint32_t) sizeof(uint16_t); break;
  6711. case MQTT_PROP_TYPE_BYTE: size += (uint32_t) sizeof(uint8_t); break;
  6712. default: return size; // cannot parse further down
  6713. }
  6714. }
  6715. return size;
  6716. }
  6717. // returns the entire size of the properties section, including the
  6718. // size of the variable length of the content
  6719. static size_t get_props_size(struct mg_mqtt_prop *props, size_t count) {
  6720. size_t size = get_properties_length(props, count);
  6721. size += varint_size(size);
  6722. return size;
  6723. }
  6724. static bool mg_send_mqtt_properties(struct mg_connection *c,
  6725. struct mg_mqtt_prop *props, size_t nprops) {
  6726. size_t total_size = get_properties_length(props, nprops);
  6727. uint8_t buf_v[4] = {0, 0, 0, 0};
  6728. uint8_t buf[4] = {0, 0, 0, 0};
  6729. size_t i, len = encode_varint(buf, total_size);
  6730. if (!mg_send(c, buf, (size_t) len)) return false;
  6731. for (i = 0; i < nprops; i++) {
  6732. if (!mg_send(c, &props[i].id, sizeof(props[i].id))) return false;
  6733. switch (mqtt_prop_type_by_id(props[i].id)) {
  6734. case MQTT_PROP_TYPE_STRING_PAIR:
  6735. if (!mg_send_u16(c, mg_htons((uint16_t) props[i].key.len)) ||
  6736. !mg_send(c, props[i].key.buf, props[i].key.len) ||
  6737. !mg_send_u16(c, mg_htons((uint16_t) props[i].val.len)) ||
  6738. !mg_send(c, props[i].val.buf, props[i].val.len))
  6739. return false;
  6740. break;
  6741. case MQTT_PROP_TYPE_BYTE:
  6742. if (!mg_send(c, &props[i].iv, sizeof(uint8_t))) return false;
  6743. break;
  6744. case MQTT_PROP_TYPE_SHORT:
  6745. if (!mg_send_u16(c, mg_htons((uint16_t) props[i].iv))) return false;
  6746. break;
  6747. case MQTT_PROP_TYPE_INT:
  6748. if (!mg_send_u32(c, mg_htonl((uint32_t) props[i].iv))) return false;
  6749. break;
  6750. case MQTT_PROP_TYPE_STRING:
  6751. if (!mg_send_u16(c, mg_htons((uint16_t) props[i].val.len)) ||
  6752. !mg_send(c, props[i].val.buf, props[i].val.len))
  6753. return false;
  6754. break;
  6755. case MQTT_PROP_TYPE_BINARY_DATA:
  6756. if (!mg_send_u16(c, mg_htons((uint16_t) props[i].val.len)) ||
  6757. !mg_send(c, props[i].val.buf, props[i].val.len))
  6758. return false;
  6759. break;
  6760. case MQTT_PROP_TYPE_VARIABLE_INT:
  6761. len = encode_varint(buf_v, props[i].iv);
  6762. if (!mg_send(c, buf_v, (size_t) len)) return false;
  6763. break;
  6764. }
  6765. }
  6766. return true;
  6767. }
  6768. size_t mg_mqtt_next_prop(struct mg_mqtt_message *msg, struct mg_mqtt_prop *prop,
  6769. size_t ofs) {
  6770. uint8_t *props = (uint8_t *) msg->dgram.buf + msg->props_start;
  6771. uint8_t *props_end = props + msg->props_size;
  6772. uint8_t *i = props + ofs;
  6773. size_t new_pos = ofs, len;
  6774. if (msg->props_start > msg->dgram.len ||
  6775. msg->props_size > msg->dgram.len - msg->props_start ||
  6776. ofs >= msg->props_size)
  6777. return 0;
  6778. memset(prop, 0, sizeof(struct mg_mqtt_prop));
  6779. prop->id = i[0];
  6780. i++, new_pos++;
  6781. switch (mqtt_prop_type_by_id(prop->id)) {
  6782. case MQTT_PROP_TYPE_STRING_PAIR:
  6783. if (i + 2 > props_end) return 0;
  6784. prop->key.len = (uint16_t) ((((uint16_t) i[0]) << 8) | i[1]);
  6785. if (i + 2 + prop->key.len > props_end) return 0;
  6786. prop->key.buf = (char *) i + 2;
  6787. i += 2 + prop->key.len;
  6788. if (i + 2 > props_end) return 0;
  6789. prop->val.len = (uint16_t) ((((uint16_t) i[0]) << 8) | i[1]);
  6790. prop->val.buf = (char *) i + 2;
  6791. if (i + 2 + prop->val.len > props_end) return 0;
  6792. new_pos += 2 * sizeof(uint16_t) + prop->val.len + prop->key.len;
  6793. break;
  6794. case MQTT_PROP_TYPE_BYTE:
  6795. if (i + 1 > props_end) return 0;
  6796. prop->iv = (uint8_t) i[0];
  6797. new_pos++;
  6798. break;
  6799. case MQTT_PROP_TYPE_SHORT:
  6800. if (i + 2 > props_end) return 0;
  6801. prop->iv = (uint16_t) ((((uint16_t) i[0]) << 8) | i[1]);
  6802. new_pos += sizeof(uint16_t);
  6803. break;
  6804. case MQTT_PROP_TYPE_INT:
  6805. if (i + 4 > props_end) return 0;
  6806. prop->iv = ((uint32_t) i[0] << 24) | ((uint32_t) i[1] << 16) |
  6807. ((uint32_t) i[2] << 8) | i[3];
  6808. new_pos += sizeof(uint32_t);
  6809. break;
  6810. case MQTT_PROP_TYPE_STRING:
  6811. if (i + 2 > props_end) return 0;
  6812. prop->val.len = (uint16_t) ((((uint16_t) i[0]) << 8) | i[1]);
  6813. prop->val.buf = (char *) i + 2;
  6814. if (i + 2 + prop->val.len > props_end) return 0;
  6815. new_pos += 2 + prop->val.len;
  6816. break;
  6817. case MQTT_PROP_TYPE_BINARY_DATA:
  6818. if (i + 2 > props_end) return 0;
  6819. prop->val.len = (uint16_t) ((((uint16_t) i[0]) << 8) | i[1]);
  6820. prop->val.buf = (char *) i + 2;
  6821. if (i + 2 + prop->val.len > props_end) return 0;
  6822. new_pos += 2 + prop->val.len;
  6823. break;
  6824. case MQTT_PROP_TYPE_VARIABLE_INT:
  6825. len = decode_varint(i, (size_t) (props_end - i), &prop->iv);
  6826. if (i + len > props_end) return 0;
  6827. new_pos = (len == 0) ? 0 : new_pos + len;
  6828. break;
  6829. default:
  6830. new_pos = 0;
  6831. break;
  6832. }
  6833. return new_pos;
  6834. }
  6835. void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
  6836. char client_id[21];
  6837. struct mg_str cid = opts->client_id;
  6838. size_t total_len = 7 + 1 + 2 + 2;
  6839. uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', 0, 0};
  6840. hdr[6] = opts->version;
  6841. if (cid.len == 0) {
  6842. mg_random_str(client_id, sizeof(client_id) - 1);
  6843. client_id[sizeof(client_id) - 1] = '\0';
  6844. cid = mg_str(client_id);
  6845. }
  6846. if (hdr[6] == 0) hdr[6] = 4; // If version is not set, use 4 (3.1.1)
  6847. c->is_mqtt5 = hdr[6] == 5; // Set version 5 flag
  6848. hdr[7] = (uint8_t) ((opts->qos & 3) << 3); // Connection flags
  6849. if (opts->user.len > 0) {
  6850. total_len += 2 + (uint32_t) opts->user.len;
  6851. hdr[7] |= MQTT_HAS_USER_NAME;
  6852. }
  6853. if (opts->pass.len > 0) {
  6854. total_len += 2 + (uint32_t) opts->pass.len;
  6855. hdr[7] |= MQTT_HAS_PASSWORD;
  6856. }
  6857. if (opts->topic.len > 0) { // allow zero-length msgs, message.len is size_t
  6858. total_len += 4 + (uint32_t) opts->topic.len + (uint32_t) opts->message.len;
  6859. hdr[7] |= MQTT_HAS_WILL;
  6860. }
  6861. if (opts->clean || cid.len == 0) hdr[7] |= MQTT_CLEAN_SESSION;
  6862. if (opts->retain) hdr[7] |= MQTT_WILL_RETAIN;
  6863. total_len += (uint32_t) cid.len;
  6864. if (c->is_mqtt5) {
  6865. total_len += get_props_size(opts->props, opts->num_props);
  6866. if (hdr[7] & MQTT_HAS_WILL)
  6867. total_len += get_props_size(opts->will_props, opts->num_will_props);
  6868. }
  6869. // keepalive == 0 means "do not disconnect us!"
  6870. if (!mqtt_send_header(c, MQTT_CMD_CONNECT, 0, (uint32_t) total_len) ||
  6871. !mg_send(c, hdr, sizeof(hdr)) ||
  6872. !mg_send_u16(c, mg_htons((uint16_t) opts->keepalive)))
  6873. goto fail;
  6874. if (c->is_mqtt5 && !mg_send_mqtt_properties(c, opts->props, opts->num_props))
  6875. goto fail;
  6876. if (!mg_send_u16(c, mg_htons((uint16_t) cid.len)) ||
  6877. !mg_send(c, cid.buf, cid.len))
  6878. goto fail;
  6879. if (hdr[7] & MQTT_HAS_WILL) {
  6880. if (c->is_mqtt5 &&
  6881. !mg_send_mqtt_properties(c, opts->will_props, opts->num_will_props))
  6882. goto fail;
  6883. if (!mg_send_u16(c, mg_htons((uint16_t) opts->topic.len)) ||
  6884. !mg_send(c, opts->topic.buf, opts->topic.len) ||
  6885. !mg_send_u16(c, mg_htons((uint16_t) opts->message.len)) ||
  6886. !mg_send(c, opts->message.buf, opts->message.len))
  6887. goto fail;
  6888. }
  6889. if (opts->user.len > 0 &&
  6890. (!mg_send_u16(c, mg_htons((uint16_t) opts->user.len)) ||
  6891. !mg_send(c, opts->user.buf, opts->user.len)))
  6892. goto fail;
  6893. if (opts->pass.len > 0 &&
  6894. (!mg_send_u16(c, mg_htons((uint16_t) opts->pass.len)) ||
  6895. !mg_send(c, opts->pass.buf, opts->pass.len)))
  6896. goto fail;
  6897. return;
  6898. fail:
  6899. mg_error(c, "OOM");
  6900. }
  6901. uint16_t mg_mqtt_pub(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
  6902. uint16_t id = opts->retransmit_id;
  6903. uint8_t flags = (uint8_t) (((opts->qos & 3) << 1) | (opts->retain ? 1 : 0));
  6904. size_t len = 2 + opts->topic.len + opts->message.len;
  6905. MG_DEBUG(("%lu [%.*s] <- [%.*s%c", c->id, (int) opts->topic.len,
  6906. (char *) opts->topic.buf,
  6907. (int) (opts->message.len <= 10 ? opts->message.len : 10),
  6908. (char *) opts->message.buf, opts->message.len <= 10 ? ']' : ' '));
  6909. if (opts->qos > 0) len += 2;
  6910. if (c->is_mqtt5) len += get_props_size(opts->props, opts->num_props);
  6911. if (opts->qos > 0 && id != 0) flags |= 1 << 3;
  6912. if (!mqtt_send_header(c, MQTT_CMD_PUBLISH, flags, (uint32_t) len) ||
  6913. !mg_send_u16(c, mg_htons((uint16_t) opts->topic.len)) ||
  6914. !mg_send(c, opts->topic.buf, opts->topic.len))
  6915. goto fail;
  6916. if (opts->qos > 0) { // need to send 'id' field
  6917. if (id == 0) { // generate new one if not resending
  6918. if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id;
  6919. id = c->mgr->mqtt_id;
  6920. }
  6921. if (!mg_send_u16(c, mg_htons(id))) goto fail;
  6922. }
  6923. if (c->is_mqtt5 && !mg_send_mqtt_properties(c, opts->props, opts->num_props))
  6924. goto fail;
  6925. if (opts->message.len > 0 &&
  6926. !mg_send(c, opts->message.buf, opts->message.len))
  6927. goto fail;
  6928. return id;
  6929. fail:
  6930. mg_error(c, "OOM");
  6931. return id;
  6932. }
  6933. static void mg_mqtt_sub_unsub(struct mg_connection *c,
  6934. const struct mg_mqtt_opts *opts, uint8_t cmd) {
  6935. uint8_t qos_ = opts->qos & 3;
  6936. bool is_sub = cmd == MQTT_CMD_SUBSCRIBE;
  6937. size_t plen = c->is_mqtt5 ? get_props_size(opts->props, opts->num_props) : 0;
  6938. size_t len = 2 + opts->topic.len + 2 + (is_sub ? 1 : 0) + plen;
  6939. if (!mqtt_send_header(c, cmd, 2, (uint32_t) len)) goto fail;
  6940. if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id;
  6941. if (!mg_send_u16(c, mg_htons(c->mgr->mqtt_id))) goto fail;
  6942. if (c->is_mqtt5 && !mg_send_mqtt_properties(c, opts->props, opts->num_props))
  6943. goto fail;
  6944. if (!mg_send_u16(c, mg_htons((uint16_t) opts->topic.len)) ||
  6945. !mg_send(c, opts->topic.buf, opts->topic.len))
  6946. goto fail;
  6947. if (is_sub && !mg_send(c, &qos_, sizeof(qos_))) goto fail;
  6948. return;
  6949. fail:
  6950. mg_error(c, "OOM");
  6951. }
  6952. void mg_mqtt_sub(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
  6953. mg_mqtt_sub_unsub(c, opts, MQTT_CMD_SUBSCRIBE);
  6954. }
  6955. void mg_mqtt_unsub(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
  6956. mg_mqtt_sub_unsub(c, opts, MQTT_CMD_UNSUBSCRIBE);
  6957. }
  6958. int mg_mqtt_parse(const uint8_t *buf, size_t len, uint8_t version,
  6959. struct mg_mqtt_message *m) {
  6960. uint8_t lc = 0, *p, *end;
  6961. uint32_t n = 0, len_len = 0, tmp;
  6962. memset(m, 0, sizeof(*m));
  6963. m->dgram.buf = (char *) buf;
  6964. if (len < 2) return MQTT_INCOMPLETE;
  6965. m->cmd = (uint8_t) (buf[0] >> 4);
  6966. m->qos = (buf[0] >> 1) & 3;
  6967. n = len_len = 0;
  6968. p = (uint8_t *) buf + 1;
  6969. while ((size_t) (p - buf) < len) {
  6970. lc = *((uint8_t *) p++);
  6971. n += (uint32_t) ((lc & 0x7f) << 7 * len_len);
  6972. len_len++;
  6973. if (!(lc & 0x80)) break;
  6974. if (len_len >= 4) return MQTT_MALFORMED;
  6975. }
  6976. end = p + n;
  6977. if ((lc & 0x80) || (end > buf + len)) return MQTT_INCOMPLETE;
  6978. m->dgram.len = (size_t) (end - buf);
  6979. switch (m->cmd) {
  6980. case MQTT_CMD_CONNACK:
  6981. if (end - p < 2) return MQTT_MALFORMED;
  6982. m->ack = p[1];
  6983. break;
  6984. case MQTT_CMD_PUBACK:
  6985. case MQTT_CMD_PUBREC:
  6986. case MQTT_CMD_PUBREL:
  6987. case MQTT_CMD_PUBCOMP:
  6988. case MQTT_CMD_SUBSCRIBE:
  6989. case MQTT_CMD_SUBACK:
  6990. case MQTT_CMD_UNSUBSCRIBE:
  6991. case MQTT_CMD_UNSUBACK:
  6992. if (p + 2 > end) return MQTT_MALFORMED;
  6993. m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
  6994. p += 2;
  6995. break;
  6996. case MQTT_CMD_PUBLISH: {
  6997. if (p + 2 > end) return MQTT_MALFORMED;
  6998. m->topic.len = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
  6999. m->topic.buf = (char *) p + 2;
  7000. p += 2 + m->topic.len;
  7001. if (p > end) return MQTT_MALFORMED;
  7002. if (m->qos > 0) {
  7003. if (p + 2 > end) return MQTT_MALFORMED;
  7004. m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
  7005. p += 2;
  7006. }
  7007. if (p > end) return MQTT_MALFORMED;
  7008. if (version == 5 && p + 2 < end) {
  7009. len_len = (uint32_t) decode_varint(p, (size_t) (end - p), &tmp);
  7010. if (!len_len) return MQTT_MALFORMED;
  7011. m->props_size = (size_t) tmp;
  7012. m->props_start = (size_t) (p + len_len - buf);
  7013. p += len_len + m->props_size;
  7014. }
  7015. if (p > end) return MQTT_MALFORMED;
  7016. m->data.buf = (char *) p;
  7017. m->data.len = (size_t) (end - p);
  7018. break;
  7019. }
  7020. default: break;
  7021. }
  7022. return MQTT_OK;
  7023. }
  7024. static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data) {
  7025. if (ev == MG_EV_READ) {
  7026. for (;;) {
  7027. uint8_t version = c->is_mqtt5 ? 5 : 4;
  7028. struct mg_mqtt_message mm;
  7029. int rc = mg_mqtt_parse(c->recv.buf, c->recv.len, version, &mm);
  7030. if (rc == MQTT_MALFORMED) {
  7031. MG_ERROR(("%lu MQTT malformed message", c->id));
  7032. c->is_closing = 1;
  7033. break;
  7034. } else if (rc == MQTT_OK) {
  7035. MG_VERBOSE(("%lu MQTT CMD %d len %d [%.*s]", c->id, mm.cmd,
  7036. (int) mm.dgram.len, (int) mm.data.len, mm.data.buf));
  7037. switch (mm.cmd) {
  7038. case MQTT_CMD_CONNACK:
  7039. mg_call(c, MG_EV_MQTT_OPEN, &mm.ack);
  7040. if (mm.ack == 0) {
  7041. MG_DEBUG(("%lu Connected", c->id));
  7042. } else {
  7043. MG_ERROR(("%lu MQTT auth failed, code %d", c->id, mm.ack));
  7044. c->is_closing = 1;
  7045. }
  7046. break;
  7047. case MQTT_CMD_PUBLISH: {
  7048. MG_DEBUG(("%lu [%.*s] -> [%.*s%c", c->id, (int) mm.topic.len,
  7049. mm.topic.buf,
  7050. (int) (mm.data.len <= 10 ? mm.data.len : 10), mm.data.buf,
  7051. mm.data.len <= 10 ? ']' : ' '));
  7052. if (mm.qos > 0) {
  7053. uint16_t id = mg_ntohs(mm.id);
  7054. uint32_t remaining_len = sizeof(id);
  7055. if (c->is_mqtt5) remaining_len += 2; // 3.4.2
  7056. if (!mqtt_send_header(c,
  7057. (uint8_t) (mm.qos == 2 ? MQTT_CMD_PUBREC
  7058. : MQTT_CMD_PUBACK),
  7059. 0, remaining_len) ||
  7060. !mg_send(c, &id, sizeof(id)))
  7061. goto fail;
  7062. if (c->is_mqtt5) {
  7063. uint16_t zero = 0;
  7064. if (!mg_send(c, &zero, sizeof(zero))) goto fail;
  7065. }
  7066. }
  7067. mg_call(c, MG_EV_MQTT_MSG, &mm); // let the app handle qos stuff
  7068. break;
  7069. }
  7070. case MQTT_CMD_PUBREC: { // MQTT5: 3.5.2-1 TODO(): variable header rc
  7071. uint16_t id = mg_ntohs(mm.id);
  7072. uint32_t remaining_len = sizeof(id); // MQTT5 3.6.2-1
  7073. if (!mqtt_send_header(c, MQTT_CMD_PUBREL, 2,
  7074. remaining_len) // MQTT5 3.6.1-1, flags = 2
  7075. || !mg_send(c, &id, sizeof(id)))
  7076. goto fail;
  7077. break;
  7078. }
  7079. case MQTT_CMD_PUBREL: { // MQTT5: 3.6.2-1 TODO(): variable header rc
  7080. uint16_t id = mg_ntohs(mm.id);
  7081. uint32_t remaining_len = sizeof(id); // MQTT5 3.7.2-1
  7082. if (!mqtt_send_header(c, MQTT_CMD_PUBCOMP, 0, remaining_len) ||
  7083. !mg_send(c, &id, sizeof(id)))
  7084. goto fail;
  7085. break;
  7086. }
  7087. }
  7088. mg_call(c, MG_EV_MQTT_CMD, &mm);
  7089. mg_iobuf_del(&c->recv, 0, mm.dgram.len);
  7090. } else {
  7091. break;
  7092. }
  7093. }
  7094. }
  7095. (void) ev_data;
  7096. return;
  7097. fail:
  7098. mg_error(c, "OOM");
  7099. }
  7100. void mg_mqtt_ping(struct mg_connection *nc) {
  7101. mg_mqtt_send_header(nc, MQTT_CMD_PINGREQ, 0, 0);
  7102. }
  7103. void mg_mqtt_pong(struct mg_connection *nc) {
  7104. mg_mqtt_send_header(nc, MQTT_CMD_PINGRESP, 0, 0);
  7105. }
  7106. void mg_mqtt_disconnect(struct mg_connection *c,
  7107. const struct mg_mqtt_opts *opts) {
  7108. size_t len = 0;
  7109. if (c->is_mqtt5) len = 1 + get_props_size(opts->props, opts->num_props);
  7110. if (!mqtt_send_header(c, MQTT_CMD_DISCONNECT, 0, (uint32_t) len)) goto fail;
  7111. if (c->is_mqtt5) {
  7112. uint8_t zero = 0;
  7113. if (!mg_send(c, &zero, sizeof(zero)) // reason code
  7114. || !mg_send_mqtt_properties(c, opts->props, opts->num_props))
  7115. goto fail;
  7116. }
  7117. return;
  7118. fail:
  7119. mg_error(c, "OOM");
  7120. }
  7121. struct mg_connection *mg_mqtt_connect(struct mg_mgr *mgr, const char *url,
  7122. const struct mg_mqtt_opts *opts,
  7123. mg_event_handler_t fn, void *fn_data) {
  7124. struct mg_connection *c =
  7125. mg_connect_svc(mgr, url, fn, fn_data, mqtt_cb, NULL);
  7126. if (c != NULL) {
  7127. struct mg_mqtt_opts empty;
  7128. memset(&empty, 0, sizeof(empty));
  7129. mg_mqtt_login(c, opts == NULL ? &empty : opts);
  7130. }
  7131. return c;
  7132. }
  7133. struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
  7134. mg_event_handler_t fn, void *fn_data) {
  7135. struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
  7136. if (c != NULL) c->pfn = mqtt_cb, c->pfn_data = mgr;
  7137. return c;
  7138. }
  7139. #ifdef MG_ENABLE_LINES
  7140. #line 1 "src/net.c"
  7141. #endif
  7142. size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list *ap) {
  7143. size_t old = c->send.len;
  7144. size_t expected = mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
  7145. size_t actual = c->send.len - old;
  7146. if (actual != expected) {
  7147. mg_error(c, "OOM");
  7148. c->send.len = old;
  7149. actual = 0;
  7150. }
  7151. return actual;
  7152. }
  7153. size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
  7154. size_t len = 0;
  7155. va_list ap;
  7156. va_start(ap, fmt);
  7157. len = mg_vprintf(c, fmt, &ap);
  7158. va_end(ap);
  7159. return len;
  7160. }
  7161. bool mg_dscp(struct mg_connection *c, uint8_t dscp) {
  7162. #if MG_ENABLE_SOCKET
  7163. #if MG_ENABLE_FREERTOS_TCP || MG_ARCH == MG_ARCH_THREADX || \
  7164. MG_ARCH == MG_ARCH_TIRTOS || MG_ARCH == MG_ARCH_WIN32
  7165. (void) c;
  7166. (void) dscp;
  7167. #else
  7168. int tos = dscp << 2, level = IPPROTO_IP, optname = IP_TOS;
  7169. c->dscp = (unsigned) (dscp & 63);
  7170. #if MG_ENABLE_IPV6 && !MG_ENABLE_LWIP
  7171. if (c->loc.is_ip6)
  7172. level = IPPROTO_IPV6, optname = IPV6_TCLASS;
  7173. #endif
  7174. return setsockopt((MG_SOCKET_TYPE) (size_t) c->fd, level, optname, (char *) &tos, sizeof(tos)) == 0;
  7175. #endif
  7176. #elif MG_ENABLE_TCPIP
  7177. c->dscp = (unsigned) (dscp & 63);
  7178. return true;
  7179. #endif
  7180. return false;
  7181. }
  7182. static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
  7183. uint32_t localhost = mg_htonl(0x7f000001);
  7184. if (mg_strcasecmp(str, mg_str("localhost")) != 0) return false;
  7185. memcpy(addr->addr.ip, &localhost, sizeof(uint32_t));
  7186. addr->is_ip6 = false;
  7187. return true;
  7188. }
  7189. static bool mg_atone(struct mg_str str, struct mg_addr *addr) {
  7190. if (str.len > 0) return false;
  7191. memset(addr->addr.ip, 0, sizeof(addr->addr.ip));
  7192. addr->is_ip6 = false;
  7193. return true;
  7194. }
  7195. static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
  7196. uint8_t data[4] = {0, 0, 0, 0};
  7197. size_t i, num_dots = 0;
  7198. for (i = 0; i < str.len; i++) {
  7199. if (str.buf[i] >= '0' && str.buf[i] <= '9') {
  7200. int octet = data[num_dots] * 10 + (str.buf[i] - '0');
  7201. if (octet > 255) return false;
  7202. data[num_dots] = (uint8_t) octet;
  7203. } else if (str.buf[i] == '.') {
  7204. if (num_dots >= 3 || i == 0 || str.buf[i - 1] == '.') return false;
  7205. num_dots++;
  7206. } else {
  7207. return false;
  7208. }
  7209. }
  7210. if (num_dots != 3 || str.buf[i - 1] == '.') return false;
  7211. memcpy(&addr->addr.ip, data, sizeof(data));
  7212. addr->is_ip6 = false;
  7213. return true;
  7214. }
  7215. static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) {
  7216. int i;
  7217. uint32_t ipv4;
  7218. if (str.len < 14) return false;
  7219. if (str.buf[0] != ':' || str.buf[1] != ':' || str.buf[6] != ':') return false;
  7220. for (i = 2; i < 6; i++) {
  7221. if (str.buf[i] != 'f' && str.buf[i] != 'F') return false;
  7222. }
  7223. // struct mg_str s = mg_str_n(&str.buf[7], str.len - 7);
  7224. if (!mg_aton4(mg_str_n(&str.buf[7], str.len - 7), addr)) return false;
  7225. memcpy(&ipv4, addr->addr.ip, sizeof(ipv4));
  7226. memset(addr->addr.ip, 0, sizeof(addr->addr.ip));
  7227. addr->addr.ip[10] = addr->addr.ip[11] = 255;
  7228. memcpy(&addr->addr.ip[12], &ipv4, 4);
  7229. addr->is_ip6 = true;
  7230. return true;
  7231. }
  7232. static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
  7233. size_t i, j = 0, n = 0, dc = 42;
  7234. uint16_t val = 0;
  7235. bool have = false;
  7236. addr->scope_id = 0;
  7237. if (str.len > 2 && str.buf[0] == '[') str.buf++, str.len -= 2;
  7238. if (mg_v4mapped(str, addr)) return true; // sets addr->is_ip6
  7239. for (i = 0; i < str.len; i++) {
  7240. int x = str.buf[i] >= '0' && str.buf[i] <= '9' ? str.buf[i] - '0'
  7241. : str.buf[i] >= 'a' && str.buf[i] <= 'f' ? str.buf[i] - 'a' + 10
  7242. : str.buf[i] >= 'A' && str.buf[i] <= 'F' ? str.buf[i] - 'A' + 10
  7243. : -1;
  7244. if (x >= 0) {
  7245. if (i > j + 3) return false;
  7246. val = (uint16_t) ((val << 4) | (uint16_t) x);
  7247. have = true;
  7248. continue;
  7249. }
  7250. if (have) {
  7251. addr->addr.ip[n] = (uint8_t) (val >> 8),
  7252. addr->addr.ip[n + 1] = (uint8_t) val;
  7253. val = 0, have = false;
  7254. }
  7255. if (str.buf[i] == ':') {
  7256. j = i + 1;
  7257. if (i > 0 && str.buf[i - 1] == ':') {
  7258. if (dc != 42) return false;
  7259. dc = n; // Double colon
  7260. if (i > 1 && str.buf[i - 2] == ':') return false;
  7261. } else if (i > 0) {
  7262. n += 2;
  7263. }
  7264. if (n > 14) return false;
  7265. addr->addr.ip[n] = addr->addr.ip[n + 1] = 0; // For trailing ::
  7266. } else if (str.buf[i] == '%') { // Scope ID, last in string
  7267. if (mg_str_to_num(mg_str_n(&str.buf[i + 1], str.len - i - 1), 10,
  7268. &addr->scope_id, sizeof(uint8_t))) {
  7269. addr->is_ip6 = true;
  7270. return true;
  7271. } else {
  7272. return false;
  7273. }
  7274. } else {
  7275. return false;
  7276. }
  7277. }
  7278. if (have)
  7279. addr->addr.ip[n] = (uint8_t) (val >> 8),
  7280. addr->addr.ip[n + 1] = (uint8_t) val;
  7281. if (n < 14 && dc == 42) return false;
  7282. if (n < 14) {
  7283. memmove(&addr->addr.ip[dc + (14 - n)], &addr->addr.ip[dc], n - dc + 2);
  7284. memset(&addr->addr.ip[dc], 0, 14 - n);
  7285. }
  7286. addr->is_ip6 = true;
  7287. return true;
  7288. }
  7289. bool mg_aton(struct mg_str str, struct mg_addr *addr) {
  7290. // MG_INFO(("[%.*s]", (int) str.len, str.buf));
  7291. return mg_atone(str, addr) || mg_atonl(str, addr) || mg_aton4(str, addr) ||
  7292. mg_aton6(str, addr);
  7293. }
  7294. struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr) {
  7295. struct mg_connection *c =
  7296. (struct mg_connection *) mg_calloc(1, sizeof(*c) + mgr->extraconnsize);
  7297. if (c != NULL) {
  7298. c->mgr = mgr;
  7299. c->send.align = c->recv.align = c->rtls.align = MG_IO_SIZE;
  7300. c->id = ++mgr->nextid;
  7301. MG_PROF_INIT(c);
  7302. }
  7303. return c;
  7304. }
  7305. void mg_close_conn(struct mg_connection *c) {
  7306. mg_resolve_cancel(c); // Close any pending DNS query
  7307. LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
  7308. if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
  7309. if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
  7310. // Order of operations is important. `MG_EV_CLOSE` event must be fired
  7311. // before we deallocate received data, see #1331
  7312. mg_call(c, MG_EV_CLOSE, NULL);
  7313. MG_DEBUG(("%lu %ld closed", c->id, c->fd));
  7314. MG_PROF_DUMP(c);
  7315. MG_PROF_FREE(c);
  7316. mg_tls_free(c);
  7317. mg_iobuf_free(&c->recv);
  7318. mg_iobuf_free(&c->send);
  7319. mg_iobuf_free(&c->rtls);
  7320. mg_bzero((unsigned char *) c, sizeof(*c));
  7321. mg_free(c);
  7322. }
  7323. struct mg_connection *mg_connect_svc(struct mg_mgr *mgr, const char *url,
  7324. mg_event_handler_t fn, void *fn_data,
  7325. mg_event_handler_t pfn, void *pfn_data) {
  7326. struct mg_connection *c = NULL;
  7327. if (url == NULL || url[0] == '\0') {
  7328. MG_ERROR(("null url"));
  7329. #if MG_ENABLE_TCPIP
  7330. } else if (mgr->ifp != NULL && mgr->ifp->state != MG_TCPIP_STATE_READY) {
  7331. MG_ERROR(("Network is down"));
  7332. #endif
  7333. } else if ((c = mg_alloc_conn(mgr)) == NULL) {
  7334. MG_ERROR(("OOM"));
  7335. } else {
  7336. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  7337. c->is_udp = (strncmp(url, "udp:", 4) == 0);
  7338. c->fd = (void *) (size_t) MG_INVALID_SOCKET;
  7339. c->fn = fn;
  7340. c->is_client = true;
  7341. c->fn_data = fn_data;
  7342. c->is_tls = (mg_url_is_ssl(url) != 0);
  7343. c->pfn = pfn;
  7344. c->pfn_data = pfn_data;
  7345. mg_call(c, MG_EV_OPEN, (void *) url);
  7346. MG_DEBUG(("%lu %ld %s", c->id, c->fd, url));
  7347. mg_resolve(c, url);
  7348. }
  7349. return c;
  7350. }
  7351. struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url,
  7352. mg_event_handler_t fn, void *fn_data) {
  7353. return mg_connect_svc(mgr, url, fn, fn_data, NULL, NULL);
  7354. }
  7355. struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
  7356. mg_event_handler_t fn, void *fn_data) {
  7357. struct mg_connection *c = NULL;
  7358. if ((c = mg_alloc_conn(mgr)) == NULL) {
  7359. MG_ERROR(("OOM %s", url));
  7360. } else if (!mg_open_listener(c, url)) {
  7361. MG_ERROR(("Failed: %s", url));
  7362. MG_PROF_FREE(c);
  7363. mg_free(c);
  7364. c = NULL;
  7365. } else {
  7366. c->is_listening = 1;
  7367. c->is_udp = strncmp(url, "udp:", 4) == 0;
  7368. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  7369. c->fn = fn;
  7370. c->fn_data = fn_data;
  7371. c->is_tls = (mg_url_is_ssl(url) != 0);
  7372. mg_call(c, MG_EV_OPEN, NULL);
  7373. MG_DEBUG(("%lu %ld %s", c->id, c->fd, url));
  7374. }
  7375. return c;
  7376. }
  7377. struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
  7378. mg_event_handler_t fn, void *fn_data) {
  7379. struct mg_connection *c = mg_alloc_conn(mgr);
  7380. if (c != NULL) {
  7381. c->fd = (void *) (size_t) fd;
  7382. c->fn = fn;
  7383. c->fn_data = fn_data;
  7384. MG_EPOLL_ADD(c);
  7385. mg_call(c, MG_EV_OPEN, NULL);
  7386. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  7387. }
  7388. return c;
  7389. }
  7390. struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
  7391. unsigned flags, void (*fn)(void *), void *arg) {
  7392. struct mg_timer *t = (struct mg_timer *) mg_calloc(1, sizeof(*t));
  7393. if (t != NULL) {
  7394. flags |= MG_TIMER_AUTODELETE; // We have alloc'ed it, so autodelete
  7395. mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
  7396. }
  7397. return t;
  7398. }
  7399. long mg_io_recv(struct mg_connection *c, void *buf, size_t len) {
  7400. if (c->rtls.len == 0) return MG_IO_WAIT;
  7401. if (len > c->rtls.len) len = c->rtls.len;
  7402. memcpy(buf, c->rtls.buf, len);
  7403. mg_iobuf_del(&c->rtls, 0, len);
  7404. return (long) len;
  7405. }
  7406. void mg_mgr_free(struct mg_mgr *mgr) {
  7407. struct mg_connection *c;
  7408. struct mg_timer *tmp, *t = mgr->timers;
  7409. while (t != NULL) tmp = t->next, mg_free(t), t = tmp;
  7410. mgr->timers = NULL; // Important. Next call to poll won't touch timers
  7411. for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
  7412. mg_mgr_poll(mgr, 0);
  7413. #if MG_ENABLE_FREERTOS_TCP
  7414. FreeRTOS_DeleteSocketSet(mgr->ss);
  7415. #endif
  7416. MG_DEBUG(("All connections closed"));
  7417. #if MG_ENABLE_EPOLL
  7418. if (mgr->epoll_fd >= 0) close(mgr->epoll_fd), mgr->epoll_fd = -1;
  7419. #endif
  7420. mg_tls_ctx_free(mgr);
  7421. #if MG_ENABLE_TCPIP
  7422. if (mgr->ifp) mg_tcpip_free(mgr->ifp);
  7423. #endif
  7424. }
  7425. void mg_mgr_init(struct mg_mgr *mgr) {
  7426. memset(mgr, 0, sizeof(*mgr));
  7427. #if MG_ENABLE_EPOLL
  7428. if ((mgr->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
  7429. MG_ERROR(("epoll_create1 errno %d", errno));
  7430. #else
  7431. mgr->epoll_fd = -1;
  7432. #endif
  7433. #if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
  7434. // clang-format off
  7435. { WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); }
  7436. // clang-format on
  7437. #elif MG_ENABLE_FREERTOS_TCP
  7438. mgr->ss = FreeRTOS_CreateSocketSet();
  7439. #elif MG_ARCH == MG_ARCH_UNIX
  7440. // Ignore SIGPIPE signal, so if client cancels the request, it
  7441. // won't kill the whole process.
  7442. signal(SIGPIPE, SIG_IGN);
  7443. #elif MG_ENABLE_TCPIP_DRIVER_INIT && defined(MG_TCPIP_DRIVER_INIT)
  7444. MG_TCPIP_DRIVER_INIT(mgr);
  7445. #endif
  7446. #if MG_ENABLE_BSD_SOCKETS
  7447. mgr->pipe.q = NULL;
  7448. #else
  7449. mgr->pipe.fd = MG_INVALID_SOCKET;
  7450. #endif
  7451. mgr->dnstimeout = 3000;
  7452. mgr->dns4.url = "udp://8.8.8.8:53";
  7453. mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
  7454. mg_tls_ctx_init(mgr);
  7455. MG_DEBUG(("MG_IO_SIZE: %lu, TLS: %s", MG_IO_SIZE,
  7456. MG_TLS == MG_TLS_NONE ? "none"
  7457. : MG_TLS == MG_TLS_MBED ? "MbedTLS"
  7458. : MG_TLS == MG_TLS_OPENSSL ? "OpenSSL"
  7459. : MG_TLS == MG_TLS_BUILTIN ? "builtin"
  7460. : MG_TLS == MG_TLS_WOLFSSL ? "WolfSSL"
  7461. : "custom"));
  7462. }
  7463. #if MG_ENABLE_TCPIP
  7464. void mg_tcpip_mapip(struct mg_connection *, struct mg_addr *);
  7465. #endif
  7466. void mg_multicast_restore(struct mg_connection *c, uint8_t *from) {
  7467. memcpy(&c->rem, from, sizeof(c->rem));
  7468. #if MG_ENABLE_TCPIP
  7469. mg_tcpip_mapip(c, &c->rem);
  7470. #endif
  7471. }
  7472. #ifdef MG_ENABLE_LINES
  7473. #line 1 "src/net_builtin.c"
  7474. #endif
  7475. #if MG_ENABLE_TCPIP
  7476. #define MG_EPHEMERAL_PORT_BASE 32768
  7477. #define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
  7478. #ifndef MG_TCPIP_KEEPALIVE_MS
  7479. #define MG_TCPIP_KEEPALIVE_MS 45000 // TCP keep-alive period, ms
  7480. #endif
  7481. #define MG_TCPIP_ACK_MS 150 // Timeout for ACKing
  7482. #define MG_TCPIP_ARP_MS 100 // Timeout for ARP response
  7483. #define MG_TCPIP_SYN_MS 15000 // Timeout for connection establishment
  7484. #define MG_TCPIP_FIN_MS 1000 // Timeout for closing connection
  7485. #ifndef MG_TCPIP_WIN
  7486. #define MG_TCPIP_WIN 6000 // TCP window size
  7487. #endif
  7488. struct connstate {
  7489. uint32_t seq, ack; // TCP seq/ack counters
  7490. uint64_t timer; // TCP timer (see 'ttype' below)
  7491. uint32_t acked; // Last ACK-ed number
  7492. size_t unacked; // Not acked bytes
  7493. uint32_t maxseq; // Max send seq (ack + window)
  7494. uint16_t win; // destination current window size
  7495. uint16_t dmss; // destination MSS (from TCP opts)
  7496. uint8_t mac[sizeof(struct mg_l2addr)]; // Peer hw address
  7497. uint8_t ttype; // Timer type:
  7498. #define MIP_TTYPE_KEEPALIVE 0 // Connection is idle for long, send keepalive
  7499. #define MIP_TTYPE_ACK 1 // Peer sent us data, we have to ack it soon
  7500. #define MIP_TTYPE_ARP 2 // ARP resolve sent, waiting for response
  7501. #define MIP_TTYPE_SYN 3 // SYN sent, waiting for response
  7502. #define MIP_TTYPE_FIN 4 // FIN sent, waiting until terminating the connection
  7503. uint8_t tmiss; // Number of keep-alive misses
  7504. bool fin_rcvd; // We have received FIN from the peer
  7505. bool twclosure; // 3-way closure done
  7506. };
  7507. #if defined(__DCC__)
  7508. #pragma pack(1)
  7509. #else
  7510. #pragma pack(push, 1)
  7511. #endif
  7512. struct ip {
  7513. uint8_t ver; // Version
  7514. uint8_t tos; // DS field
  7515. uint16_t len; // Datagram length
  7516. uint16_t id; // Unused
  7517. uint16_t frag; // Fragmentation
  7518. #define IP_FRAG_OFFSET_MSK 0x1fff
  7519. #define IP_MORE_FRAGS_MSK 0x2000
  7520. uint8_t ttl; // Time to live
  7521. uint8_t proto; // Upper level protocol
  7522. uint16_t csum; // Checksum
  7523. uint32_t src; // Source IP
  7524. uint32_t dst; // Destination IP
  7525. };
  7526. struct ip6 {
  7527. uint8_t ver; // Version
  7528. uint8_t label[3]; // Flow label
  7529. uint16_t plen; // Payload length
  7530. uint8_t next; // Upper level protocol
  7531. uint8_t hops; // Hop limit
  7532. uint64_t src[2]; // Source IP
  7533. uint64_t dst[2]; // Destination IP
  7534. };
  7535. struct icmp {
  7536. uint8_t type;
  7537. uint8_t code;
  7538. uint16_t csum;
  7539. };
  7540. struct icmp6 {
  7541. uint8_t type;
  7542. uint8_t code;
  7543. uint16_t csum;
  7544. };
  7545. struct ndp_na {
  7546. uint8_t res[4]; // R S O, reserved
  7547. uint64_t addr[2]; // Target address
  7548. };
  7549. struct ndp_ra {
  7550. uint8_t cur_hop_limit;
  7551. uint8_t flags; // M,O,Prf,Resvd
  7552. uint16_t router_lifetime;
  7553. uint32_t reachable_time;
  7554. uint32_t retrans_timer;
  7555. };
  7556. struct arp {
  7557. uint16_t fmt; // Format of hardware address
  7558. uint16_t pro; // Format of protocol address
  7559. uint8_t hlen; // Length of hardware address
  7560. uint8_t plen; // Length of protocol address
  7561. uint16_t op; // Operation
  7562. uint8_t sha[6]; // Sender hardware address
  7563. uint32_t spa; // Sender protocol address
  7564. uint8_t tha[6]; // Target hardware address
  7565. uint32_t tpa; // Target protocol address
  7566. };
  7567. struct tcp {
  7568. uint16_t sport; // Source port
  7569. uint16_t dport; // Destination port
  7570. uint32_t seq; // Sequence number
  7571. uint32_t ack; // Acknowledgement number
  7572. uint8_t off; // Data offset
  7573. uint8_t flags; // TCP flags
  7574. #define TH_FIN 0x01
  7575. #define TH_SYN 0x02
  7576. #define TH_RST 0x04
  7577. #define TH_PUSH 0x08
  7578. #define TH_ACK 0x10
  7579. #define TH_URG 0x20
  7580. #define TH_STDFLAGS 0x3f
  7581. // #define TH_ECE 0x40 // not part of TCP but RFC-3168 (ECN)
  7582. // #define TH_CWR 0x80
  7583. uint16_t win; // Window
  7584. uint16_t csum; // Checksum
  7585. uint16_t urp; // Urgent pointer
  7586. };
  7587. struct udp {
  7588. uint16_t sport; // Source port
  7589. uint16_t dport; // Destination port
  7590. uint16_t len; // UDP length
  7591. uint16_t csum; // UDP checksum
  7592. };
  7593. struct dhcp {
  7594. uint8_t op, htype, hlen, hops;
  7595. uint32_t xid;
  7596. uint16_t secs, flags;
  7597. uint32_t ciaddr, yiaddr, siaddr, giaddr;
  7598. uint8_t hwaddr[208];
  7599. uint32_t magic;
  7600. uint8_t options[30 + sizeof(((struct mg_tcpip_if *) 0)->dhcp_name)];
  7601. };
  7602. struct dhcp6 {
  7603. union {
  7604. uint8_t type;
  7605. uint32_t xid;
  7606. };
  7607. uint8_t options[30 + sizeof(((struct mg_tcpip_if *) 0)->dhcp_name)];
  7608. };
  7609. struct pseudoip {
  7610. uint32_t src; // Source IP
  7611. uint32_t dst; // Destination IP
  7612. uint8_t zero;
  7613. uint8_t proto; // Upper level protocol
  7614. uint16_t len; // Datagram length
  7615. };
  7616. struct pseudoip6 {
  7617. uint64_t src[2]; // Source IP
  7618. uint64_t dst[2]; // Destination IP
  7619. uint32_t plen; // Payload length
  7620. uint8_t zero[3];
  7621. uint8_t next; // Upper level protocol
  7622. };
  7623. #if defined(__DCC__)
  7624. #pragma pack(0)
  7625. #else
  7626. #pragma pack(pop)
  7627. #endif
  7628. // pkt is 8-bit aligned, pointers to headers hint compilers to generate
  7629. // byte-copy code for micros with alignment constraints
  7630. struct pkt {
  7631. struct mg_str raw; // Raw packet data
  7632. struct mg_str pay; // Payload data
  7633. uint8_t *l2; // Ethernet, PPP [, etc] frame data
  7634. struct arp *arp;
  7635. struct ip *ip;
  7636. struct ip6 *ip6;
  7637. struct icmp *icmp;
  7638. struct icmp6 *icmp6;
  7639. struct tcp *tcp;
  7640. struct udp *udp;
  7641. struct dhcp *dhcp;
  7642. struct dhcp6 *dhcp6;
  7643. };
  7644. // L2 API
  7645. void mg_l2_init(struct mg_tcpip_if *ifp);
  7646. uint8_t *mg_l2_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
  7647. uint8_t *src, uint8_t *dst, uint8_t *frame);
  7648. size_t mg_l2_trailer(struct mg_tcpip_if *ifp, size_t len, uint8_t *cur);
  7649. bool mg_l2_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
  7650. struct mg_str *pay, struct mg_str *raw);
  7651. uint8_t *mg_l2_getaddr(struct mg_tcpip_if *ifp, uint8_t *frame);
  7652. uint8_t *mg_l2_mapip(enum mg_l2type type, enum mg_l2addrtype addrtype,
  7653. struct mg_addr *ip);
  7654. #if MG_ENABLE_IPV6
  7655. bool mg_l2_genip6(enum mg_l2type type, uint64_t *ip6, uint8_t prefix_len,
  7656. uint8_t *addr);
  7657. bool mg_l2_ip6get(enum mg_l2type type, uint8_t *addr, uint8_t *opts,
  7658. uint8_t len);
  7659. uint8_t mg_l2_ip6put(enum mg_l2type type, uint8_t *addr, uint8_t *opts);
  7660. #endif
  7661. bool mg_l2_poll(struct mg_tcpip_if *ifp, bool expired_1000ms);
  7662. static void mg_tcpip_call(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
  7663. #if 0 && MG_ENABLE_PROFILE
  7664. const char *names[] = {"TCPIP_EV_STATE_CHANGE", "TCPIP_EV_DHCP_DNS",
  7665. "TCPIP_EV_DHCP_SNTP", "TCPIP_EV_ARP",
  7666. "TCPIP_EV_TIMER_1S", "TCPIP_EV_WIFI_SCAN_RESULT",
  7667. "TCPIP_EV_WIFI_SCAN_END", "TCPIP_EV_WIFI_CONNECT_ERR",
  7668. "TCPIP_EV_DRIVER", "TCPIP_EV_STATE6_CHANGE",
  7669. "TCPIP_EV_USER"};
  7670. if (ev != MG_TCPIP_EV_TIMER_1S && ev < (int) (sizeof(names) / sizeof(names[0]))) {
  7671. MG_PROF_ADD(ifp, names[ev]); // TODO(): call MG_PROF_DUMP() MG_PROF_FREE()
  7672. }
  7673. #endif
  7674. // Fire protocol handler first, user handler second. See #2559
  7675. if (ifp->pfn != NULL) ifp->pfn(ifp, ev, ev_data);
  7676. if (ifp->fn != NULL) ifp->fn(ifp, ev, ev_data);
  7677. }
  7678. static void send_syn(struct mg_connection *c);
  7679. static void mkpay(struct pkt *pkt, void *p) {
  7680. pkt->pay =
  7681. mg_str_n((char *) p, (size_t) (&pkt->pay.buf[pkt->pay.len] - (char *) p));
  7682. }
  7683. // NOTE(): DOES NOT handle reentries after odd length, use last
  7684. static uint32_t csumup(uint32_t sum, const void *buf, size_t len) {
  7685. size_t i;
  7686. const uint8_t *p = (const uint8_t *) buf;
  7687. for (i = 0; i < len; i++) sum += i & 1 ? p[i] : ((uint32_t) p[i]) << 8;
  7688. return sum;
  7689. }
  7690. static uint16_t csumfin(uint32_t sum) {
  7691. while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
  7692. return mg_htons((uint16_t) ((uint16_t) ~sum & 0xffff));
  7693. }
  7694. static uint16_t ipcsum(const void *buf, size_t len) {
  7695. uint32_t sum = csumup(0, buf, len);
  7696. return csumfin(sum);
  7697. }
  7698. static bool ipcsum_ok(const void *d) {
  7699. struct ip *ip = (struct ip *) d;
  7700. return (ipcsum(d, (ip->ver & 0x0F) * 4) == 0);
  7701. }
  7702. static bool icmpcsum_ok(const void *d, size_t len) {
  7703. return (ipcsum(d, len) == 0);
  7704. }
  7705. static uint16_t pcsum(void *d, void *p, size_t plen) {
  7706. uint32_t sum;
  7707. struct ip *ip = (struct ip *) d;
  7708. #if defined(__DCC__)
  7709. volatile /* Makes PPC & Diab4.3 happy */
  7710. #endif
  7711. struct pseudoip pip;
  7712. pip.src = ip->src;
  7713. pip.dst = ip->dst;
  7714. pip.zero = 0;
  7715. pip.proto = ip->proto;
  7716. pip.len = mg_htons((uint16_t) plen);
  7717. sum = csumup(0, &pip, sizeof(pip)); // even length
  7718. sum = csumup(sum, p, plen); // possibly odd length: last
  7719. return csumfin(sum);
  7720. }
  7721. static bool udpcsum_ok(void *d, void *u) {
  7722. struct udp *udp = (struct udp *) u;
  7723. if (udp->csum == 0) return true;
  7724. if (udp->csum == 0xFFFF) udp->csum = 0;
  7725. return (pcsum(d, u, (size_t) mg_ntohs(udp->len)) == 0);
  7726. }
  7727. static bool tcpcsum_ok(void *d, void *t) {
  7728. struct ip *ip = (struct ip *) d;
  7729. return (pcsum(d, t, (size_t) (mg_ntohs(ip->len) - (ip->ver & 0x0F) * 4)) ==
  7730. 0);
  7731. }
  7732. #if MG_ENABLE_IPV6
  7733. static uint16_t p6csum(void *d, void *p, size_t plen) {
  7734. uint32_t sum;
  7735. struct ip6 *ip6 = (struct ip6 *) d;
  7736. #if defined(__DCC__)
  7737. volatile /* Makes PPC & Diab4.3 happy */
  7738. #endif
  7739. struct pseudoip6 pip6;
  7740. pip6.src[0] = ip6->src[0], pip6.src[1] = ip6->src[1];
  7741. pip6.dst[0] = ip6->dst[0], pip6.dst[1] = ip6->dst[1];
  7742. pip6.zero[0] = 0, pip6.zero[1] = 0, pip6.zero[2] = 0;
  7743. pip6.plen = mg_htonl((uint32_t) plen);
  7744. pip6.next = ip6->next;
  7745. sum = csumup(0, &pip6, sizeof(pip6)); // even length
  7746. sum = csumup(sum, p, plen); // possibly odd length: last
  7747. return csumfin(sum);
  7748. }
  7749. static bool udp6csum_ok(void *d, void *u) {
  7750. struct udp *udp = (struct udp *) u;
  7751. if (udp->csum == 0) return false; // mandatory in IPv6
  7752. if (udp->csum == 0xFFFF) udp->csum = 0;
  7753. return (p6csum(d, u, (size_t) mg_ntohs(udp->len)) == 0);
  7754. }
  7755. static bool tcp6csum_ok(void *d, void *t) {
  7756. struct ip6 *ip6 = (struct ip6 *) d;
  7757. return (p6csum(d, t, (size_t) mg_ntohs(ip6->plen)) == 0);
  7758. }
  7759. static bool icmp6csum_ok(void *d, void *i) {
  7760. struct ip6 *ip6 = (struct ip6 *) d;
  7761. return (p6csum(d, i, (size_t) mg_ntohs(ip6->plen)) == 0);
  7762. }
  7763. static void ip6sn(uint64_t *addr, uint64_t *sn_addr) {
  7764. // Build solicited-node multicast address from a given unicast IP
  7765. // RFC-4291 2.7
  7766. uint8_t *sn = (uint8_t *) sn_addr;
  7767. memset(sn_addr, 0, 16);
  7768. sn[0] = 0xff;
  7769. sn[1] = 0x02;
  7770. sn[11] = 0x01;
  7771. sn[12] = 0xff;
  7772. sn[13] = ((uint8_t *) addr)[13];
  7773. sn[14] = ((uint8_t *) addr)[14];
  7774. sn[15] = ((uint8_t *) addr)[15];
  7775. }
  7776. static const struct mg_addr ip6_allrouters = {
  7777. {{0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}}, 0, 0, true};
  7778. static const struct mg_addr ip6_allnodes = {
  7779. {{0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}}, 0, 0, true};
  7780. #define MG_IP6MATCH(a, b) (a[0] == b[0] && a[1] == b[1])
  7781. #endif
  7782. static void settmout(struct mg_connection *c, uint8_t type) {
  7783. struct mg_tcpip_if *ifp = c->mgr->ifp;
  7784. struct connstate *s = (struct connstate *) (c + 1);
  7785. unsigned n = type == MIP_TTYPE_ACK ? MG_TCPIP_ACK_MS
  7786. : type == MIP_TTYPE_ARP ? MG_TCPIP_ARP_MS
  7787. : type == MIP_TTYPE_SYN ? MG_TCPIP_SYN_MS
  7788. : type == MIP_TTYPE_FIN ? MG_TCPIP_FIN_MS
  7789. : MG_TCPIP_KEEPALIVE_MS;
  7790. if (s->ttype == MIP_TTYPE_FIN) return; // skip if 3-way closing
  7791. s->timer = ifp->now + n;
  7792. s->ttype = type;
  7793. MG_VERBOSE(("%lu %d -> %llx", c->id, type, s->timer));
  7794. }
  7795. static size_t driver_output(struct mg_tcpip_if *ifp, size_t len) {
  7796. size_t n = ifp->driver->tx(ifp->tx.buf, len, ifp);
  7797. if (n == len) ifp->nsent++;
  7798. return n;
  7799. }
  7800. // RFC826, ARP assumes Ethernet MAC addresses
  7801. void mg_tcpip_arp_request(struct mg_tcpip_if *ifp, uint32_t ip, uint8_t *mac) {
  7802. uint8_t *l2p = (uint8_t *) ifp->tx.buf;
  7803. struct arp *arp = (struct arp *) mg_l2_header(
  7804. ifp, MG_TCPIP_L2PROTO_ARP, ifp->mac,
  7805. mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_BCAST, NULL), l2p);
  7806. memset(arp, 0, sizeof(*arp));
  7807. arp->fmt = mg_htons(1), arp->pro = mg_htons(0x800), arp->hlen = 6,
  7808. arp->plen = 4;
  7809. arp->op = mg_htons(1), arp->tpa = ip, arp->spa = ifp->ip;
  7810. memcpy(arp->sha, ifp->mac, sizeof(arp->sha));
  7811. if (mac != NULL) memcpy(arp->tha, mac, sizeof(arp->tha));
  7812. driver_output(ifp, mg_l2_trailer(ifp, sizeof(*arp), (uint8_t *) (arp + 1)));
  7813. }
  7814. static void onstatechange(struct mg_tcpip_if *ifp) {
  7815. if (ifp->state == MG_TCPIP_STATE_IP &&
  7816. (ifp->l2type == MG_TCPIP_L2_PPP || ifp->l2type == MG_TCPIP_L2_PPPoE))
  7817. ifp->state = MG_TCPIP_STATE_READY;
  7818. if (ifp->state == MG_TCPIP_STATE_READY) {
  7819. MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip));
  7820. MG_INFO((" GW: %M", mg_print_ip4, &ifp->gw));
  7821. if (ifp->l2type == MG_TCPIP_L2_ETH ||
  7822. ifp->l2type == MG_TCPIP_L2_PPPoE) // TODO(): print other l2
  7823. MG_INFO((" MAC: %M", mg_print_mac, ifp->mac));
  7824. if (ifp->l2type == MG_TCPIP_L2_ETH)
  7825. mg_tcpip_arp_request(ifp, ifp->ip, ifp->mac); // gratuitous ARP annc
  7826. if (ifp->is_ip_changed) {
  7827. struct mg_connection *c;
  7828. for (c = ifp->mgr->conns; c != NULL; c = c->next) {
  7829. if (!c->is_listening && !c->is_udp) c->is_closing = 1;
  7830. }
  7831. ifp->is_ip_changed = false;
  7832. }
  7833. } else if (ifp->state == MG_TCPIP_STATE_IP) {
  7834. if (ifp->gw != 0 && ifp->l2type == MG_TCPIP_L2_ETH)
  7835. mg_tcpip_arp_request(ifp, ifp->gw, NULL); // unsolicited GW ARP request
  7836. } else if (ifp->state == MG_TCPIP_STATE_UP) {
  7837. srand((unsigned int) mg_millis());
  7838. } else if (ifp->state == MG_TCPIP_STATE_DOWN) {
  7839. MG_ERROR(("Link down"));
  7840. }
  7841. mg_tcpip_call(ifp, MG_TCPIP_EV_STATE_CHANGE, &ifp->state);
  7842. }
  7843. static struct ip *tx_ip(struct mg_tcpip_if *ifp, uint8_t *l2_dst, uint8_t proto,
  7844. uint8_t dscp, uint32_t ip_src, uint32_t ip_dst,
  7845. size_t plen) {
  7846. // ifp->tx.buf is 8-bit aligned, keep other headers as pointers, see pkt
  7847. uint8_t *l2p = (uint8_t *) ifp->tx.buf;
  7848. struct ip *ip = (struct ip *) mg_l2_header(ifp, MG_TCPIP_L2PROTO_IPV4,
  7849. ifp->mac, l2_dst, l2p);
  7850. memset(ip, 0, sizeof(*ip));
  7851. ip->ver = 0x45; // Version 4, header length 5 words
  7852. ip->tos = (uint8_t) (dscp << 2);
  7853. ip->frag = mg_htons(0x4000); // Don't fragment
  7854. ip->len = mg_htons((uint16_t) (sizeof(*ip) + plen));
  7855. ip->ttl = 64;
  7856. ip->proto = proto;
  7857. ip->src = ip_src;
  7858. ip->dst = ip_dst;
  7859. ip->csum = ipcsum(ip, sizeof(*ip));
  7860. return ip;
  7861. }
  7862. #if MG_ENABLE_IPV6
  7863. static struct ip6 *tx_ip6(struct mg_tcpip_if *ifp, uint8_t *l2_dst,
  7864. uint8_t next, uint8_t dscp, uint64_t *ip_src,
  7865. uint64_t *ip_dst, size_t plen);
  7866. #endif
  7867. static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *l2_dst,
  7868. struct mg_addr *ip_src, struct mg_addr *ip_dst, uint8_t dscp,
  7869. const void *buf, size_t len) {
  7870. uint8_t *l3p;
  7871. size_t l2_len;
  7872. struct ip *ip = NULL;
  7873. struct udp *udp;
  7874. #if MG_ENABLE_IPV6
  7875. struct ip6 *ip6 = NULL;
  7876. if (ip_dst->is_ip6) {
  7877. ip6 = tx_ip6(ifp, l2_dst, 17, dscp, ip_src->addr.ip6, ip_dst->addr.ip6,
  7878. len + sizeof(struct udp));
  7879. udp = (struct udp *) (ip6 + 1);
  7880. l2_len = sizeof(*ip6) + sizeof(*udp) + len;
  7881. l3p = (uint8_t *) ip6;
  7882. } else
  7883. #endif
  7884. {
  7885. ip = tx_ip(ifp, l2_dst, 17, dscp, ip_src->addr.ip4, ip_dst->addr.ip4,
  7886. len + sizeof(struct udp));
  7887. udp = (struct udp *) (ip + 1);
  7888. l2_len = sizeof(*ip) + sizeof(*udp) + len;
  7889. l3p = (uint8_t *) ip;
  7890. }
  7891. udp->sport = ip_src->port;
  7892. udp->dport = ip_dst->port;
  7893. udp->len = mg_htons((uint16_t) (sizeof(*udp) + len));
  7894. udp->csum = 0;
  7895. memmove(udp + 1, buf, len);
  7896. #if MG_ENABLE_IPV6
  7897. if (ip_dst->is_ip6) {
  7898. udp->csum = p6csum(ip6, udp, sizeof(*udp) + len);
  7899. } else
  7900. #endif
  7901. {
  7902. udp->csum = pcsum(ip, udp, sizeof(*udp) + len);
  7903. }
  7904. l2_len = mg_l2_trailer(ifp, l2_len, l3p + l2_len);
  7905. return (driver_output(ifp, l2_len) == l2_len);
  7906. }
  7907. static bool tx_udp4(struct mg_tcpip_if *ifp, uint8_t *l2_dst, uint32_t ip_src,
  7908. uint16_t sport, uint32_t ip_dst, uint16_t dport,
  7909. const void *buf, size_t len) {
  7910. struct mg_addr ips, ipd;
  7911. memset(&ips, 0, sizeof(ips));
  7912. ips.addr.ip4 = ip_src;
  7913. ips.port = sport;
  7914. memset(&ipd, 0, sizeof(ipd));
  7915. ipd.addr.ip4 = ip_dst;
  7916. ipd.port = dport;
  7917. return tx_udp(ifp, l2_dst, &ips, &ipd, 0, buf, len);
  7918. }
  7919. static void tx_dhcp(struct mg_tcpip_if *ifp, uint8_t *l2_dst, uint32_t ip_src,
  7920. uint32_t ip_dst, uint8_t *opts, size_t optslen,
  7921. bool ciaddr) {
  7922. // https://datatracker.ietf.org/doc/html/rfc2132#section-9.6
  7923. // NOTE(): assumes Ethernet: htype=1 hlen=6, copy 6 bytes
  7924. struct dhcp dhcp = {1, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
  7925. dhcp.magic = mg_htonl(0x63825363);
  7926. memcpy(&dhcp.hwaddr, ifp->mac, 6);
  7927. memcpy(&dhcp.xid, ifp->mac + 2, sizeof(dhcp.xid));
  7928. memcpy(&dhcp.options, opts, optslen);
  7929. if (ciaddr) dhcp.ciaddr = ip_src;
  7930. tx_udp4(ifp, l2_dst, ip_src, mg_htons(68), ip_dst, mg_htons(67), &dhcp,
  7931. sizeof(dhcp));
  7932. }
  7933. // RFC-2131 #4.3.6, #4.4.1; RFC-2132 #9.8
  7934. static void tx_dhcp_request_sel(struct mg_tcpip_if *ifp, uint32_t ip_req,
  7935. uint32_t ip_srv) {
  7936. uint8_t extra = (uint8_t) ((ifp->enable_req_dns ? 1 : 0) +
  7937. (ifp->enable_req_sntp ? 1 : 0));
  7938. size_t len = strlen(ifp->dhcp_name);
  7939. size_t olen = 21 + len + extra + 2 + 1; // Total length of options
  7940. #define OPTS_MAXLEN (21 + sizeof(ifp->dhcp_name) + 2 + 2 + 1)
  7941. uint8_t opts[OPTS_MAXLEN]; // Allocate options (max size possible)
  7942. uint8_t *p = opts;
  7943. assert(olen <= sizeof(opts));
  7944. memset(opts, 0, sizeof(opts));
  7945. *p++ = 53, *p++ = 1, *p++ = 3; // Type: DHCP request
  7946. *p++ = 54, *p++ = 4, memcpy(p, &ip_srv, 4), p += 4; // DHCP server ID
  7947. *p++ = 50, *p++ = 4, memcpy(p, &ip_req, 4), p += 4; // Requested IP
  7948. *p++ = 12, *p++ = (uint8_t) (len & 255); // DHCP host
  7949. memcpy(p, ifp->dhcp_name, len), p += len; // name
  7950. *p++ = 55, *p++ = 2 + extra, *p++ = 1, *p++ = 3; // GW, MASK
  7951. if (ifp->enable_req_dns) *p++ = 6; // DNS
  7952. if (ifp->enable_req_sntp) *p++ = 42; // SNTP
  7953. *p++ = 255; // End of options
  7954. // assert((size_t) (p - opts) < olen);
  7955. tx_dhcp(ifp, mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_BCAST, NULL), 0,
  7956. 0xffffffff, opts, olen, 0);
  7957. MG_DEBUG(("DHCP req sent"));
  7958. }
  7959. // RFC-2131 #4.3.6, #4.4.5 (renewing: unicast, rebinding: bcast)
  7960. static void tx_dhcp_request_re(struct mg_tcpip_if *ifp, uint8_t *l2_dst,
  7961. uint32_t ip_src, uint32_t ip_dst) {
  7962. uint8_t opts[] = {
  7963. 53, 1, 3, // Type: DHCP request
  7964. 255 // End of options
  7965. };
  7966. tx_dhcp(ifp, l2_dst, ip_src, ip_dst, opts, sizeof(opts), true);
  7967. MG_DEBUG(("DHCP req sent"));
  7968. }
  7969. static void tx_dhcp_discover(struct mg_tcpip_if *ifp) {
  7970. uint8_t opts[] = {
  7971. 53, 1, 1, // Type: DHCP discover
  7972. 55, 2, 1, 3, // Parameters: ip, mask
  7973. 255 // End of options
  7974. };
  7975. tx_dhcp(ifp, mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_BCAST, NULL), 0,
  7976. 0xffffffff, opts, sizeof(opts), false);
  7977. MG_DEBUG(("DHCP discover sent. Our MAC: %M", mg_print_mac, ifp->mac));
  7978. }
  7979. static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
  7980. bool lsn) {
  7981. struct mg_connection *c = NULL;
  7982. for (c = mgr->conns; c != NULL; c = c->next) {
  7983. if (c->is_arplooking && pkt->arp && pkt->arp->spa == c->rem.addr.ip4) break;
  7984. #if MG_ENABLE_IPV6
  7985. if (c->is_arplooking && pkt->icmp6 && pkt->icmp6->type == 136) {
  7986. struct ndp_na *na = (struct ndp_na *) (pkt->icmp6 + 1);
  7987. if (MG_IP6MATCH(na->addr, c->rem.addr.ip6)) break;
  7988. }
  7989. #endif
  7990. if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport &&
  7991. !(c->loc.is_ip6 ^ (pkt->ip6 != NULL))) // IP or IPv6 to same dest
  7992. break;
  7993. if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport &&
  7994. ((lsn && c->is_listening && !(c->loc.is_ip6 ^ (pkt->ip6 != NULL))) ||
  7995. (!lsn && !c->is_listening && c->rem.port == pkt->tcp->sport &&
  7996. ((!c->loc.is_ip6 && c->rem.addr.ip4 == pkt->ip->src)
  7997. #if MG_ENABLE_IPV6
  7998. || (c->loc.is_ip6 && MG_IP6MATCH(c->rem.addr.ip6, pkt->ip6->src))
  7999. #endif
  8000. )))) // validate addr for established (not listening) conns
  8001. break;
  8002. }
  8003. return c;
  8004. }
  8005. static void l2addr_resolved(struct mg_connection *c);
  8006. static uint8_t *get_return_l2addr(struct mg_tcpip_if *ifp, struct mg_addr *rem,
  8007. bool is_udp, struct pkt *pkt);
  8008. // RFC826, ARP assumes Ethernet MAC addresses
  8009. static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  8010. if (pkt->arp->op == mg_htons(1) && pkt->arp->tpa == ifp->ip) {
  8011. // ARP request. Make a response, then send
  8012. // MG_VERBOSE(("ARP req from %M", mg_print_ip4, &pkt->arp->spa));
  8013. uint8_t *l2p = (uint8_t *) ifp->tx.buf;
  8014. struct arp *arp = (struct arp *) mg_l2_header(
  8015. ifp, MG_TCPIP_L2PROTO_ARP, ifp->mac, mg_l2_getaddr(ifp, pkt->l2), l2p);
  8016. *arp = *pkt->arp;
  8017. arp->op = mg_htons(2);
  8018. memcpy(arp->tha, pkt->arp->sha, sizeof(pkt->arp->tha));
  8019. memcpy(arp->sha, ifp->mac, sizeof(pkt->arp->sha));
  8020. arp->tpa = pkt->arp->spa;
  8021. arp->spa = ifp->ip;
  8022. MG_DEBUG(("ARP: tell %M we're %M", mg_print_ip4, &arp->tpa, mg_print_mac,
  8023. ifp->mac));
  8024. driver_output(ifp, mg_l2_trailer(ifp, sizeof(*arp), (uint8_t *) (arp + 1)));
  8025. } else if (pkt->arp->op == mg_htons(2)) {
  8026. if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) return;
  8027. // MG_VERBOSE(("ARP resp from %M", mg_print_ip4, &pkt->arp->spa));
  8028. if (pkt->arp->spa == ifp->gw) {
  8029. // Got response for the GW ARP request. Set ifp->gwmac and IP -> READY
  8030. memcpy(ifp->gwmac, pkt->arp->sha, sizeof(ifp->gwmac));
  8031. ifp->gw_ready = true;
  8032. if (ifp->state == MG_TCPIP_STATE_IP) {
  8033. ifp->state = MG_TCPIP_STATE_READY;
  8034. onstatechange(ifp);
  8035. }
  8036. } else {
  8037. struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
  8038. if (c != NULL && c->is_arplooking) {
  8039. struct connstate *s = (struct connstate *) (c + 1);
  8040. memcpy(s->mac, pkt->arp->sha, sizeof(s->mac));
  8041. MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4,
  8042. &c->rem.addr.ip4, mg_print_mac, s->mac));
  8043. c->is_arplooking = 0;
  8044. l2addr_resolved(c);
  8045. }
  8046. }
  8047. }
  8048. }
  8049. static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  8050. size_t plen = pkt->pay.len;
  8051. if (!icmpcsum_ok(pkt->icmp, sizeof(struct icmp) + plen)) return;
  8052. if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) {
  8053. size_t l2_max_overhead = ifp->framesize - ifp->l2mtu;
  8054. size_t hlen = sizeof(struct ip) + sizeof(struct icmp);
  8055. size_t room = ifp->tx.len - hlen - l2_max_overhead;
  8056. uint8_t *l2addr;
  8057. struct ip *ip;
  8058. struct icmp *icmp;
  8059. struct mg_addr ips;
  8060. ips.addr.ip4 = pkt->ip->src;
  8061. ips.is_ip6 = false;
  8062. if ((l2addr = get_return_l2addr(ifp, &ips, false, pkt)) == NULL)
  8063. return; // safety net for lousy networks
  8064. if (plen > room) plen = room;
  8065. ip = tx_ip(ifp, l2addr, 1, 0, ifp->ip, pkt->ip->src, sizeof(*icmp) + plen);
  8066. icmp = (struct icmp *) (ip + 1);
  8067. memset(icmp, 0, sizeof(*icmp)); // Set csum, type, code to 0
  8068. memcpy(icmp + 1, pkt->pay.buf, plen); // Copy RX payload to TX
  8069. icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen);
  8070. driver_output(
  8071. ifp, mg_l2_trailer(ifp, hlen + plen, (uint8_t *) ip + hlen + plen));
  8072. }
  8073. }
  8074. static void setdns4(struct mg_tcpip_if *ifp, uint32_t *ip);
  8075. static bool dhcp_opt_len_ok(uint8_t len, uint8_t *p, uint8_t *end) {
  8076. return (len >= 4 && (len & 3) == 0 && p + 6 < end);
  8077. }
  8078. static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  8079. uint32_t ip = 0, gw = 0, mask = 0, lease = 0, dns = 0, sntp = 0, owner = 0;
  8080. uint8_t msgtype = 0, state = ifp->state;
  8081. // perform size check first, then access fields
  8082. uint8_t *p = (uint8_t *) pkt->pay.buf,
  8083. *end = (uint8_t *) &pkt->pay.buf[pkt->pay.len];
  8084. // min header length checked at payload calculation, options are optional
  8085. if (memcmp(&pkt->dhcp->xid, ifp->mac + 2, sizeof(pkt->dhcp->xid))) return;
  8086. while (p < end && p[0] != 255) { // RFC-2132 9
  8087. if (p[0] == 0) { p++; continue; } // Pad
  8088. if ((size_t) (end - p) < 2 || (size_t) (end - p) < 2U + p[1]) break;
  8089. if (p[0] == 1) { // Mask, 3.3
  8090. if (p[1] != 4) break;
  8091. memcpy(&mask, p + 2, sizeof(mask));
  8092. } else if (p[0] == 3) { // GW, 3.5
  8093. if (!dhcp_opt_len_ok(p[1], p, end)) break;
  8094. memcpy(&gw, p + 2, sizeof(gw));
  8095. ip = pkt->dhcp->yiaddr;
  8096. } else if (ifp->enable_req_dns && p[0] == 6) { // DNS, 3.8
  8097. if (!dhcp_opt_len_ok(p[1], p, end)) break;
  8098. memcpy(&dns, p + 2, sizeof(dns));
  8099. } else if (ifp->enable_req_sntp && p[0] == 42) { // SNTP, 8.3
  8100. if (!dhcp_opt_len_ok(p[1], p, end)) break;
  8101. memcpy(&sntp, p + 2, sizeof(sntp));
  8102. } else if (p[0] == 51) { // Lease
  8103. if (p[1] != 4) break;
  8104. memcpy(&lease, p + 2, sizeof(lease));
  8105. lease = mg_ntohl(lease);
  8106. } else if (p[0] == 53) { // Msg Type
  8107. if (p[1] != 1) break;
  8108. msgtype = p[2];
  8109. } else if (p[0] == 54) { // Server id 9.7
  8110. if (p[1] != 4) break;
  8111. memcpy(&owner, p + 2, sizeof(sntp)); // This is the lease owner
  8112. }
  8113. p += p[1] + 2;
  8114. }
  8115. // Process message type, RFC-1533 (9.4); RFC-2131 (3.1, 4)
  8116. if (msgtype == 6 && ifp->ip == ip) { // DHCPNACK, release IP
  8117. ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0;
  8118. } else if (msgtype == 2 && ifp->state == MG_TCPIP_STATE_UP && ip && gw &&
  8119. lease) { // DHCPOFFER
  8120. // select a server (2131 4.4.1, 2132 9.7): lease owner takes precedence,
  8121. // otherwise use siaddr (fallback to IP source addr on foul play).
  8122. // This is broadcast, otherwise siaddr would be the destination.
  8123. tx_dhcp_request_sel(ifp, ip,
  8124. owner ? owner
  8125. : pkt->dhcp->siaddr ? pkt->dhcp->siaddr
  8126. : pkt->ip->src);
  8127. ifp->state = MG_TCPIP_STATE_REQ; // REQUESTING state
  8128. } else if (msgtype == 5) { // DHCPACK
  8129. if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) { // got an IP
  8130. uint64_t rand;
  8131. ifp->lease_expire = ifp->now + (uint64_t) lease * 1000;
  8132. MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000));
  8133. // assume DHCP server = router until ARP resolves
  8134. memcpy(ifp->gwmac, mg_l2_getaddr(ifp, pkt->l2), sizeof(ifp->gwmac));
  8135. ifp->gw_ready = true; // NOTE(): actual gw ARP won't retry now
  8136. if (ifp->ip != ip) ifp->is_ip_changed = true;
  8137. ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
  8138. ifp->state = MG_TCPIP_STATE_IP; // BOUND state
  8139. mg_random(&rand, sizeof(rand));
  8140. srand((unsigned int) (rand + mg_millis()));
  8141. if (ifp->enable_req_dns && dns != 0) {
  8142. setdns4(ifp, &dns);
  8143. mg_tcpip_call(ifp, MG_TCPIP_EV_DHCP_DNS, &dns);
  8144. }
  8145. if (ifp->enable_req_sntp && sntp != 0)
  8146. mg_tcpip_call(ifp, MG_TCPIP_EV_DHCP_SNTP, &sntp);
  8147. } else if (ifp->state == MG_TCPIP_STATE_READY && ifp->ip == ip) { // renew
  8148. ifp->lease_expire = ifp->now + (uint64_t) lease * 1000;
  8149. MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000));
  8150. } // TODO(): accept provided T1/T2 and store server IP for renewal (4.4)
  8151. }
  8152. if (ifp->state != state) onstatechange(ifp);
  8153. }
  8154. // Simple DHCP server that assigns a next IP address: ifp->ip + 1
  8155. static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  8156. uint8_t *mac;
  8157. uint8_t op = 0, *p = (uint8_t *) pkt->pay.buf,
  8158. *end = (uint8_t *) &pkt->pay.buf[pkt->pay.len];
  8159. // NOTE(): assumes Ethernet: htype=1 hlen=6, copy 6 bytes
  8160. struct dhcp res = {2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
  8161. // min header length checked at payload calculation, options are optional
  8162. res.yiaddr = ifp->ip;
  8163. ((uint8_t *) (&res.yiaddr))[3]++; // Offer our IP + 1
  8164. while (p < end && p[0] != 255) { // Parse options
  8165. if (p[0] == 0) { p++; continue; } // Pad
  8166. if ((size_t) (end - p) < 2 || (size_t) (end - p) < 2U + p[1]) break;
  8167. if (p[0] == 53) { // Message type
  8168. if (p[1] != 1) break;
  8169. op = p[2];
  8170. }
  8171. p += p[1] + 2;
  8172. }
  8173. if (op == 1 || op == 3) { // DHCP Discover or DHCP Request
  8174. uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK
  8175. uint8_t opts[] = {
  8176. 53, 1, 0, // Message type
  8177. 1, 4, 0, 0, 0, 0, // Subnet mask
  8178. 54, 4, 0, 0, 0, 0, // Server ID
  8179. 12, 3, 'm', 'i', 'p', // Host name: "mip"
  8180. 51, 4, 255, 255, 255, 255, // Lease time
  8181. 255 // End of options
  8182. };
  8183. opts[2] = msg;
  8184. memcpy(&res.hwaddr, pkt->dhcp->hwaddr, 6);
  8185. memcpy(opts + 5, &ifp->mask, sizeof(ifp->mask));
  8186. memcpy(opts + 11, &ifp->ip, sizeof(ifp->ip));
  8187. memcpy(&res.options, opts, sizeof(opts));
  8188. res.magic = pkt->dhcp->magic;
  8189. res.xid = pkt->dhcp->xid;
  8190. mac = mg_l2_getaddr(ifp, pkt->l2);
  8191. if (ifp->enable_get_gateway) {
  8192. ifp->gw = res.yiaddr; // set gw IP, best-effort gwmac as DHCP server's
  8193. memcpy(ifp->gwmac, mac, sizeof(ifp->gwmac));
  8194. }
  8195. tx_udp4(ifp, mac, ifp->ip, mg_htons(67), op == 1 ? ~0U : res.yiaddr,
  8196. mg_htons(68), &res, sizeof(res));
  8197. }
  8198. }
  8199. #if MG_ENABLE_IPV6
  8200. static struct ip6 *tx_ip6(struct mg_tcpip_if *ifp, uint8_t *l2_dst,
  8201. uint8_t next, uint8_t dscp, uint64_t *ip_src,
  8202. uint64_t *ip_dst, size_t plen) {
  8203. // ifp->tx.buf is 8-bit aligned, keep other headers as pointers, see pkt
  8204. uint8_t *l2p = (uint8_t *) ifp->tx.buf;
  8205. struct ip6 *ip6 = (struct ip6 *) mg_l2_header(ifp, MG_TCPIP_L2PROTO_IPV6,
  8206. ifp->mac, l2_dst, l2p);
  8207. memset(ip6, 0, sizeof(*ip6));
  8208. ip6->ver = (uint8_t) (0x60 | (dscp >> 2)); // Version 6, traffic class
  8209. ip6->label[0] = (uint8_t) (dscp << 6);
  8210. ip6->plen = mg_htons((uint16_t) plen);
  8211. ip6->next = next;
  8212. ip6->hops = 255; // NDP requires max
  8213. ip6->src[0] = *ip_src++;
  8214. ip6->src[1] = *ip_src;
  8215. ip6->dst[0] = *ip_dst++;
  8216. ip6->dst[1] = *ip_dst;
  8217. return ip6;
  8218. }
  8219. static void tx_icmp6(struct mg_tcpip_if *ifp, uint8_t *l2_dst, uint64_t *ip_src,
  8220. uint64_t *ip_dst, uint8_t type, uint8_t code,
  8221. const void *buf, size_t len) {
  8222. struct ip6 *ip6;
  8223. struct icmp6 *icmp6;
  8224. ip6 = tx_ip6(ifp, l2_dst, 58, 0, ip_src, ip_dst, sizeof(*icmp6) + len);
  8225. icmp6 = (struct icmp6 *) (ip6 + 1);
  8226. memset(icmp6, 0, sizeof(*icmp6)); // Set csum to 0
  8227. icmp6->type = type;
  8228. icmp6->code = code;
  8229. memcpy(icmp6 + 1, buf, len); // Copy payload
  8230. icmp6->csum = 0; // RFC-4443 2.3, RFC-8200 8.1
  8231. icmp6->csum = p6csum(ip6, icmp6, sizeof(*icmp6) + len);
  8232. driver_output(ifp,
  8233. mg_l2_trailer(ifp, sizeof(*ip6) + sizeof(*icmp6) + len,
  8234. (uint8_t *) (ip6 + 1) + sizeof(*icmp6) + len));
  8235. }
  8236. // Neighbor Discovery Protocol, RFC-4861
  8237. // Neighbor Advertisement, 4.4
  8238. static void tx_ndp_na(struct mg_tcpip_if *ifp, uint8_t *l2_dst,
  8239. uint64_t *ip_src, uint64_t *ip_dst, bool solicited,
  8240. uint8_t *l2) {
  8241. uint8_t data[20 + 16]; // NOTE(): optional len upto 2 hw addr
  8242. memset(data, 0, sizeof(data));
  8243. data[0] = solicited ? 0x60 : 0x20; // O + S
  8244. memcpy(data + 4, ip_src, 16); // Target address
  8245. data[20] = 2; // 4.6.1, target hwaddr
  8246. data[21] = mg_l2_ip6put(ifp->l2type, l2, data + 22); // option length / 8
  8247. tx_icmp6(ifp, l2_dst, ip_src, ip_dst, 136, 0, data,
  8248. 20 + (size_t) (8 * data[21]));
  8249. }
  8250. static void onstate6change(struct mg_tcpip_if *ifp);
  8251. static void rx_ndp_na(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  8252. struct ndp_na *na = (struct ndp_na *) pkt->pay.buf;
  8253. uint8_t *opts = (uint8_t *) (na + 1),
  8254. *endp = opts + pkt->pay.len - sizeof(*na);
  8255. if (pkt->pay.len < (sizeof(*na) + 2)) return; // first 2 bytes in opts
  8256. if ((na->res[0] & 0x40) == 0) return; // not "solicited"
  8257. if (*opts++ != 2) return; // no target hwaddr, must have
  8258. MG_VERBOSE(("NDP NA resp from %M", mg_print_ip6, (char *) &na->addr));
  8259. if (MG_IP6MATCH(na->addr, ifp->gw6)) {
  8260. // Got response for the GW NS request. Set ifp->gw6mac and IP6 -> READY
  8261. uint8_t len = *opts++; // check valid hwaddr and get it
  8262. if ((opts + 8 * len - 2) > endp) return; // truncated
  8263. if (!mg_l2_ip6get(ifp->l2type, ifp->gw6mac, opts, len)) return;
  8264. ifp->gw6_ready = true;
  8265. if (ifp->state6 == MG_TCPIP_STATE_IP) {
  8266. ifp->state6 = MG_TCPIP_STATE_READY;
  8267. onstate6change(ifp);
  8268. }
  8269. } else {
  8270. struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
  8271. if (c != NULL && c->is_arplooking) {
  8272. struct connstate *s = (struct connstate *) (c + 1);
  8273. uint8_t len = *opts++; // check valid hwaddr and get it
  8274. if ((opts + 8 * len - 2) > endp) return; // truncated
  8275. if (!mg_l2_ip6get(ifp->l2type, s->mac, opts, len)) return;
  8276. MG_DEBUG(("%lu NDP resolved %M -> %M", c->id, mg_print_ip6,
  8277. &c->rem.addr.ip6, mg_print_l2addr, ifp->l2type, s->mac));
  8278. c->is_arplooking = 0;
  8279. l2addr_resolved(c);
  8280. }
  8281. }
  8282. }
  8283. // Neighbor Solicitation, 4.3
  8284. static void rx_ndp_ns(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  8285. struct ndp_na *ns = (struct ndp_na *) pkt->pay.buf; // struct ndp_ns = ndp_na
  8286. uint64_t target[2];
  8287. if (pkt->pay.len < (sizeof(*ns) + 2)) return; // first 2 bytes in opts
  8288. memcpy(target, ns->addr, sizeof(target));
  8289. if (MG_IP6MATCH(target, ifp->ip6ll) || MG_IP6MATCH(target, ifp->ip6)) {
  8290. uint64_t req[2]; // requester address
  8291. uint8_t l2[sizeof(struct mg_l2addr)];
  8292. uint8_t len, *opts = (uint8_t *) (ns + 1),
  8293. *endp = opts + pkt->pay.len - sizeof(*ns);
  8294. if (*opts++ != 1) return; // no requester hwaddr (source)
  8295. len = *opts++; // check valid hwaddr and get it
  8296. if ((opts + 8 * len - 2) > endp) return; // truncated
  8297. if (!mg_l2_ip6get(ifp->l2type, l2, opts, len)) return;
  8298. req[0] = pkt->ip6->src[0], req[1] = pkt->ip6->src[1]; // align to 64-bit
  8299. tx_ndp_na(ifp, l2, target, req, true, ifp->mac);
  8300. }
  8301. }
  8302. // - use solicited node multicast to resolve a l2 address (l2_addr = NULL)
  8303. // - use unicast to verify presence (l2_addr = neighbor l2 address)
  8304. static void tx_ndp_ns(struct mg_tcpip_if *ifp, uint64_t *ip_dst,
  8305. uint8_t *l2_addr) {
  8306. uint8_t payload[4 + 16 + 16]; // NOTE(): 16 --> optional len upto 2 hw addr
  8307. uint64_t ip_unspec[2] = {0, 0};
  8308. size_t payload_len = 20;
  8309. bool mcast = (l2_addr == NULL);
  8310. uint64_t ip_mcast[2] = {0, 0};
  8311. uint8_t *l2 = l2_addr;
  8312. if (ifp->l2type == MG_TCPIP_L2_PPP || ifp->l2type == MG_TCPIP_L2_PPPoE) {
  8313. MG_DEBUG(("SKIP NS for %M", mg_print_ip6, ip_dst));
  8314. return;
  8315. }
  8316. memset(payload, 0, sizeof(payload));
  8317. memcpy(payload + 4, ip_dst, 16);
  8318. if (mcast) {
  8319. struct mg_addr ipd;
  8320. ip6sn(ip_dst, ip_mcast);
  8321. ipd.addr.ip6[0] = ip_mcast[0], ipd.addr.ip6[1] = ip_mcast[1],
  8322. ipd.is_ip6 = true;
  8323. l2 = mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_MCAST6, &ipd);
  8324. }
  8325. payload_len = 20;
  8326. // TODO(robertc2000): using only link-local IP addr for now
  8327. // We might consider to add an option to use either link-local or global IP
  8328. if (!MG_IP6MATCH(ifp->ip6ll, ip_unspec)) {
  8329. payload[20] = 1; // 4.6.1, source hwaddr; option length in 8-byte units
  8330. payload[21] = mg_l2_ip6put(ifp->l2type, ifp->mac, payload + 22);
  8331. payload_len += 8 * payload[21];
  8332. }
  8333. tx_icmp6(ifp, l2, ifp->ip6ll, mcast ? ip_mcast : ip_dst, 135, 0, payload,
  8334. payload_len);
  8335. }
  8336. // Router Solicitation, 4.1
  8337. static void tx_ndp_rs(struct mg_tcpip_if *ifp) {
  8338. uint8_t payload[4 + 16]; // reserved + optional len upto 2 hw addr NOTE()
  8339. size_t payload_len = 4;
  8340. uint64_t ip_unspec[2] = {0, 0};
  8341. memset(payload, 0, sizeof(payload));
  8342. if (!MG_IP6MATCH(ifp->ip6ll, ip_unspec)) {
  8343. payload[4] = 1; // 4.6.1, source hwaddr; option length in 8-byte units
  8344. payload[5] = mg_l2_ip6put(ifp->l2type, ifp->mac, payload + 6);
  8345. payload_len += 8 * payload[5];
  8346. }
  8347. tx_icmp6(ifp,
  8348. mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_MCAST6,
  8349. (struct mg_addr *) &ip6_allrouters),
  8350. ifp->ip6ll, (uint64_t *) ip6_allrouters.addr.ip6, 133, 0, payload,
  8351. payload_len);
  8352. MG_DEBUG(("NDP Router Solicitation sent"));
  8353. }
  8354. static void fill_prefix(uint8_t *dst, uint8_t *src, uint8_t len) {
  8355. uint8_t full = len / 8;
  8356. uint8_t rem = len % 8;
  8357. if (full > 0) memcpy(dst, src, full);
  8358. if (rem > 0) {
  8359. uint8_t mask = (uint8_t) (0xFF << (8 - rem));
  8360. dst[full] |= src[full] & mask; // mg_l2_genip6() zeroes dst
  8361. }
  8362. }
  8363. static bool match_prefix(uint8_t *newp, uint8_t *curp, uint8_t len) {
  8364. uint8_t full = len / 8;
  8365. uint8_t rem = len % 8;
  8366. if (full > 0 && memcmp(curp, newp, full) != 0) return false;
  8367. if (rem > 0) {
  8368. uint8_t mask = (uint8_t) (0xFF << (8 - rem));
  8369. if (curp[full] != (newp[full] & mask)) return false;
  8370. }
  8371. return true;
  8372. }
  8373. static bool fill_global(struct mg_tcpip_if *ifp, uint8_t *prefix,
  8374. uint8_t prefix_len) {
  8375. if (!mg_l2_genip6(ifp->l2type, ifp->ip6, prefix_len, ifp->mac)) return false;
  8376. fill_prefix((uint8_t *) ifp->ip6, prefix, prefix_len);
  8377. fill_prefix(ifp->prefix, prefix, prefix_len);
  8378. ifp->prefix_len = prefix_len;
  8379. return true;
  8380. }
  8381. // Router Advertisement, 4.2
  8382. static void rx_ndp_ra(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  8383. struct ndp_ra *ra = (struct ndp_ra *) pkt->pay.buf;
  8384. uint8_t *opts = (uint8_t *) (ra + 1);
  8385. size_t opt_left = pkt->pay.len - sizeof(*ra);
  8386. bool gotl2addr = false, gotprefix = false, changed = false;
  8387. uint8_t l2[sizeof(struct mg_l2addr)];
  8388. uint32_t mtu = 0;
  8389. uint8_t *prefix = NULL, prefix_len = 0;
  8390. if (pkt->pay.len < sizeof(*ra)) return;
  8391. if (ifp->state6 == MG_TCPIP_STATE_UP) {
  8392. MG_DEBUG(("Received NDP RA")); // fill gw6 address
  8393. // parse options
  8394. while (opt_left >= 2) {
  8395. uint8_t type = opts[0], len = opts[1];
  8396. size_t length = (size_t) len * 8;
  8397. if (length == 0 || length > opt_left) break; // malformed
  8398. if (type == 1 && length >= 8) {
  8399. // Received router's L2 address
  8400. if (!mg_l2_ip6get(ifp->l2type, l2, opts + 2, len)) break;
  8401. gotl2addr = true;
  8402. } else if (type == 5 && length >= 8) {
  8403. // process MTU if available, ignore if it smells
  8404. mtu = MG_LOAD_BE32(opts + 4);
  8405. if (mtu < 1280 || mtu > ifp->l2mtu) mtu = 0; // RFC-8200, minimum MTU
  8406. } else if (type == 3 && length >= 32) {
  8407. // process prefix, 4.6.2, ignore if it smells
  8408. uint8_t pfx_flags = opts[3]; // L=0x80, A=0x40
  8409. uint32_t valid = MG_LOAD_BE32(opts + 4);
  8410. uint32_t pref_lifetime = MG_LOAD_BE32(opts + 8);
  8411. prefix_len = opts[2];
  8412. if (prefix_len >= 128) break;
  8413. prefix = opts + 16;
  8414. // TODO (robertc2000): handle prefix options if necessary
  8415. (void) pfx_flags;
  8416. (void) valid;
  8417. (void) pref_lifetime;
  8418. gotprefix = true;
  8419. if (prefix_len != ifp->prefix_len ||
  8420. !match_prefix(prefix, ifp->prefix, ifp->prefix_len))
  8421. changed = true;
  8422. }
  8423. opts += length;
  8424. opt_left -= length;
  8425. }
  8426. // fill prefix and global
  8427. if (gotprefix && !fill_global(ifp, prefix, prefix_len)) return;
  8428. if (changed) ifp->is_ip6_changed = true;
  8429. ifp->gw6[0] = pkt->ip6->src[0], ifp->gw6[1] = pkt->ip6->src[1];
  8430. if (gotl2addr) memcpy(ifp->gw6mac, l2, sizeof(ifp->gw6mac));
  8431. if (gotl2addr || ifp->l2type == MG_TCPIP_L2_PPP ||
  8432. ifp->l2type == MG_TCPIP_L2_PPPoE) {
  8433. ifp->state6 = MG_TCPIP_STATE_READY;
  8434. ifp->gw6_ready = true;
  8435. }
  8436. if (mtu != 0 && ifp->mtu != mtu) {
  8437. MG_ERROR(
  8438. ("got an MTU: %u, that differs from the configured one. "
  8439. "All devices in an IPv6 network should have the same MTU, "
  8440. "using the router's instead...",
  8441. mtu));
  8442. ifp->mtu = (uint16_t) mtu;
  8443. }
  8444. if (ifp->state6 != MG_TCPIP_STATE_READY) {
  8445. tx_ndp_ns(ifp, ifp->gw6, NULL); // unsolicited GW hwaddr resolution
  8446. ifp->state6 = MG_TCPIP_STATE_IP;
  8447. }
  8448. onstate6change(ifp);
  8449. }
  8450. }
  8451. static void rx_icmp6(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  8452. if (!icmp6csum_ok(pkt->ip6, pkt->icmp6)) return;
  8453. switch (pkt->icmp6->type) {
  8454. case 128: { // Echo Request, RFC-4443 4.1
  8455. uint64_t target[2];
  8456. target[0] = pkt->ip6->dst[0], target[1] = pkt->ip6->dst[1];
  8457. if (MG_IP6MATCH(target, ifp->ip6ll) || MG_IP6MATCH(target, ifp->ip6)) {
  8458. size_t l2_max_overhead = ifp->framesize - ifp->l2mtu;
  8459. size_t hlen = sizeof(struct ip6) + sizeof(struct icmp6);
  8460. size_t room = ifp->tx.len - hlen - l2_max_overhead, plen = pkt->pay.len;
  8461. struct mg_addr ips;
  8462. uint8_t *l2addr;
  8463. ips.addr.ip6[0] = pkt->ip6->src[0], ips.addr.ip6[1] = pkt->ip6->src[1];
  8464. ips.is_ip6 = true;
  8465. if ((l2addr = get_return_l2addr(ifp, &ips, false, pkt)) == NULL)
  8466. return; // safety net for lousy networks
  8467. if (plen > room) plen = room; // Copy (truncated) RX payload to TX
  8468. // Echo Reply, 4.2
  8469. tx_icmp6(ifp, l2addr, target, ips.addr.ip6, 129, 0, pkt->pay.buf, plen);
  8470. }
  8471. } break;
  8472. case 134: // Router Advertisement
  8473. rx_ndp_ra(ifp, pkt);
  8474. break;
  8475. case 135: // Neighbor Solicitation
  8476. rx_ndp_ns(ifp, pkt);
  8477. break;
  8478. case 136: // Neighbor Advertisement
  8479. rx_ndp_na(ifp, pkt);
  8480. break;
  8481. default:
  8482. if (mg_log_level >= MG_LL_VERBOSE)
  8483. mg_hexdump(pkt->icmp6, pkt->pay.len > 16 ? 16 : pkt->pay.len);
  8484. break;
  8485. }
  8486. }
  8487. static void onstate6change(struct mg_tcpip_if *ifp) {
  8488. if (ifp->state6 == MG_TCPIP_STATE_READY) {
  8489. MG_INFO(("READY, IP: %M", mg_print_ip6, &ifp->ip6));
  8490. MG_INFO((" GW: %M", mg_print_ip6, &ifp->gw6));
  8491. if (ifp->l2type == MG_TCPIP_L2_ETH) // TODO(): print other l2
  8492. MG_INFO((" MAC: %M", mg_print_mac, &ifp->mac));
  8493. if (ifp->l2type == MG_TCPIP_L2_ETH) { // gratuitous NA annc
  8494. tx_ndp_na(ifp, // RFC-4861 7.2.6
  8495. mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_MCAST6,
  8496. (struct mg_addr *) &ip6_allnodes),
  8497. ifp->ip6ll, (uint64_t *) ip6_allnodes.addr.ip6, false,
  8498. ifp->mac);
  8499. if (ifp->ip6[0] != 0 && ifp->ip6[1] != 0)
  8500. tx_ndp_na(ifp, // RFC-9131 4.1
  8501. mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_MCAST6,
  8502. (struct mg_addr *) &ip6_allrouters),
  8503. ifp->ip6, (uint64_t *) ip6_allrouters.addr.ip6, false,
  8504. ifp->mac);
  8505. }
  8506. if (ifp->is_ip6_changed) {
  8507. struct mg_connection *c;
  8508. for (c = ifp->mgr->conns; c != NULL; c = c->next) {
  8509. if (!c->is_listening && !c->is_udp) c->is_closing = 1;
  8510. }
  8511. ifp->is_ip6_changed = false;
  8512. }
  8513. } else if (ifp->state6 == MG_TCPIP_STATE_IP) {
  8514. if ((ifp->gw6[0] != 0 || ifp->gw6[1] != 0) &&
  8515. (ifp->l2type != MG_TCPIP_L2_PPP && ifp->l2type != MG_TCPIP_L2_PPPoE))
  8516. tx_ndp_ns(ifp, ifp->gw6, NULL); // unsolicited GW hwaddr resolution
  8517. } else if (ifp->state6 == MG_TCPIP_STATE_UP) {
  8518. MG_INFO(("IP: %M", mg_print_ip6, &ifp->ip6ll));
  8519. }
  8520. if (ifp->state6 > MG_TCPIP_STATE_UP)
  8521. mg_tcpip_call(ifp, MG_TCPIP_EV_STATE6_CHANGE, &ifp->state6);
  8522. }
  8523. #endif
  8524. static uint8_t *tcpip_mapip(struct mg_tcpip_if *ifp, struct mg_addr *ip) {
  8525. #if MG_ENABLE_IPV6
  8526. if (ip->is_ip6) {
  8527. if (MG_IP6MATCH(ip->addr.ip6, ip6_allnodes.addr.ip6)) // local broadcast
  8528. return mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_MCAST6,
  8529. (struct mg_addr *) &ip6_allnodes);
  8530. if (*ip->addr.ip == 0xFF) // multicast
  8531. return mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_MCAST6, ip);
  8532. } else
  8533. #endif
  8534. { // global/local broadcast
  8535. if (ip->addr.ip4 == 0xffffffff || ip->addr.ip4 == (ifp->ip | ~ifp->mask))
  8536. return mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_BCAST, NULL);
  8537. if ((*ip->addr.ip & 0xE0) == 0xE0) // 224 ~ 239 = E0 ~ EF, multicast
  8538. return mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_MCAST, ip);
  8539. }
  8540. return NULL;
  8541. }
  8542. static uint8_t *get_return_l2addr(struct mg_tcpip_if *ifp, struct mg_addr *rem,
  8543. bool is_udp, struct pkt *pkt) {
  8544. uint8_t *l2addr;
  8545. if (is_udp && (l2addr = tcpip_mapip(ifp, rem)) != NULL)
  8546. return l2addr; // broadcast or multicast
  8547. #if MG_ENABLE_IPV6
  8548. if (rem->is_ip6) {
  8549. if (rem->addr.ip6[0] == ifp->ip6ll[0] ||
  8550. match_prefix((uint8_t *) rem->addr.ip6, ifp->prefix, ifp->prefix_len))
  8551. return mg_l2_getaddr(ifp, pkt->l2); // same LAN, get from frame
  8552. if (ifp->gw6_ready) // use the router
  8553. return ifp->gw6mac; // ignore source address in frame
  8554. } else
  8555. #endif
  8556. {
  8557. if (ifp->ip != 0 && ((rem->addr.ip4 & ifp->mask) == (ifp->ip & ifp->mask)))
  8558. return mg_l2_getaddr(ifp, pkt->l2); // same LAN, get from frame
  8559. if (ifp->gw_ready) // use the router
  8560. return ifp->gwmac; // ignore source address in frame
  8561. }
  8562. MG_ERROR(("%M %s: No way back, can't respond", mg_print_ip_port, rem,
  8563. is_udp ? "UDP" : "TCP"));
  8564. return NULL;
  8565. }
  8566. static bool rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  8567. struct mg_connection *c = getpeer(ifp->mgr, pkt, true);
  8568. struct connstate *s;
  8569. uint8_t *l2addr;
  8570. if (c == NULL) return false; // No UDP listener on this port
  8571. s = (struct connstate *) (c + 1);
  8572. c->rem.port = pkt->udp->sport;
  8573. #if MG_ENABLE_IPV6
  8574. if (c->loc.is_ip6) { // matching of v4/v6 to dest is done bt getpeer()
  8575. if (!udp6csum_ok(pkt->ip6, pkt->udp)) return false;
  8576. c->rem.addr.ip6[0] = pkt->ip6->src[0],
  8577. c->rem.addr.ip6[1] = pkt->ip6->src[1], c->rem.is_ip6 = true;
  8578. } else
  8579. #endif
  8580. {
  8581. if (!udpcsum_ok(pkt->ip, pkt->udp)) return false;
  8582. c->rem.addr.ip4 = pkt->ip->src;
  8583. }
  8584. if ((l2addr = get_return_l2addr(ifp, &c->rem, true, pkt)) == NULL)
  8585. return false; // safety net for lousy networks
  8586. memcpy(s->mac, l2addr, sizeof(s->mac));
  8587. if (c->recv.len >= MG_MAX_RECV_SIZE) {
  8588. mg_error(c, "max_recv_buf_size reached");
  8589. } else if (c->recv.size - c->recv.len < pkt->pay.len &&
  8590. !mg_iobuf_resize(&c->recv, c->recv.len + pkt->pay.len)) {
  8591. mg_error(c, "oom");
  8592. } else {
  8593. memcpy(&c->recv.buf[c->recv.len], pkt->pay.buf, pkt->pay.len);
  8594. c->recv.len += pkt->pay.len;
  8595. mg_call(c, MG_EV_READ, &pkt->pay.len);
  8596. }
  8597. return true;
  8598. }
  8599. static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *l2_dst,
  8600. struct mg_addr *ip_src, struct mg_addr *ip_dst,
  8601. uint8_t dscp, uint8_t flags, uint32_t seq, uint32_t ack,
  8602. const void *buf, size_t len) {
  8603. uint8_t *l3p;
  8604. struct ip *ip = NULL;
  8605. struct tcp *tcp;
  8606. uint16_t opts[4 / 2];
  8607. size_t hlen = sizeof(*tcp);
  8608. #if MG_ENABLE_IPV6
  8609. struct ip6 *ip6 = NULL;
  8610. #endif
  8611. // Handle any options first, here, to determine header size
  8612. if (flags & TH_SYN) { // Send MSS
  8613. uint16_t mss;
  8614. #if MG_ENABLE_IPV6 // RFC-9293 3.7.1; RFC-6691 2
  8615. mss = (uint16_t) (ifp->mtu - 60);
  8616. #else
  8617. mss = (uint16_t) (ifp->mtu - 40);
  8618. #endif
  8619. opts[0] = mg_htons(0x0204); // RFC-9293 3.2
  8620. opts[1] = mg_htons(mss);
  8621. hlen += sizeof(opts); // always whole number of 32-bit words
  8622. }
  8623. #if MG_ENABLE_IPV6
  8624. if (ip_dst->is_ip6) {
  8625. ip6 = tx_ip6(ifp, l2_dst, 6, dscp, ip_src->addr.ip6, ip_dst->addr.ip6,
  8626. hlen + len);
  8627. tcp = (struct tcp *) (ip6 + 1);
  8628. l3p = (uint8_t *) ip6;
  8629. } else
  8630. #endif
  8631. {
  8632. ip = tx_ip(ifp, l2_dst, 6, dscp, ip_src->addr.ip4, ip_dst->addr.ip4,
  8633. hlen + len);
  8634. tcp = (struct tcp *) (ip + 1);
  8635. l3p = (uint8_t *) ip;
  8636. }
  8637. memset(tcp, 0, sizeof(*tcp));
  8638. memmove(tcp + 1, opts, hlen - sizeof(*tcp)); // copy opts if any
  8639. if (buf != NULL && len) memmove((uint8_t *) tcp + hlen, buf, len);
  8640. tcp->sport = ip_src->port;
  8641. tcp->dport = ip_dst->port;
  8642. tcp->seq = seq;
  8643. tcp->ack = ack;
  8644. tcp->flags = flags;
  8645. tcp->win = mg_htons(MG_TCPIP_WIN);
  8646. tcp->off = (uint8_t) (hlen / 4 << 4);
  8647. #if MG_ENABLE_IPV6
  8648. if (ip_dst->is_ip6) {
  8649. tcp->csum = p6csum(ip6, tcp, hlen + len);
  8650. } else
  8651. #endif
  8652. {
  8653. tcp->csum = pcsum(ip, tcp, hlen + len);
  8654. }
  8655. MG_VERBOSE(("TCP %M -> %M fl %x len %u", mg_print_ip_port, ip_src,
  8656. mg_print_ip_port, ip_dst, tcp->flags, len));
  8657. return driver_output(
  8658. ifp, mg_l2_trailer(ifp, PDIFF(l3p, (uint8_t *) tcp + hlen + len),
  8659. (uint8_t *) tcp + hlen + len));
  8660. }
  8661. static size_t tx_tcp_ctrlresp(struct mg_tcpip_if *ifp, struct pkt *pkt,
  8662. uint8_t flags, uint32_t seqno) {
  8663. uint32_t ackno = mg_htonl(mg_ntohl(pkt->tcp->seq) + (uint32_t) pkt->pay.len +
  8664. ((pkt->tcp->flags & (TH_SYN | TH_FIN)) ? 1 : 0));
  8665. struct mg_addr ips, ipd;
  8666. uint8_t *l2addr;
  8667. memset(&ips, 0, sizeof(ips));
  8668. memset(&ipd, 0, sizeof(ipd));
  8669. if (pkt->ip != NULL) {
  8670. ips.addr.ip4 = pkt->ip->dst;
  8671. ipd.addr.ip4 = pkt->ip->src;
  8672. } else {
  8673. ips.addr.ip6[0] = pkt->ip6->dst[0], ips.addr.ip6[1] = pkt->ip6->dst[1];
  8674. ipd.addr.ip6[0] = pkt->ip6->src[0], ipd.addr.ip6[1] = pkt->ip6->src[1];
  8675. ips.is_ip6 = true;
  8676. ipd.is_ip6 = true;
  8677. }
  8678. ips.port = pkt->tcp->dport;
  8679. ipd.port = pkt->tcp->sport;
  8680. if ((l2addr = get_return_l2addr(ifp, &ipd, false, pkt)) == NULL)
  8681. return 0; // safety net for lousy networks
  8682. return tx_tcp(ifp, l2addr, &ips, &ipd, 0, flags, seqno, ackno, NULL, 0);
  8683. }
  8684. static size_t tx_tcp_rst(struct mg_tcpip_if *ifp, struct pkt *pkt, bool toack) {
  8685. return tx_tcp_ctrlresp(ifp, pkt,
  8686. (uint8_t) (toack ? TH_RST : (TH_RST | TH_ACK)),
  8687. toack ? pkt->tcp->ack : 0);
  8688. }
  8689. static struct mg_connection *accept_conn(struct mg_connection *lsn,
  8690. struct pkt *pkt, uint16_t mss) {
  8691. struct connstate *s;
  8692. uint8_t *l2addr;
  8693. struct mg_connection *c = mg_alloc_conn(lsn->mgr);
  8694. if (c == NULL) {
  8695. MG_ERROR(("OOM"));
  8696. return NULL;
  8697. }
  8698. s = (struct connstate *) (c + 1);
  8699. s->dmss = mss; // from options in client SYN
  8700. s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
  8701. s->win = mg_ntohs(pkt->tcp->win), s->maxseq = (uint32_t) (s->seq + s->win);
  8702. #if MG_ENABLE_IPV6
  8703. if (lsn->loc.is_ip6) {
  8704. c->rem.addr.ip6[0] = pkt->ip6->src[0],
  8705. c->rem.addr.ip6[1] = pkt->ip6->src[1], c->rem.is_ip6 = true;
  8706. c->loc.addr.ip6[0] = c->mgr->ifp->ip6[0],
  8707. c->loc.addr.ip6[1] = c->mgr->ifp->ip6[1], c->loc.is_ip6 = true;
  8708. // TODO(): compare lsn to link-local, or rem as link-local: use ll instead
  8709. } else
  8710. #endif
  8711. {
  8712. c->rem.addr.ip4 = pkt->ip->src;
  8713. c->loc.addr.ip4 = c->mgr->ifp->ip;
  8714. }
  8715. c->rem.port = pkt->tcp->sport;
  8716. c->loc.port = lsn->loc.port;
  8717. if ((l2addr = get_return_l2addr(lsn->mgr->ifp, &c->rem, false, pkt)) ==
  8718. NULL) {
  8719. free(c); // safety net for lousy networks, not actually needed
  8720. return NULL; // as path has already been checked at SYN (sending SYN+ACK)
  8721. }
  8722. memcpy(s->mac, l2addr, sizeof(s->mac));
  8723. settmout(c, MIP_TTYPE_KEEPALIVE);
  8724. MG_DEBUG(("%lu accepted %M", c->id, mg_print_ip_port, &c->rem));
  8725. LIST_ADD_HEAD(struct mg_connection, &lsn->mgr->conns, c);
  8726. c->is_accepted = 1;
  8727. c->is_hexdumping = lsn->is_hexdumping;
  8728. c->pfn = lsn->pfn;
  8729. c->pfn_data = lsn->pfn_data;
  8730. c->fn = lsn->fn;
  8731. c->fn_data = lsn->fn_data;
  8732. c->is_tls = lsn->is_tls;
  8733. mg_call(c, MG_EV_OPEN, NULL);
  8734. mg_call(c, MG_EV_ACCEPT, NULL);
  8735. if (!c->is_tls_hs) c->is_tls = 0; // user did not call mg_tls_init()
  8736. return c;
  8737. }
  8738. static size_t trim_len(struct mg_connection *c, size_t len) {
  8739. struct mg_tcpip_if *ifp = c->mgr->ifp;
  8740. size_t l2_max_overhead = ifp->framesize - ifp->l2mtu;
  8741. size_t ip_max_h_len = c->rem.is_ip6 ? 40 : 24; // we don't send options
  8742. size_t tcp_max_h_len = 60 /* RFC-9293 3.7.1; RFC-6691 2 */, udp_h_len = 8;
  8743. size_t max_headers_len =
  8744. ip_max_h_len + (c->is_udp ? udp_h_len : tcp_max_h_len);
  8745. size_t min_mtu = c->rem.is_ip6 ? 1280 /* RFC-8200, IPv6 minimum */
  8746. : c->is_udp ? 68 /* RFC-791, IP minimum */
  8747. : max_headers_len /* fit full TCP header */;
  8748. // NOTE(): We are effectively reducing transmitted TCP segment length by 20,
  8749. // accounting for possible options; though we currently don't send options
  8750. // except for SYN.
  8751. // If the frame exceeds the available buffer, trim the length.
  8752. if (len + max_headers_len + l2_max_overhead > ifp->tx.len)
  8753. len = ifp->tx.len - max_headers_len - l2_max_overhead;
  8754. // Ensure the MTU isn't lower than the minimum allowed value
  8755. if (ifp->mtu < min_mtu) {
  8756. MG_ERROR(("MTU is lower than minimum, raising to %lu", min_mtu));
  8757. ifp->mtu = (uint16_t) min_mtu;
  8758. }
  8759. // If the total packet size exceeds the MTU, trim the length
  8760. if (len + max_headers_len > ifp->mtu) {
  8761. len = ifp->mtu - max_headers_len;
  8762. if (c->is_udp) MG_ERROR(("UDP datagram exceeds MTU. Truncating it."));
  8763. }
  8764. return len;
  8765. }
  8766. static bool udp_send(struct mg_connection *c, const void *buf, size_t len) {
  8767. struct mg_tcpip_if *ifp = c->mgr->ifp;
  8768. struct connstate *s = (struct connstate *) (c + 1);
  8769. struct mg_addr ips;
  8770. memset(&ips, 0, sizeof(ips));
  8771. #if MG_ENABLE_IPV6
  8772. if (c->loc.is_ip6) {
  8773. ips.addr.ip6[0] = ifp->ip6[0], ips.addr.ip6[1] = ifp->ip6[1],
  8774. ips.is_ip6 = true;
  8775. // TODO(): detect link-local (c->rem) and use it
  8776. } else
  8777. #endif
  8778. {
  8779. ips.addr.ip4 = ifp->ip;
  8780. }
  8781. ips.port = c->loc.port;
  8782. return tx_udp(ifp, s->mac, &ips, &c->rem, c->dscp, buf, len);
  8783. }
  8784. long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
  8785. struct connstate *s = (struct connstate *) (c + 1);
  8786. len = trim_len(c, len);
  8787. if (c->is_udp) {
  8788. if (!udp_send(c, buf, len)) return MG_IO_WAIT;
  8789. } else { // TCP, cap to peer's MSS and check window
  8790. struct mg_tcpip_if *ifp = c->mgr->ifp;
  8791. size_t sent;
  8792. uint32_t room = s->maxseq - s->seq;
  8793. if (room == 0) return MG_IO_WAIT;
  8794. if (len > s->dmss) len = s->dmss; // RFC-6691: reduce if sending opts
  8795. if ((uint32_t) len > room) len = room;
  8796. sent = tx_tcp(ifp, s->mac, &c->loc, &c->rem, c->dscp, TH_PUSH | TH_ACK,
  8797. mg_htonl(s->seq), mg_htonl(s->ack), buf, len);
  8798. if (sent == 0) {
  8799. return MG_IO_WAIT;
  8800. } else if (sent == (size_t) -1) {
  8801. return MG_IO_ERR;
  8802. } else {
  8803. s->seq += (uint32_t) len;
  8804. if (s->ttype == MIP_TTYPE_ACK) settmout(c, MIP_TTYPE_KEEPALIVE);
  8805. }
  8806. }
  8807. return (long) len;
  8808. }
  8809. static void handle_tls_recv(struct mg_connection *c) {
  8810. size_t avail = mg_tls_pending(c); // will change after mg_tls_recv()
  8811. size_t min = avail > MG_MAX_RECV_SIZE ? MG_MAX_RECV_SIZE : avail;
  8812. struct mg_iobuf *io = &c->recv; // allocated on first avail > 0
  8813. if (io->size - io->len < min && !mg_iobuf_resize(io, io->len + min)) {
  8814. mg_error(c, "oom");
  8815. } else {
  8816. // Decrypt data directly into c->recv. If io->buf = NULL or
  8817. // io->len = io->size (no room), there can be outstanding data that can't be
  8818. // moved (mg_tls_pending() > 0 after mg_tls_recv() returns). So
  8819. // mg_tls_recv() takes care of returning 0 in this case (commented as "MIP")
  8820. long n = mg_tls_recv(c, io->buf != NULL ? &io->buf[io->len] : io->buf,
  8821. io->size - io->len);
  8822. if (n == MG_IO_ERR) {
  8823. mg_error(c, "TLS recv error");
  8824. } else if (n > 0) {
  8825. // Decrypted successfully - trigger MG_EV_READ
  8826. io->len += (size_t) n;
  8827. mg_call(c, MG_EV_READ, &n);
  8828. } // else n < 0: outstanding data to be moved to c->recv
  8829. }
  8830. }
  8831. static void handle_ack(struct connstate *s, uint32_t ackno, uint16_t win) {
  8832. if (ackno < (s->seq - s->win) || ackno > s->seq) return;
  8833. s->maxseq = (uint32_t) (ackno + win);
  8834. s->win = win;
  8835. }
  8836. static void read_conn(struct mg_connection *c, struct pkt *pkt) {
  8837. struct connstate *s = (struct connstate *) (c + 1);
  8838. struct mg_iobuf *io = c->is_tls ? &c->rtls : &c->recv;
  8839. uint32_t seq = mg_ntohl(pkt->tcp->seq);
  8840. if (pkt->tcp->flags & TH_FIN) {
  8841. uint8_t flags = TH_ACK;
  8842. if (mg_ntohl(pkt->tcp->seq) != s->ack) {
  8843. MG_VERBOSE(("ignoring FIN, %x != %x", mg_ntohl(pkt->tcp->seq), s->ack));
  8844. tx_tcp(c->mgr->ifp, s->mac, &c->loc, &c->rem, c->dscp, TH_ACK,
  8845. mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
  8846. return;
  8847. }
  8848. // If we initiated the closure, we reply with ACK upon receiving FIN
  8849. // If we didn't initiate it, we reply with FIN as part of the normal TCP
  8850. // closure process
  8851. s->ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len + 1);
  8852. s->fin_rcvd = true;
  8853. if (c->is_draining && s->ttype == MIP_TTYPE_FIN) {
  8854. if (s->seq == mg_htonl(pkt->tcp->ack)) { // Simultaneous closure ?
  8855. s->seq++; // Yes. Increment our SEQ
  8856. } else { // Otherwise,
  8857. s->seq = mg_htonl(pkt->tcp->ack); // Set to peer's ACK
  8858. }
  8859. s->twclosure = true;
  8860. } else {
  8861. // Peer closed first: send ACK only, enter CLOSE_WAIT.
  8862. // The connection loop will call init_closure after pending send data
  8863. // is flushed, then send our FIN.
  8864. c->is_draining = 1;
  8865. }
  8866. tx_tcp(c->mgr->ifp, s->mac, &c->loc, &c->rem, c->dscp, flags,
  8867. mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
  8868. if (pkt->pay.len == 0) return; // if no data, we're done
  8869. } else if (pkt->pay.len <= 1 && mg_ntohl(pkt->tcp->seq) == s->ack - 1) {
  8870. // Keep-Alive (RFC-9293 3.8.4, allow erroneous implementations)
  8871. MG_VERBOSE(("%lu keepalive ACK", c->id));
  8872. tx_tcp(c->mgr->ifp, s->mac, &c->loc, &c->rem, c->dscp, TH_ACK,
  8873. mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
  8874. return; // no data to process
  8875. } else if (pkt->pay.len == 0) { // this is an ACK
  8876. if (pkt->tcp->flags & TH_ACK)
  8877. handle_ack(s, mg_ntohl(pkt->tcp->ack), mg_ntohs(pkt->tcp->win));
  8878. if (s->fin_rcvd && s->ttype == MIP_TTYPE_FIN) s->twclosure = true;
  8879. return; // no data to process
  8880. } else if (seq != s->ack) {
  8881. uint32_t ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
  8882. if (s->ack == ack) {
  8883. MG_VERBOSE(("ignoring duplicate pkt"));
  8884. } else {
  8885. MG_VERBOSE(("SEQ != ACK: %x %x %x", seq, s->ack, ack));
  8886. tx_tcp(c->mgr->ifp, s->mac, &c->loc, &c->rem, c->dscp, TH_ACK,
  8887. mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
  8888. }
  8889. return; // drop it
  8890. } else if (io->size - io->len < pkt->pay.len &&
  8891. !mg_iobuf_resize(io, io->len + pkt->pay.len)) {
  8892. mg_error(c, "oom");
  8893. return; // drop it
  8894. }
  8895. if (pkt->tcp->flags & TH_ACK)
  8896. handle_ack(s, mg_ntohl(pkt->tcp->ack), mg_ntohs(pkt->tcp->win));
  8897. // Copy TCP payload into the IO buffer. If the connection is plain text,
  8898. // we copy to c->recv. If the connection is TLS, this data is encrypted,
  8899. // therefore we copy that encrypted data to the c->rtls iobuffer instead,
  8900. // and then call mg_tls_recv() to decrypt it. NOTE: mg_tls_recv() will
  8901. // call back mg_io_recv() which grabs raw data from c->rtls
  8902. memcpy(&io->buf[io->len], pkt->pay.buf, pkt->pay.len);
  8903. io->len += pkt->pay.len;
  8904. MG_VERBOSE(("%lu SEQ %x -> %x", c->id, mg_htonl(pkt->tcp->seq), s->ack));
  8905. // Advance ACK counter
  8906. s->ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
  8907. s->unacked += pkt->pay.len;
  8908. // size_t diff = s->acked <= s->ack ? s->ack - s->acked : s->ack;
  8909. if (s->unacked > MG_TCPIP_WIN / 2 && s->acked != s->ack) {
  8910. // Send ACK immediately
  8911. MG_VERBOSE(("%lu imm ACK %lu", c->id, s->acked));
  8912. tx_tcp(c->mgr->ifp, s->mac, &c->loc, &c->rem, c->dscp, TH_ACK,
  8913. mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
  8914. s->unacked = 0;
  8915. s->acked = s->ack;
  8916. if (s->ttype != MIP_TTYPE_KEEPALIVE) settmout(c, MIP_TTYPE_KEEPALIVE);
  8917. } else {
  8918. // if not already running, setup a timer to send an ACK later
  8919. if (s->ttype != MIP_TTYPE_ACK) settmout(c, MIP_TTYPE_ACK);
  8920. }
  8921. if (c->is_tls) {
  8922. c->is_tls_hs ? mg_tls_handshake(c) : handle_tls_recv(c);
  8923. } else {
  8924. // Plain text connection, data is already in c->recv, trigger MG_EV_READ
  8925. mg_call(c, MG_EV_READ, &pkt->pay.len);
  8926. }
  8927. }
  8928. // TCP backlog
  8929. struct mg_backlog {
  8930. uint16_t port, mss; // use port=0 for available entries
  8931. uint8_t age;
  8932. };
  8933. static int backlog_insert(struct mg_connection *c, uint16_t port,
  8934. uint16_t mss) {
  8935. struct mg_backlog *p = (struct mg_backlog *) c->data;
  8936. size_t i;
  8937. for (i = 0; i < sizeof(c->data) / sizeof(*p); i++) {
  8938. if (p[i].port != 0) continue;
  8939. p[i].age = 2; // remove after two calls, average 1.5 call rate
  8940. p[i].port = port, p[i].mss = mss;
  8941. return (int) i;
  8942. }
  8943. return -1;
  8944. }
  8945. static struct mg_backlog *backlog_retrieve(struct mg_connection *c,
  8946. uint16_t key, uint16_t port) {
  8947. struct mg_backlog *p = (struct mg_backlog *) c->data;
  8948. if (key >= sizeof(c->data) / sizeof(*p)) return NULL;
  8949. if (p[key].port != port) return NULL;
  8950. p += key;
  8951. return p;
  8952. }
  8953. static void backlog_remove(struct mg_connection *c, uint16_t key) {
  8954. struct mg_backlog *p = (struct mg_backlog *) c->data;
  8955. p[key].port = 0;
  8956. }
  8957. static void backlog_maintain(struct mg_connection *c) {
  8958. struct mg_backlog *p = (struct mg_backlog *) c->data;
  8959. size_t i; // dec age and remove those where it reaches 0
  8960. for (i = 0; i < sizeof(c->data) / sizeof(*p); i++) {
  8961. if (p[i].port == 0) continue;
  8962. if (p[i].age != 0) --p[i].age;
  8963. if (p[i].age == 0) p[i].port = 0;
  8964. }
  8965. }
  8966. static void backlog_poll(struct mg_mgr *mgr) {
  8967. struct mg_connection *c = NULL;
  8968. for (c = mgr->conns; c != NULL; c = c->next) {
  8969. if (!c->is_udp && c->is_listening) backlog_maintain(c);
  8970. }
  8971. }
  8972. // process options (MSS)
  8973. static bool handle_opt(struct connstate *s, struct tcp *tcp, bool ip6) {
  8974. uint8_t *opts = (uint8_t *) (tcp + 1);
  8975. int len = 4 * ((int) (tcp->off >> 4) - ((int) sizeof(*tcp) / 4));
  8976. s->dmss = ip6 ? 1220 : 536; // assume default, RFC-9293 3.7.1
  8977. while (len > 0) { // RFC-9293 3.1 3.2
  8978. uint8_t kind = opts[0], optlen = 1;
  8979. if (kind != 1) { // No-Operation
  8980. if (kind == 0) break; // End of Option List
  8981. if (len < 2 || opts[1] == 0 || opts[1] > len) return false; // Malformed
  8982. optlen = opts[1];
  8983. if (kind == 2 && optlen == 4) // set received MSS
  8984. s->dmss = (uint16_t) (((uint16_t) opts[2] << 8) + opts[3]);
  8985. }
  8986. MG_VERBOSE(("kind: %u, optlen: %u, len: %d\n", kind, optlen, len));
  8987. opts += optlen;
  8988. len -= optlen;
  8989. }
  8990. return true;
  8991. }
  8992. static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  8993. struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
  8994. struct connstate *s = c == NULL ? NULL : (struct connstate *) (c + 1);
  8995. #if MG_ENABLE_IPV6 // matching of v4/v6 to dest is done by getpeer()
  8996. if (pkt->ip6 != NULL && !tcp6csum_ok(pkt->ip6, pkt->tcp)) return;
  8997. #endif
  8998. if (pkt->ip != NULL && !tcpcsum_ok(pkt->ip, pkt->tcp)) return;
  8999. pkt->tcp->flags &= TH_STDFLAGS; // tolerate creative usage (ECN, ?)
  9000. // Order is VERY important; RFC-9293 3.5.2
  9001. // - check clients (Group 1) and established connections (Group 3)
  9002. if (c != NULL && c->is_connecting && pkt->tcp->flags == (TH_SYN | TH_ACK)) {
  9003. // client got a server connection accept
  9004. if (!handle_opt(s, pkt->tcp, pkt->ip6 != NULL))
  9005. return; // process options (MSS)
  9006. s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq) + 1;
  9007. s->win = mg_ntohs(pkt->tcp->win), s->maxseq = (uint32_t) (s->seq + s->win);
  9008. tx_tcp_ctrlresp(ifp, pkt, TH_ACK, pkt->tcp->ack);
  9009. c->is_connecting = 0; // Client connected
  9010. settmout(c, MIP_TTYPE_KEEPALIVE);
  9011. mg_call(c, MG_EV_CONNECT, NULL); // Let user know
  9012. if (c->is_tls_hs) mg_tls_handshake(c);
  9013. if (!c->is_tls_hs) c->is_tls = 0; // user did not call mg_tls_init()
  9014. } else if (c != NULL && c->is_connecting && pkt->tcp->flags != TH_ACK) {
  9015. mg_error(c, "connection refused");
  9016. } else if (c != NULL && pkt->tcp->flags & TH_RST) {
  9017. uint32_t seqno = mg_ntohl(pkt->tcp->seq);
  9018. if (seqno >= s->ack && seqno < (s->ack + MG_TCPIP_WIN)) // RFC-9293 3.5.3
  9019. mg_error(c, "peer RST"); // RFC-1122 4.2.2.13
  9020. } else if (c != NULL) {
  9021. // process segment
  9022. s->tmiss = 0; // Reset missed keep-alive counter
  9023. if (s->ttype == MIP_TTYPE_KEEPALIVE) // Advance keep-alive timer
  9024. settmout(c,
  9025. MIP_TTYPE_KEEPALIVE); // unless a former ACK timeout is pending
  9026. read_conn(c, pkt); // Override timer with ACK timeout if needed
  9027. } else
  9028. // - we don't listen on that port; RFC-9293 3.5.2 Group 1
  9029. // - check listening connections; RFC-9293 3.5.2 Group 2
  9030. if ((c = getpeer(ifp->mgr, pkt, true)) == NULL) {
  9031. // not listening on that port
  9032. if (!(pkt->tcp->flags & TH_RST)) {
  9033. tx_tcp_rst(ifp, pkt, pkt->tcp->flags & TH_ACK);
  9034. } // else silently discard
  9035. } else if (pkt->tcp->flags == TH_SYN) {
  9036. // listener receives a connection request
  9037. struct connstate cs; // At this point, s = NULL, there is no connection
  9038. int key;
  9039. uint32_t isn;
  9040. if (pkt->tcp->sport != 0) {
  9041. if (!handle_opt(&cs, pkt->tcp, pkt->ip6 != NULL))
  9042. return; // process options (MSS)
  9043. key = backlog_insert(c, pkt->tcp->sport,
  9044. cs.dmss); // backlog options (MSS)
  9045. if (key < 0) return; // no room in backlog, discard SYN, client retries
  9046. // Use peer's src port and bl key as ISN, to later identify the
  9047. // handshake
  9048. isn = (mg_htonl(((uint32_t) key << 16) | mg_ntohs(pkt->tcp->sport)));
  9049. if (tx_tcp_ctrlresp(ifp, pkt, TH_SYN | TH_ACK, isn) == 0)
  9050. backlog_remove(c, (uint16_t) key); // safety net for lousy networks
  9051. } // what should we do when port=0 ? Linux takes port 0 as any other
  9052. // port
  9053. } else if (pkt->tcp->flags == TH_ACK) {
  9054. // listener receives an ACK
  9055. struct mg_backlog *b = NULL;
  9056. if ((uint16_t) (mg_htonl(pkt->tcp->ack) - 1) ==
  9057. mg_htons(pkt->tcp->sport)) {
  9058. uint16_t key = (uint16_t) ((mg_htonl(pkt->tcp->ack) - 1) >> 16);
  9059. b = backlog_retrieve(c, key, pkt->tcp->sport);
  9060. if (b != NULL) { // ACK is a response to a SYN+ACK
  9061. accept_conn(c, pkt, b->mss); // pass options
  9062. backlog_remove(c, key);
  9063. } // else not an actual match, reset
  9064. }
  9065. if (b == NULL) tx_tcp_rst(ifp, pkt, true);
  9066. } else if (pkt->tcp->flags & TH_RST) {
  9067. // silently discard
  9068. } else if (pkt->tcp->flags & TH_ACK) { // ACK + something else != RST
  9069. tx_tcp_rst(ifp, pkt, true);
  9070. } else if (pkt->tcp->flags & TH_SYN) { // SYN + something else != ACK
  9071. tx_tcp_rst(ifp, pkt, false);
  9072. } // else silently discard
  9073. }
  9074. static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  9075. uint8_t ihl;
  9076. uint16_t frag, len;
  9077. if (pkt->pay.len < sizeof(*pkt->ip)) return; // Truncated
  9078. if ((pkt->ip->ver >> 4) != 4) return; // Not IP
  9079. ihl = pkt->ip->ver & 0x0F;
  9080. if (ihl < 5) return; // bad IHL
  9081. if (pkt->pay.len < (uint16_t) (ihl * 4)) return; // Truncated / malformed
  9082. // There can be link padding, take length from IP header
  9083. len = mg_ntohs(pkt->ip->len); // IP datagram length
  9084. if (len < (uint16_t) (ihl * 4) || len > pkt->pay.len) return; // malformed
  9085. pkt->pay.len = len; // strip padding
  9086. mkpay(pkt, (uint32_t *) pkt->ip + ihl); // account for opts
  9087. if (!ipcsum_ok(pkt->ip)) return;
  9088. frag = mg_ntohs(pkt->ip->frag);
  9089. if (frag & IP_MORE_FRAGS_MSK || frag & IP_FRAG_OFFSET_MSK) {
  9090. struct mg_connection *c;
  9091. if (pkt->ip->proto == 17) pkt->udp = (struct udp *) (pkt->pay.buf);
  9092. if (pkt->ip->proto == 6) pkt->tcp = (struct tcp *) (pkt->pay.buf);
  9093. c = getpeer(ifp->mgr, pkt, false);
  9094. if (c) mg_error(c, "Received fragmented packet");
  9095. } else if (pkt->ip->proto == 1) {
  9096. pkt->icmp = (struct icmp *) (pkt->pay.buf);
  9097. if (pkt->pay.len < sizeof(*pkt->icmp)) return;
  9098. mkpay(pkt, pkt->icmp + 1);
  9099. rx_icmp(ifp, pkt);
  9100. } else if (pkt->ip->proto == 17) {
  9101. pkt->udp = (struct udp *) (pkt->pay.buf);
  9102. if (pkt->pay.len < sizeof(*pkt->udp)) return; // truncated
  9103. // Take length from UDP header
  9104. len = mg_ntohs(pkt->udp->len); // UDP datagram length
  9105. if (len < sizeof(*pkt->udp) || len > pkt->pay.len) return; // malformed
  9106. pkt->pay.len = len; // strip excess data
  9107. mkpay(pkt, pkt->udp + 1);
  9108. MG_VERBOSE(("UDP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src,
  9109. mg_ntohs(pkt->udp->sport), mg_print_ip4, &pkt->ip->dst,
  9110. mg_ntohs(pkt->udp->dport), (int) pkt->pay.len));
  9111. if (ifp->enable_dhcp_client && pkt->udp->dport == mg_htons(68) &&
  9112. len >= offsetof(struct dhcp, options)) {
  9113. pkt->dhcp = (struct dhcp *) (pkt->udp + 1);
  9114. mkpay(pkt, &pkt->dhcp->options);
  9115. rx_dhcp_client(ifp, pkt);
  9116. } else if (ifp->enable_dhcp_server && pkt->udp->dport == mg_htons(67) &&
  9117. len >= offsetof(struct dhcp, options)) {
  9118. pkt->dhcp = (struct dhcp *) (pkt->udp + 1);
  9119. mkpay(pkt, &pkt->dhcp->options);
  9120. rx_dhcp_server(ifp, pkt);
  9121. } else if (!rx_udp(ifp, pkt)) {
  9122. // Should send ICMP Destination Unreachable for unicasts, but keep
  9123. // silent
  9124. }
  9125. } else if (pkt->ip->proto == 6) {
  9126. uint8_t off;
  9127. pkt->tcp = (struct tcp *) (pkt->pay.buf);
  9128. if (pkt->pay.len < sizeof(*pkt->tcp)) return;
  9129. off = pkt->tcp->off >> 4; // account for opts
  9130. if (pkt->pay.len < (uint16_t) (4 * off)) return;
  9131. mkpay(pkt, (uint32_t *) pkt->tcp + off);
  9132. MG_VERBOSE(("TCP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src,
  9133. mg_ntohs(pkt->tcp->sport), mg_print_ip4, &pkt->ip->dst,
  9134. mg_ntohs(pkt->tcp->dport), (int) pkt->pay.len));
  9135. rx_tcp(ifp, pkt);
  9136. } else {
  9137. MG_DEBUG(("Unknown IP proto %x", (int) pkt->ip->proto));
  9138. if (mg_log_level >= MG_LL_VERBOSE)
  9139. mg_hexdump(pkt->ip, pkt->pay.len >= 32 ? 32 : pkt->pay.len);
  9140. }
  9141. }
  9142. #if MG_ENABLE_IPV6
  9143. static void rx_ip6(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  9144. uint16_t len = 0, plen;
  9145. uint8_t next, *nhdr;
  9146. bool loop = true;
  9147. if (pkt->pay.len < sizeof(*pkt->ip6)) return; // Truncated
  9148. if ((pkt->ip6->ver >> 4) != 0x6) return; // Not IPv6
  9149. plen = mg_ntohs(pkt->ip6->plen);
  9150. if (plen > (pkt->pay.len - sizeof(*pkt->ip6))) return; // malformed
  9151. next = pkt->ip6->next;
  9152. nhdr = (uint8_t *) (pkt->ip6 + 1);
  9153. while (loop) {
  9154. uint16_t hlen;
  9155. switch (next) {
  9156. case 0: // Hop-by-Hop 4.3
  9157. case 43: // Routing 4.4
  9158. case 60: // Destination Options 4.6
  9159. case 51: // Authentication RFC-4302
  9160. MG_INFO(("IPv6 extension header %d", (int) next));
  9161. if (((uint32_t) len + 2) > plen) return; // nhdr[0, 1]; malformed
  9162. next = nhdr[0];
  9163. hlen = (uint16_t) (8 * (nhdr[1] + 1));
  9164. if (((uint32_t) len + hlen) > plen) return; // malformed
  9165. len += hlen;
  9166. nhdr += hlen;
  9167. break;
  9168. case 44: // Fragment 4.5
  9169. {
  9170. struct mg_connection *c;
  9171. if (((uint32_t) len + 2) > plen) return; // nhdr[0, 1]; malformed
  9172. if (nhdr[0] == 17) pkt->udp = (struct udp *) (pkt->pay.buf);
  9173. if (nhdr[0] == 6) pkt->tcp = (struct tcp *) (pkt->pay.buf);
  9174. c = getpeer(ifp->mgr, pkt, false);
  9175. if (c) mg_error(c, "Received fragmented packet");
  9176. }
  9177. return;
  9178. case 59: // No Next Header 4.7
  9179. return;
  9180. case 50: // IPsec ESP RFC-4303, unsupported
  9181. default:
  9182. loop = false;
  9183. break;
  9184. }
  9185. }
  9186. // There can be link padding, take payload length from IPv6 header - options
  9187. pkt->pay.buf = (char *) nhdr;
  9188. pkt->pay.len = plen - len;
  9189. if (next == 58) {
  9190. pkt->icmp6 = (struct icmp6 *) (pkt->pay.buf);
  9191. if (pkt->pay.len < sizeof(*pkt->icmp6)) return;
  9192. mkpay(pkt, pkt->icmp6 + 1);
  9193. MG_DEBUG(("ICMPv6 %M -> %M len %u", mg_print_ip6, &pkt->ip6->src,
  9194. mg_print_ip6, &pkt->ip6->dst, (int) pkt->pay.len));
  9195. rx_icmp6(ifp, pkt);
  9196. } else if (next == 17) {
  9197. pkt->udp = (struct udp *) (pkt->pay.buf);
  9198. if (pkt->pay.len < sizeof(*pkt->udp)) return;
  9199. // Take length from UDP header
  9200. len = mg_ntohs(pkt->udp->len); // UDP datagram length
  9201. if (len < sizeof(*pkt->udp) || len > pkt->pay.len) return; // malformed
  9202. pkt->pay.len = len; // strip excess data
  9203. mkpay(pkt, pkt->udp + 1);
  9204. MG_DEBUG(("UDP %M:%hu -> %M:%hu len %u", mg_print_ip6, &pkt->ip6->src,
  9205. mg_ntohs(pkt->udp->sport), mg_print_ip6, &pkt->ip6->dst,
  9206. mg_ntohs(pkt->udp->dport), (int) pkt->pay.len));
  9207. if (ifp->enable_dhcp6_client && pkt->udp->dport == mg_htons(546)) {
  9208. pkt->dhcp6 = (struct dhcp6 *) (pkt->udp + 1);
  9209. mkpay(pkt, pkt->dhcp6 + 1);
  9210. // rx_dhcp6_client(ifp, pkt);
  9211. #if 0
  9212. } else if (ifp->enable_dhcp_server && pkt->udp->dport == mg_htons(547)) {
  9213. pkt->dhcp6 = (struct dhcp6 *) (pkt->udp + 1);
  9214. mkpay(pkt, pkt->dhcp6 + 1);
  9215. rx_dhcp6_server(ifp, pkt);
  9216. #endif
  9217. } else if (!rx_udp(ifp, pkt)) {
  9218. // Should send ICMPv6 Destination Unreachable for unicasts, keep silent
  9219. }
  9220. } else if (next == 6) {
  9221. uint8_t off;
  9222. pkt->tcp = (struct tcp *) (pkt->pay.buf);
  9223. if (pkt->pay.len < sizeof(*pkt->tcp)) return;
  9224. off = pkt->tcp->off >> 4; // account for opts
  9225. if (pkt->pay.len < (uint16_t) (4 * off)) return;
  9226. mkpay(pkt, (uint32_t *) pkt->tcp + off);
  9227. MG_DEBUG(("TCP %M:%hu -> %M:%hu len %u", mg_print_ip6, &pkt->ip6->src,
  9228. mg_ntohs(pkt->tcp->sport), mg_print_ip6, &pkt->ip6->dst,
  9229. mg_ntohs(pkt->tcp->dport), (int) pkt->pay.len));
  9230. rx_tcp(ifp, pkt);
  9231. } else {
  9232. MG_DEBUG(("Unknown IPv6 next hdr %x", (int) next));
  9233. if (mg_log_level >= MG_LL_VERBOSE)
  9234. mg_hexdump(pkt->ip6, pkt->pay.len >= 32 ? 32 : pkt->pay.len);
  9235. }
  9236. }
  9237. #else
  9238. #define rx_ip6(x, y)
  9239. #endif
  9240. static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
  9241. struct pkt pkt;
  9242. enum mg_l2proto proto;
  9243. memset(&pkt, 0, sizeof(pkt));
  9244. pkt.raw.buf = (char *) buf;
  9245. pkt.raw.len = len;
  9246. pkt.l2 = (uint8_t *) pkt.raw.buf;
  9247. if (!mg_l2_rx(ifp, &proto, &pkt.pay, &pkt.raw)) return;
  9248. if (ifp->state < MG_TCPIP_STATE_UP) return; // discard while L2 is not up
  9249. if (proto == MG_TCPIP_L2PROTO_ARP) {
  9250. pkt.arp = (struct arp *) (pkt.pay.buf);
  9251. if (pkt.pay.len < sizeof(*pkt.arp)) return; // Truncated
  9252. mg_tcpip_call(ifp, MG_TCPIP_EV_ARP, &pkt.raw);
  9253. rx_arp(ifp, &pkt);
  9254. } else if (proto == MG_TCPIP_L2PROTO_IPV6) {
  9255. pkt.ip6 = (struct ip6 *) (pkt.pay.buf);
  9256. rx_ip6(ifp, &pkt);
  9257. } else if (proto == MG_TCPIP_L2PROTO_IPV4) {
  9258. pkt.ip = (struct ip *) (pkt.pay.buf);
  9259. rx_ip(ifp, &pkt);
  9260. }
  9261. }
  9262. static void mg_ip_poll(struct mg_tcpip_if *ifp, bool s1) {
  9263. if (ifp->state < MG_TCPIP_STATE_UP) return;
  9264. // DHCP RFC-2131 (4.4)
  9265. if (ifp->enable_dhcp_client && s1) {
  9266. if (ifp->state == MG_TCPIP_STATE_UP) {
  9267. tx_dhcp_discover(ifp); // INIT (4.4.1)
  9268. } else if (ifp->state == MG_TCPIP_STATE_READY &&
  9269. ifp->lease_expire > 0) { // BOUND / RENEWING / REBINDING
  9270. if (ifp->now >= ifp->lease_expire) {
  9271. ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0; // expired, release IP
  9272. onstatechange(ifp);
  9273. } else if (ifp->now + 30UL * 60UL * 1000UL > ifp->lease_expire &&
  9274. ((ifp->now / 1000) % 60) == 0) {
  9275. // hack: 30 min before deadline, try to rebind (4.3.6) every min
  9276. tx_dhcp_request_re(
  9277. ifp, mg_l2_mapip(ifp->l2type, MG_TCPIP_L2ADDR_BCAST, NULL), ifp->ip,
  9278. 0xffffffff);
  9279. } // TODO(): Handle T1 (RENEWING) and T2 (REBINDING) (4.4.5)
  9280. }
  9281. }
  9282. }
  9283. static void mg_ip_link(struct mg_tcpip_if *ifp, bool drv_up, bool l2_up) {
  9284. bool cur_drv = (ifp->state != MG_TCPIP_STATE_DOWN);
  9285. bool cur_l2 = (ifp->state >= MG_TCPIP_STATE_UP);
  9286. if (!l2_up && ifp->enable_dhcp_client) ifp->ip = 0;
  9287. if (drv_up != cur_drv || l2_up != cur_l2) { // link/L2 state has changed
  9288. ifp->state = !drv_up ? MG_TCPIP_STATE_DOWN
  9289. : !l2_up ? MG_TCPIP_STATE_LINK_UP
  9290. : ifp->enable_dhcp_client || ifp->ip == 0 ? MG_TCPIP_STATE_UP
  9291. : MG_TCPIP_STATE_IP;
  9292. onstatechange(ifp);
  9293. } else if (!ifp->enable_dhcp_client && ifp->state == MG_TCPIP_STATE_UP &&
  9294. ifp->ip) {
  9295. ifp->state = MG_TCPIP_STATE_IP; // ifp->fn has set an IP
  9296. onstatechange(ifp);
  9297. }
  9298. }
  9299. #if MG_ENABLE_IPV6
  9300. static void mg_ip6_poll(struct mg_tcpip_if *ifp, bool s1) {
  9301. if (ifp->state6 < MG_TCPIP_STATE_UP) return;
  9302. if (ifp->enable_slaac && s1 && ifp->state6 == MG_TCPIP_STATE_UP)
  9303. tx_ndp_rs(ifp);
  9304. }
  9305. static void mg_ip6_link(struct mg_tcpip_if *ifp, bool drv_up, bool l2_up) {
  9306. bool cur_drv = (ifp->state6 != MG_TCPIP_STATE_DOWN);
  9307. bool cur_l2 = (ifp->state6 >= MG_TCPIP_STATE_UP);
  9308. const uint8_t px[8] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0}; // RFC-4291 2.5.6
  9309. if (drv_up != cur_drv || l2_up != cur_l2) { // link/L2 state has changed
  9310. if (ifp->l2type == MG_TCPIP_L2_ETH && l2_up && ifp->ip6ll[0] == 0 &&
  9311. ifp->ip6ll[1] == 0) { // gen ll address
  9312. mg_l2_genip6(ifp->l2type, ifp->ip6ll, 64, ifp->mac);
  9313. memcpy(ifp->ip6ll, px, 8); // RFC-2464 5
  9314. } // just got our link local address if we didn't have one.
  9315. // If static configuration is used, global addresses,
  9316. // prefix length, and gw are already filled at this point.
  9317. if (ifp->ip6[0] == 0 && ifp->ip6[1] == 0) ifp->enable_slaac = true;
  9318. if (!l2_up && ifp->enable_slaac) ifp->ip6[0] = ifp->ip6[1] = 0;
  9319. ifp->state6 = !drv_up ? MG_TCPIP_STATE_DOWN
  9320. : !l2_up ? MG_TCPIP_STATE_LINK_UP
  9321. : ifp->ip6ll[0] == 0 || ifp->enable_slaac || ifp->ip6[0] == 0
  9322. ? MG_TCPIP_STATE_UP
  9323. : MG_TCPIP_STATE_IP;
  9324. onstate6change(ifp);
  9325. } else if (!ifp->enable_slaac && ifp->state6 == MG_TCPIP_STATE_UP &&
  9326. ifp->ip6ll[0] != 0 && ifp->ip6[0] != 0) {
  9327. ifp->state6 = MG_TCPIP_STATE_IP; // ifp->fn has set an IP
  9328. onstate6change(ifp);
  9329. }
  9330. if ((ifp->l2type == MG_TCPIP_L2_PPP || ifp->l2type == MG_TCPIP_L2_PPPoE) &&
  9331. ifp->state6 == MG_TCPIP_STATE_UP && ifp->ip6ll[0] == 0 &&
  9332. ifp->ip6ll[1] != 0) { // IPV6CP has got an IFCID, gen ll address
  9333. memcpy(ifp->ip6ll, px, 8); // RFC-5072 5
  9334. onstate6change(ifp);
  9335. } // just got our link local address if we didn't have one.
  9336. }
  9337. #else
  9338. #define mg_ip6_poll(x, y)
  9339. #define mg_ip6_link(x, y, z)
  9340. #endif
  9341. static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {
  9342. struct mg_connection *c;
  9343. bool expired_1000ms = mg_timer_expired(&ifp->timer_1000ms, 1000, now);
  9344. ifp->now = now;
  9345. if (expired_1000ms) {
  9346. #if MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
  9347. const char *names[] = {"down", "lnk up", "lnk rdy", "req", "ip", "ready"};
  9348. size_t max = sizeof(names) / sizeof(char *);
  9349. unsigned int state = ifp->state >= max ? max - 1 : ifp->state;
  9350. MG_INFO(("Status: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u", names[state],
  9351. mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent, ifp->ndrop,
  9352. ifp->nerr));
  9353. #if MG_ENABLE_IPV6
  9354. state = ifp->state6 >= max ? max - 1 : ifp->state6;
  9355. if (state > MG_TCPIP_STATE_UP)
  9356. MG_INFO(("Status: %s, IPv6: %M", names[state], mg_print_ip6, &ifp->ip6));
  9357. #endif
  9358. #endif
  9359. backlog_poll(ifp->mgr);
  9360. }
  9361. // Handle gw ARP request timeout, order is important
  9362. if (expired_1000ms && ifp->state == MG_TCPIP_STATE_IP) {
  9363. ifp->state = MG_TCPIP_STATE_READY; // keep best-effort MAC or poison mark
  9364. onstatechange(ifp);
  9365. }
  9366. if (expired_1000ms && ifp->state == MG_TCPIP_STATE_READY && !ifp->gw_ready &&
  9367. ifp->gw != 0)
  9368. mg_tcpip_arp_request(ifp, ifp->gw, NULL); // retry GW ARP request
  9369. #if MG_ENABLE_IPV6
  9370. // Handle gw NS/NA req/resp timeout, order is important
  9371. if (expired_1000ms && ifp->state6 == MG_TCPIP_STATE_IP) {
  9372. ifp->state6 = MG_TCPIP_STATE_READY; // keep best-effort MAC or poison mark
  9373. onstate6change(ifp);
  9374. }
  9375. if (expired_1000ms && ifp->state == MG_TCPIP_STATE_READY && !ifp->gw6_ready &&
  9376. (ifp->gw6[0] != 0 || ifp->gw6[1] != 0))
  9377. tx_ndp_ns(ifp, ifp->gw6, NULL); // retry GW hwaddr resolution
  9378. #endif
  9379. { // poll driver and let L2 do its work, if any
  9380. // Handle physical interface up/down status
  9381. bool drv_up, l2_up;
  9382. drv_up = ifp->driver->poll ? ifp->driver->poll(ifp, expired_1000ms) : true;
  9383. l2_up = mg_l2_poll(ifp, expired_1000ms); // Handle L2 up/down link status;
  9384. if (expired_1000ms) { // ifp->state rules over state6
  9385. mg_ip_link(ifp, drv_up, l2_up); // Handle IPv4
  9386. mg_ip6_link(ifp, drv_up, l2_up); // Handle IPv6
  9387. if (ifp->state < MG_TCPIP_STATE_UP) MG_ERROR(("Network is down"));
  9388. mg_tcpip_call(ifp, MG_TCPIP_EV_TIMER_1S, NULL);
  9389. }
  9390. }
  9391. mg_ip_poll(ifp, expired_1000ms); // Handle IPv4
  9392. mg_ip6_poll(ifp, expired_1000ms); // Handle IPv6
  9393. // Read data from the network (mg_tcpip_rx() will discard for us)
  9394. if (ifp->driver->rx != NULL) { // Simple polling driver, returns one frame
  9395. size_t len =
  9396. ifp->driver->rx(ifp->recv_queue.buf, ifp->recv_queue.size, ifp);
  9397. if (len > 0) {
  9398. ifp->nrecv++;
  9399. mg_tcpip_rx(ifp, ifp->recv_queue.buf, len);
  9400. }
  9401. } else { // Complex poll / Interrupt-based driver. Queues recvd frames
  9402. char *buf;
  9403. size_t len, cnt = 7; // Max 7 packets to fetch
  9404. while (cnt-- > 0 && (len = mg_queue_next(&ifp->recv_queue, &buf)) > 0) {
  9405. mg_tcpip_rx(ifp, buf, len);
  9406. mg_queue_del(&ifp->recv_queue, len);
  9407. }
  9408. }
  9409. if (ifp->state < MG_TCPIP_STATE_UP) return; // need to let L2 do its job
  9410. // Process timeouts
  9411. for (c = ifp->mgr->conns; c != NULL; c = c->next) {
  9412. struct connstate *s = (struct connstate *) (c + 1);
  9413. if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving)
  9414. continue;
  9415. if (ifp->now > s->timer) {
  9416. if (s->ttype == MIP_TTYPE_ARP) {
  9417. mg_error(c, "ARP timeout");
  9418. } else if (c->is_udp) {
  9419. continue;
  9420. } else if (s->ttype == MIP_TTYPE_ACK && s->acked != s->ack) {
  9421. MG_VERBOSE(("%lu ack %x %x", c->id, s->seq, s->ack));
  9422. tx_tcp(ifp, s->mac, &c->loc, &c->rem, c->dscp, TH_ACK, mg_htonl(s->seq),
  9423. mg_htonl(s->ack), NULL, 0);
  9424. s->acked = s->ack;
  9425. } else if (s->ttype == MIP_TTYPE_SYN) {
  9426. mg_error(c, "Connection timeout");
  9427. } else if (s->ttype == MIP_TTYPE_FIN) {
  9428. c->is_closing = 1;
  9429. continue;
  9430. } else {
  9431. if (s->tmiss++ > 2) {
  9432. mg_error(c, "keepalive");
  9433. } else {
  9434. MG_VERBOSE(("%lu keepalive", c->id));
  9435. tx_tcp(ifp, s->mac, &c->loc, &c->rem, c->dscp, TH_ACK,
  9436. mg_htonl(s->seq - 1), mg_htonl(s->ack), NULL, 0);
  9437. }
  9438. }
  9439. settmout(c, MIP_TTYPE_KEEPALIVE);
  9440. }
  9441. }
  9442. }
  9443. // This function executes in interrupt context, thus it should copy data
  9444. // somewhere fast. Note that newlib's malloc is not thread safe, thus use
  9445. // our lock-free queue with preallocated buffer to copy data and return asap
  9446. void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp) {
  9447. char *p;
  9448. if (mg_queue_book(&ifp->recv_queue, &p, len) >= len) {
  9449. memcpy(p, buf, len);
  9450. mg_queue_add(&ifp->recv_queue, len);
  9451. ifp->nrecv++;
  9452. } else {
  9453. ifp->ndrop++;
  9454. }
  9455. }
  9456. void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
  9457. // If L2 address is not set, make a random one; fill MTU
  9458. mg_l2_init(ifp);
  9459. ifp->mtu = ifp->l2mtu;
  9460. if (ifp->dhcp_name[0] == '\0') // If DHCP name is not set, use "mip"
  9461. memcpy(ifp->dhcp_name, "mip", 4);
  9462. ifp->dhcp_name[sizeof(ifp->dhcp_name) - 1] = '\0'; // Just in case
  9463. if (ifp->driver->init && !ifp->driver->init(ifp)) {
  9464. MG_ERROR(("driver init failed"));
  9465. } else {
  9466. ifp->tx.buf = (char *) mg_calloc(1, ifp->framesize),
  9467. ifp->tx.len = ifp->framesize;
  9468. if (ifp->recv_queue.size == 0)
  9469. ifp->recv_queue.size = ifp->driver->rx ? ifp->framesize : 8192;
  9470. ifp->recv_queue.buf = (char *) mg_calloc(1, ifp->recv_queue.size);
  9471. ifp->timer_1000ms = mg_millis();
  9472. mgr->ifp = ifp;
  9473. ifp->mgr = mgr;
  9474. mgr->extraconnsize = sizeof(struct connstate);
  9475. if (ifp->ip == 0 && ifp->l2type != MG_TCPIP_L2_PPP &&
  9476. ifp->l2type != MG_TCPIP_L2_PPPoE)
  9477. ifp->enable_dhcp_client = true;
  9478. mg_random(&ifp->eport, sizeof(ifp->eport)); // Random from 0 to 65535
  9479. ifp->eport |= MG_EPHEMERAL_PORT_BASE; // Random from
  9480. // MG_EPHEMERAL_PORT_BASE to 65535
  9481. if (ifp->tx.buf == NULL || ifp->recv_queue.buf == NULL) MG_ERROR(("OOM"));
  9482. }
  9483. }
  9484. void mg_tcpip_free(struct mg_tcpip_if *ifp) {
  9485. mg_free(ifp->recv_queue.buf);
  9486. mg_free(ifp->tx.buf);
  9487. mg_free(ifp->dns4_url);
  9488. }
  9489. static void send_syn(struct mg_connection *c) {
  9490. struct connstate *s = (struct connstate *) (c + 1);
  9491. uint32_t isn = mg_htonl((uint32_t) mg_ntohs(c->loc.port));
  9492. tx_tcp(c->mgr->ifp, s->mac, &c->loc, &c->rem, c->dscp, TH_SYN, isn, 0, NULL,
  9493. 0);
  9494. }
  9495. static void l2addr_resolved(struct mg_connection *c) {
  9496. if (c->is_udp) {
  9497. c->is_connecting = 0;
  9498. mg_call(c, MG_EV_CONNECT, NULL);
  9499. } else {
  9500. send_syn(c);
  9501. settmout(c, MIP_TTYPE_SYN);
  9502. }
  9503. }
  9504. void mg_connect_resolved(struct mg_connection *c) {
  9505. struct mg_tcpip_if *ifp = c->mgr->ifp;
  9506. uint8_t *l2addr;
  9507. c->is_resolving = 0;
  9508. if (ifp->eport < MG_EPHEMERAL_PORT_BASE) ifp->eport = MG_EPHEMERAL_PORT_BASE;
  9509. c->loc.port = mg_htons(ifp->eport++);
  9510. #if MG_ENABLE_IPV6
  9511. if (c->rem.is_ip6) {
  9512. if (c->rem.addr.ip6[0] == ifp->ip6ll[0]) { // same local LAN, use ll
  9513. c->loc.addr.ip6[0] = ifp->ip6ll[0], c->loc.addr.ip6[1] = ifp->ip6ll[1];
  9514. } else { // use global address
  9515. c->loc.addr.ip6[0] = ifp->ip6[0], c->loc.addr.ip6[1] = ifp->ip6[1];
  9516. }
  9517. c->loc.is_ip6 = true;
  9518. } else
  9519. #endif
  9520. {
  9521. c->loc.addr.ip4 = ifp->ip;
  9522. }
  9523. MG_DEBUG(("%lu %M -> %M", c->id, mg_print_ip_port, &c->loc, mg_print_ip_port,
  9524. &c->rem));
  9525. mg_call(c, MG_EV_RESOLVE, NULL);
  9526. c->is_connecting = 1;
  9527. if (c->is_udp && (l2addr = tcpip_mapip(ifp, &c->rem)) != NULL) {
  9528. struct connstate *s = (struct connstate *) (c + 1);
  9529. memcpy(s->mac, l2addr, sizeof(s->mac));
  9530. l2addr_resolved(c); // broadcast or multicast
  9531. #if MG_ENABLE_IPV6
  9532. } else if (c->rem.is_ip6) {
  9533. if (match_prefix((uint8_t *) c->rem.addr.ip6, ifp->prefix,
  9534. ifp->prefix_len) // same global LAN
  9535. || (c->rem.addr.ip6[0] == ifp->ip6ll[0] // same local LAN
  9536. && !MG_IP6MATCH(c->rem.addr.ip6, ifp->gw6))) { // and not gw
  9537. // If we're in the same LAN, fire a Neighbor Solicitation
  9538. MG_DEBUG(("%lu NS lookup...", c->id));
  9539. tx_ndp_ns(ifp, c->rem.addr.ip6, NULL); // RFC-4861 4.3, requesting
  9540. settmout(c, MIP_TTYPE_ARP);
  9541. c->is_arplooking = 1;
  9542. } else if (ifp->gw6_ready) {
  9543. struct connstate *s = (struct connstate *) (c + 1);
  9544. memcpy(s->mac, ifp->gw6mac, sizeof(s->mac));
  9545. l2addr_resolved(c);
  9546. } else {
  9547. MG_ERROR(("No IPv6 gateway, can't connect"));
  9548. }
  9549. #endif
  9550. } else {
  9551. uint32_t rem_ip = c->rem.addr.ip4;
  9552. if (ifp->ip && ((rem_ip & ifp->mask) == (ifp->ip & ifp->mask)) &&
  9553. rem_ip != ifp->gw) { // skip if gw (onstatechange -> ARP)
  9554. // If we're in the same LAN, fire an ARP lookup.
  9555. MG_DEBUG(("%lu ARP lookup...", c->id));
  9556. mg_tcpip_arp_request(ifp, rem_ip, NULL);
  9557. settmout(c, MIP_TTYPE_ARP);
  9558. c->is_arplooking = 1;
  9559. } else if (ifp->gw_ready) {
  9560. struct connstate *s = (struct connstate *) (c + 1);
  9561. memcpy(s->mac, ifp->gwmac, sizeof(s->mac));
  9562. l2addr_resolved(c);
  9563. } else {
  9564. MG_ERROR(("No gateway, can't connect"));
  9565. }
  9566. }
  9567. }
  9568. bool mg_open_listener(struct mg_connection *c, const char *url) {
  9569. c->loc.port = mg_htons(mg_url_port(url));
  9570. if (!mg_aton(mg_url_host(url), &c->loc)) {
  9571. MG_ERROR(("invalid listening URL: %s", url));
  9572. return false;
  9573. }
  9574. return true;
  9575. }
  9576. static void write_conn(struct mg_connection *c) {
  9577. long len = c->is_tls ? mg_tls_send(c, c->send.buf, c->send.len)
  9578. : mg_io_send(c, c->send.buf, c->send.len);
  9579. // TODO(): mg_tls_send() may return 0 forever on steady OOM
  9580. if (len == MG_IO_ERR) {
  9581. mg_error(c, "tx err");
  9582. } else if (len > 0) {
  9583. mg_iobuf_del(&c->send, 0, (size_t) len);
  9584. mg_call(c, MG_EV_WRITE, &len);
  9585. }
  9586. }
  9587. static void init_closure(struct mg_connection *c) {
  9588. struct connstate *s = (struct connstate *) (c + 1);
  9589. if (c->is_udp == false && c->is_listening == false &&
  9590. c->is_connecting == false) { // For TCP conns,
  9591. tx_tcp(c->mgr->ifp, s->mac, &c->loc, &c->rem, c->dscp, TH_FIN | TH_ACK,
  9592. mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
  9593. settmout(c, MIP_TTYPE_FIN);
  9594. }
  9595. }
  9596. static void close_conn(struct mg_connection *c) {
  9597. struct connstate *s = (struct connstate *) (c + 1);
  9598. mg_close_conn(c);
  9599. (void) s;
  9600. }
  9601. static bool can_write(struct mg_connection *c) {
  9602. return c->is_connecting == 0 && c->is_resolving == 0 && c->send.len > 0 &&
  9603. c->is_tls_hs == 0 && c->is_arplooking == 0;
  9604. }
  9605. void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
  9606. struct mg_connection *c, *tmp;
  9607. uint64_t now = mg_millis();
  9608. mg_timer_poll(&mgr->timers, now);
  9609. mg_ota_poll(mgr);
  9610. if (mgr->ifp == NULL || mgr->ifp->driver == NULL) return;
  9611. mg_tcpip_poll(mgr->ifp, now);
  9612. for (c = mgr->conns; c != NULL; c = tmp) {
  9613. struct connstate *s = (struct connstate *) (c + 1);
  9614. bool is_tls = c->is_tls && !c->is_resolving && !c->is_arplooking &&
  9615. !c->is_listening && !c->is_connecting;
  9616. tmp = c->next;
  9617. mg_call(c, MG_EV_POLL, &now);
  9618. MG_VERBOSE(("%lu .. %c%c%c%c%c %lu %lu", c->id, c->is_tls ? 'T' : 't',
  9619. c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
  9620. c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c',
  9621. mg_tls_pending(c), c->rtls.len));
  9622. // order is important, TLS conn close with > 1 record in buffer (below)
  9623. if (is_tls && (c->rtls.len > 0 || mg_tls_pending(c) > 0))
  9624. c->is_tls_hs ? mg_tls_handshake(c) : handle_tls_recv(c);
  9625. if (can_write(c)) write_conn(c);
  9626. if (is_tls && c->send.len == 0) mg_tls_flush(c);
  9627. if (c->is_draining && c->send.len == 0 && s->ttype != MIP_TTYPE_FIN)
  9628. init_closure(c);
  9629. // For non-TLS, close immediately upon completing the 3-way closure
  9630. // For TLS, handle any pending data (above) until MIP_TTYPE_FIN expires
  9631. if (s->twclosure &&
  9632. (!c->is_tls || (c->rtls.len == 0 && mg_tls_pending(c) == 0)))
  9633. c->is_closing = 1;
  9634. if (c->is_closing) close_conn(c);
  9635. }
  9636. (void) ms;
  9637. }
  9638. bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
  9639. struct mg_tcpip_if *ifp = c->mgr->ifp;
  9640. bool res = false;
  9641. if (!c->loc.is_ip6 && (ifp->ip == 0 || ifp->state != MG_TCPIP_STATE_READY)) {
  9642. mg_error(c, "net down");
  9643. #if MG_ENABLE_IPV6
  9644. } else if (c->loc.is_ip6 && ifp->state6 != MG_TCPIP_STATE_READY) {
  9645. mg_error(c, "net down");
  9646. #endif
  9647. } else if (c->is_udp && (c->is_arplooking || c->is_resolving)) {
  9648. // Fail to send, no target MAC or IP
  9649. MG_VERBOSE(("still resolving..."));
  9650. } else if (c->is_udp) {
  9651. len = trim_len(c, len); // Trimming length if necessary
  9652. res = udp_send(c, buf, len);
  9653. } else {
  9654. res = len == 0 || mg_iobuf_add(&c->send, c->send.len, buf, len) > 0;
  9655. // returning 0 means an OOM condition (iobuf couldn't resize), yet this is
  9656. // so far recoverable, let the caller decide
  9657. }
  9658. return res;
  9659. }
  9660. uint8_t mcast_addr[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb};
  9661. void mg_multicast_add(struct mg_connection *c, char *ip) {
  9662. (void) ip; // ip4/6_mcastmac(mcast_mac, &ip); ipv6 param
  9663. // TODO(): actual IP -> MAC; check database, update
  9664. c->mgr->ifp->update_mac_hash_table = true; // mark dirty
  9665. }
  9666. bool mg_dnsc_init(struct mg_mgr *mgr, struct mg_dns *dnsc);
  9667. static void setdns4(struct mg_tcpip_if *ifp, uint32_t *ip) {
  9668. struct mg_dns *dnsc;
  9669. mg_free(ifp->dns4_url);
  9670. ifp->dns4_url = mg_mprintf("udp://%M:53", mg_print_ip4, ip);
  9671. dnsc = &ifp->mgr->dns4;
  9672. dnsc->url = (const char *) ifp->dns4_url;
  9673. MG_DEBUG(("Set DNS URL to %s", dnsc->url));
  9674. if (ifp->mgr->use_dns6) return;
  9675. if (dnsc->c != NULL) mg_close_conn(dnsc->c);
  9676. if (!mg_dnsc_init(ifp->mgr, dnsc)) // create DNS connection
  9677. MG_ERROR(("DNS connection creation failed"));
  9678. }
  9679. void mg_tcpip_mapip(struct mg_connection *c, struct mg_addr *ip) {
  9680. struct connstate *s = (struct connstate *) (c + 1);
  9681. uint8_t *l2addr = tcpip_mapip(c->mgr->ifp, ip);
  9682. if (l2addr == NULL) return;
  9683. memcpy(s->mac, l2addr, sizeof(s->mac));
  9684. }
  9685. #endif // MG_ENABLE_TCPIP
  9686. #ifdef MG_ENABLE_LINES
  9687. #line 1 "src/ota.c"
  9688. #endif
  9689. #ifndef MG_OTA_MAX_URL_LEN
  9690. #define MG_OTA_MAX_URL_LEN 256
  9691. #endif
  9692. // Scannable version tag embedded in every firmware binary, for server-side
  9693. // version extraction. The version string starts after the "MG_VERSION:" prefix.
  9694. static const char s_fw_version[] = "MG_VERSION:" MG_OTA_FIRMWARE_VERSION;
  9695. static bool s_autocommit_ok; // True after OTA server confirms "same version"
  9696. static struct mg_ota_state {
  9697. char json_url[MG_OTA_MAX_URL_LEN];
  9698. char url[MG_OTA_MAX_URL_LEN];
  9699. size_t size;
  9700. uint8_t sha256[32];
  9701. void (*fn)(const char *error_message);
  9702. } *s_ota;
  9703. static void s_firmware_fn(struct mg_connection *c, int ev, void *ev_data);
  9704. static bool s_tls_init(struct mg_connection *c, const char *url) {
  9705. struct mg_tls_opts opts;
  9706. memset(&opts, 0, sizeof(opts));
  9707. opts.ca = mg_str(MG_OTA_TLS_CA);
  9708. opts.name = mg_url_host(url);
  9709. if (opts.ca.len == 0) {
  9710. mg_error(c, "MG_OTA_TLS_CA is not configured");
  9711. } else {
  9712. mg_tls_init(c, &opts);
  9713. }
  9714. return c->is_tls_hs != 0 && !c->is_closing;
  9715. }
  9716. #if MG_ENABLE_CUSTOM_DEVICE_ID
  9717. #else
  9718. void mg_ota_device_id(char *buf, size_t len) {
  9719. #if defined(UID_BASE) && \
  9720. (defined(__SYSTEM_STM32F4XX_H) || defined(__SYSTEM_STM32F7XX_H) || \
  9721. defined(SYSTEM_STM32H5XX_H) || defined(SYSTEM_STM32H7XX_H) || \
  9722. defined(SYSTEM_STM32N6XX_H) || defined(SYSTEM_STM32U5XX_H))
  9723. uint32_t *p = (uint32_t *) UID_BASE;
  9724. mg_snprintf(buf, len, "stm32_%08x%08x%08x", p[0], p[1], p[2]);
  9725. #elif MG_ARCH == MG_ARCH_PICOSDK
  9726. pico_unique_board_id_t x = {0};
  9727. pico_get_unique_board_id(&x);
  9728. mg_snprintf(buf, len, "rp_%02x%02x%02x%02x%02x%02x%02x%02x", x.id[0], x.id[1],
  9729. x.id[2], x.id[3], x.id[4], x.id[5], x.id[6], x.id[7]);
  9730. #elif defined(OCOTP_BASE) && OCOTP_BASE == 0x401F4000u
  9731. mg_snprintf(buf, len, "rt10xx_%08x%08x", OCOTP->CFG0, OCOTP->CFG1);
  9732. #elif defined(OCOTP_BASE) && OCOTP_BASE == 0x40CAC000u
  9733. mg_snprintf(buf, len, "rt11xx_%08x%08x", OCOTP->FUSEN[16].FUSE,
  9734. OCOTP->FUSEN[17].FUSE);
  9735. #elif MG_ARCH == MG_ARCH_ESP32
  9736. uint8_t mac[6] = {0};
  9737. esp_efuse_mac_get_default(mac);
  9738. mg_snprintf(buf, len, "esp32_%02x%02x%02x%02x%02x%02x", mac[0], mac[1],
  9739. mac[2], mac[3], mac[4], mac[5]);
  9740. #else
  9741. mg_snprintf(buf, len, "%d", 0);
  9742. #endif
  9743. }
  9744. #endif
  9745. static void s_version_fn(struct mg_connection *c, int ev, void *ev_data) {
  9746. uint64_t expiration = *(uint64_t *) c->data;
  9747. if (s_ota == NULL) {
  9748. c->fn = NULL;
  9749. c->is_closing = 1;
  9750. return;
  9751. }
  9752. if (ev == MG_EV_POLL) {
  9753. if (mg_millis() > expiration) mg_error(c, "Metadata timeout");
  9754. } else if (ev == MG_EV_CONNECT) {
  9755. char id[40];
  9756. struct mg_str host = mg_url_host(s_ota->json_url);
  9757. const char *uri = mg_url_uri(s_ota->json_url);
  9758. const char *sep = strchr(uri, '?') == NULL ? "?" : "&";
  9759. if (mg_url_is_ssl(s_ota->json_url)) {
  9760. if (!s_tls_init(c, s_ota->json_url)) return;
  9761. }
  9762. mg_ota_device_id(id, sizeof(id));
  9763. id[sizeof(id) - 1] = '\0';
  9764. mg_printf(
  9765. c,
  9766. "GET %s%sarch=%d&version=%s&id=%s&interval=%d&boot=%d HTTP/1.1\r\n"
  9767. "Host: %.*s\r\n"
  9768. "Connection: close\r\n\r\n",
  9769. uri, sep, MG_ARCH, s_fw_version + 11, id, MG_OTA_PULL_INTERVAL_SECONDS,
  9770. MG_OTA_STATE_GET(), host.len, host.buf);
  9771. } else if (ev == MG_EV_HTTP_MSG) {
  9772. struct mg_http_message *hm = (struct mg_http_message *) ev_data;
  9773. char version[MG_OTA_MAX_VERSION_LEN];
  9774. double result;
  9775. MG_DEBUG(("Got metadata: %.*s", hm->body.len, hm->body.buf));
  9776. if (mg_http_status(hm) != 200 || mg_json_get(hm->body, "$", NULL) != 0 ||
  9777. !mg_json_unescape(hm->body, "$.version", version, sizeof(version)) ||
  9778. !mg_json_unescape(hm->body, "$.url", s_ota->url, sizeof(s_ota->url)) ||
  9779. !mg_json_get_num(hm->body, "$.size", &result) || result <= 0) {
  9780. char buf[100];
  9781. mg_snprintf(buf, sizeof(buf), "Bad metadata: %.*s", hm->body.len,
  9782. hm->body.buf);
  9783. s_ota->fn(buf);
  9784. mg_free(s_ota);
  9785. s_ota = NULL;
  9786. } else if (strcmp(version, s_fw_version + 11) == 0) {
  9787. s_autocommit_ok = true;
  9788. s_ota->fn("Same version");
  9789. mg_free(s_ota);
  9790. s_ota = NULL;
  9791. } else {
  9792. struct mg_connection *fc;
  9793. s_ota->size = (size_t) result;
  9794. // TODO (robertc2000): parse and validate sha256
  9795. MG_DEBUG(("Firmware version: %s, url: %s, size: %ld", version, s_ota->url,
  9796. s_ota->size));
  9797. fc = mg_http_connect(c->mgr, s_ota->url, s_firmware_fn, NULL);
  9798. if (fc == NULL) {
  9799. s_ota->fn("Failed to connect");
  9800. mg_free(s_ota);
  9801. s_ota = NULL;
  9802. } else {
  9803. *(uint64_t *) fc->data = mg_millis() + 5 * 1000; // Set expiration
  9804. }
  9805. }
  9806. c->is_closing = 1;
  9807. } else if (ev == MG_EV_ERROR) {
  9808. s_ota->fn((char *) ev_data);
  9809. mg_free(s_ota);
  9810. s_ota = NULL;
  9811. }
  9812. }
  9813. static void status_fn(const char *errmsg) {
  9814. if (errmsg) MG_ERROR(("OTA failed: %s", errmsg));
  9815. }
  9816. static void status_fn_2(struct mg_connection *c, const char *errmsg) {
  9817. if (s_ota) s_ota->fn(errmsg);
  9818. mg_free(s_ota);
  9819. s_ota = NULL;
  9820. mg_http_reply(c, errmsg ? 500 : 200, "", "%s\n", errmsg ? errmsg : "ok");
  9821. }
  9822. static void s_firmware_fn(struct mg_connection *c, int ev, void *ev_data) {
  9823. uint64_t expiration = *(uint64_t *) c->data;
  9824. if (s_ota == NULL) {
  9825. c->fn = NULL;
  9826. c->is_closing = 1;
  9827. return;
  9828. }
  9829. if (ev == MG_EV_POLL) {
  9830. if (mg_millis() > expiration) mg_error(c, "OTA timeout");
  9831. } else if (ev == MG_EV_CONNECT) {
  9832. struct mg_str host = mg_url_host(s_ota->url);
  9833. if (mg_url_is_ssl(s_ota->url)) {
  9834. if (!s_tls_init(c, s_ota->url)) return;
  9835. }
  9836. mg_printf(c,
  9837. "GET %s HTTP/1.1\r\n"
  9838. "Host: %.*s\r\n"
  9839. "Connection: close\r\n\r\n",
  9840. mg_url_uri(s_ota->url), (int) host.len, host.buf);
  9841. *(uint64_t *) c->data = mg_millis() + 300 * 1000; // Set expiration
  9842. } else if (ev == MG_EV_HTTP_HDRS) {
  9843. struct mg_http_message *hm = (struct mg_http_message *) ev_data;
  9844. int status = mg_http_status(hm);
  9845. if (status != 200 || hm->body.len != s_ota->size) {
  9846. mg_error(c, "Bad HTTP response: status %d, size %lu vs %lu", status,
  9847. (unsigned long) hm->body.len, (unsigned long) s_ota->size);
  9848. } else {
  9849. MG_DEBUG(("Beginning OTA (%lu bytes)", (unsigned long) s_ota->size));
  9850. mg_http_start_ota(c, hm, status_fn_2);
  9851. }
  9852. } else if (ev == MG_EV_ERROR) {
  9853. s_ota->fn((char *) ev_data);
  9854. mg_free(s_ota);
  9855. s_ota = NULL;
  9856. }
  9857. }
  9858. void mg_ota_url_check(struct mg_mgr *mgr, const char *json_url,
  9859. void (*fn)(const char *error_message)) {
  9860. if (fn == NULL) fn = status_fn;
  9861. if (s_ota != NULL) {
  9862. fn("OTA already in progress");
  9863. } else if ((s_ota = (struct mg_ota_state *) mg_calloc(1, sizeof(*s_ota))) ==
  9864. NULL) {
  9865. fn("Out of memory");
  9866. } else {
  9867. struct mg_connection *c;
  9868. mg_snprintf(s_ota->json_url, sizeof(s_ota->json_url), "%s", json_url);
  9869. MG_DEBUG(("Connecting to %s", json_url));
  9870. c = mg_http_connect(mgr, s_ota->json_url, s_version_fn, NULL);
  9871. if (c == NULL) {
  9872. mg_free(s_ota);
  9873. s_ota = NULL;
  9874. fn("Failed to connect");
  9875. } else {
  9876. s_ota->fn = fn;
  9877. *(uint64_t *) c->data = mg_millis() + 5 * 1000; // Set expiration
  9878. }
  9879. }
  9880. }
  9881. void mg_ota_poll(struct mg_mgr *mgr) {
  9882. static uint64_t t = 5000; // Fire first time 5 sec after boot
  9883. static uint64_t feed_timer; // Advances 500ms per tick; tracks elapsed time
  9884. if (MG_OTA_STATE_GET() == MG_OTA_FAILED &&
  9885. mg_timer_expired(&feed_timer, 500, mg_millis())) {
  9886. if (feed_timer < (uint64_t) MG_OTA_ROLLBACK_TIMEOUT_SECONDS * 1000) {
  9887. MG_OTA_ROLLBACK_TIMER_FEED(); // Feed watchdog every 500ms
  9888. } else if (s_autocommit_ok) {
  9889. MG_INFO(("Auto-committing firmware"));
  9890. MG_OTA_STATE_SET(MG_OTA_CONFIRMED); // Stop feeding → IWDG resets cleanly
  9891. } else {
  9892. MG_INFO(("No commit confirmation, rolling back"));
  9893. // Stop feeding → IWDG fires → resets into MG_OTA_FAILED → rollback
  9894. }
  9895. }
  9896. if (MG_OTA_URL != NULL &&
  9897. mg_timer_expired(&t, MG_OTA_PULL_INTERVAL_SECONDS * 1000, mg_millis())) {
  9898. mg_ota_url_check(mgr, MG_OTA_URL, MG_OTA_STATUS_FN);
  9899. }
  9900. }
  9901. #ifdef MG_ENABLE_LINES
  9902. #line 1 "src/ota_ch32v307.c"
  9903. #endif
  9904. #if MG_OTA == MG_OTA_CH32V307
  9905. // RM: https://www.wch-ic.com/downloads/CH32FV2x_V3xRM_PDF.html
  9906. static bool mg_ch32v307_write(void *, const void *, size_t);
  9907. static bool mg_ch32v307_swap(void);
  9908. static struct mg_flash s_mg_flash_ch32v307 = {
  9909. (void *) 0x08000000, // Start
  9910. 480 * 1024, // Size, first 320k is 0-wait
  9911. 4 * 1024, // Sector size, 4k
  9912. 4, // Align, 32 bit
  9913. mg_ch32v307_write,
  9914. mg_ch32v307_swap,
  9915. };
  9916. #define FLASH_BASE 0x40022000
  9917. #define FLASH_ACTLR (FLASH_BASE + 0)
  9918. #define FLASH_KEYR (FLASH_BASE + 4)
  9919. #define FLASH_OBKEYR (FLASH_BASE + 8)
  9920. #define FLASH_STATR (FLASH_BASE + 12)
  9921. #define FLASH_CTLR (FLASH_BASE + 16)
  9922. #define FLASH_ADDR (FLASH_BASE + 20)
  9923. #define FLASH_OBR (FLASH_BASE + 28)
  9924. #define FLASH_WPR (FLASH_BASE + 32)
  9925. MG_IRAM static void flash_unlock(void) {
  9926. static bool unlocked;
  9927. if (unlocked == false) {
  9928. MG_REG(FLASH_KEYR) = 0x45670123;
  9929. MG_REG(FLASH_KEYR) = 0xcdef89ab;
  9930. unlocked = true;
  9931. }
  9932. }
  9933. MG_IRAM static void flash_wait(void) {
  9934. while (MG_REG(FLASH_STATR) & MG_BIT(0)) (void) 0;
  9935. }
  9936. MG_IRAM static void mg_ch32v307_erase(void *addr) {
  9937. // MG_INFO(("%p", addr));
  9938. flash_unlock();
  9939. flash_wait();
  9940. MG_REG(FLASH_ADDR) = (uint32_t) addr;
  9941. MG_REG(FLASH_CTLR) |= MG_BIT(1) | MG_BIT(6); // PER | STRT;
  9942. flash_wait();
  9943. }
  9944. MG_IRAM static bool is_page_boundary(const void *addr) {
  9945. uint32_t val = (uint32_t) addr;
  9946. return (val & (s_mg_flash_ch32v307.secsz - 1)) == 0;
  9947. }
  9948. MG_IRAM static bool mg_ch32v307_write(void *addr, const void *buf, size_t len) {
  9949. // MG_INFO(("%p %p %lu", addr, buf, len));
  9950. // mg_hexdump(buf, len);
  9951. flash_unlock();
  9952. const uint16_t *src = (uint16_t *) buf, *end = &src[len / 2];
  9953. uint16_t *dst = (uint16_t *) addr;
  9954. MG_REG(FLASH_CTLR) |= MG_BIT(0); // Set PG
  9955. // MG_INFO(("CTLR: %#lx", MG_REG(FLASH_CTLR)));
  9956. while (src < end) {
  9957. if (is_page_boundary(dst)) mg_ch32v307_erase(dst);
  9958. *dst++ = *src++;
  9959. flash_wait();
  9960. }
  9961. MG_REG(FLASH_CTLR) &= ~MG_BIT(0); // Clear PG
  9962. return true;
  9963. }
  9964. MG_IRAM bool mg_ch32v307_swap(void) {
  9965. return true;
  9966. }
  9967. // just overwrite instead of swap
  9968. MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss) {
  9969. // no stdlib calls here
  9970. for (size_t ofs = 0; ofs < s; ofs += ss) {
  9971. mg_ch32v307_write(p1 + ofs, p2 + ofs, ss);
  9972. }
  9973. *((volatile uint32_t *) 0xbeef0000) |= 1U << 7; // NVIC_SystemReset()
  9974. }
  9975. bool mg_ota_begin(size_t new_firmware_size) {
  9976. return mg_ota_flash_begin(new_firmware_size, &s_mg_flash_ch32v307);
  9977. }
  9978. bool mg_ota_write(const void *buf, size_t len) {
  9979. return mg_ota_flash_write(buf, len, &s_mg_flash_ch32v307);
  9980. }
  9981. bool mg_ota_end(void) {
  9982. if (mg_ota_flash_end(&s_mg_flash_ch32v307)) {
  9983. // Swap partitions. Pray power does not go away
  9984. MG_INFO(("Swapping partitions, size %u (%u sectors)",
  9985. s_mg_flash_ch32v307.size,
  9986. s_mg_flash_ch32v307.size / s_mg_flash_ch32v307.secsz));
  9987. MG_INFO(("Do NOT power off..."));
  9988. mg_log_level = MG_LL_NONE;
  9989. // TODO() disable IRQ, s_flash_irq_disabled = true;
  9990. // Runs in RAM, will reset when finished
  9991. single_bank_swap(
  9992. (char *) s_mg_flash_ch32v307.start,
  9993. (char *) s_mg_flash_ch32v307.start + s_mg_flash_ch32v307.size / 2,
  9994. s_mg_flash_ch32v307.size / 2, s_mg_flash_ch32v307.secsz);
  9995. }
  9996. return false;
  9997. }
  9998. struct mg_flash *mg_flash = &s_mg_flash_ch32v307;
  9999. #endif
  10000. #ifdef MG_ENABLE_LINES
  10001. #line 1 "src/ota_dummy.c"
  10002. #endif
  10003. #if MG_OTA == MG_OTA_NONE
  10004. bool mg_ota_begin(size_t new_firmware_size) {
  10005. (void) new_firmware_size;
  10006. return true;
  10007. }
  10008. bool mg_ota_write(const void *buf, size_t len) {
  10009. (void) buf, (void) len;
  10010. return true;
  10011. }
  10012. bool mg_ota_end(void) {
  10013. return true;
  10014. }
  10015. #endif
  10016. #ifdef MG_ENABLE_LINES
  10017. #line 1 "src/ota_esp32.c"
  10018. #endif
  10019. #if MG_ARCH == MG_ARCH_ESP32 && MG_OTA == MG_OTA_ESP32
  10020. static const esp_partition_t *s_ota_update_partition;
  10021. static esp_ota_handle_t s_ota_update_handle;
  10022. static bool s_ota_success;
  10023. // Those empty macros do nothing, but mark places in the code which could
  10024. // potentially trigger a watchdog reboot due to the log flash erase operation
  10025. #define disable_wdt()
  10026. #define enable_wdt()
  10027. bool mg_ota_begin(size_t new_firmware_size) {
  10028. if (s_ota_update_partition != NULL) {
  10029. MG_ERROR(("Update in progress. Call mg_ota_end() ?"));
  10030. return false;
  10031. } else {
  10032. s_ota_success = false;
  10033. disable_wdt();
  10034. s_ota_update_partition = esp_ota_get_next_update_partition(NULL);
  10035. esp_err_t err = esp_ota_begin(s_ota_update_partition, new_firmware_size,
  10036. &s_ota_update_handle);
  10037. enable_wdt();
  10038. MG_DEBUG(("esp_ota_begin(): %d", err));
  10039. s_ota_success = (err == ESP_OK);
  10040. }
  10041. return s_ota_success;
  10042. }
  10043. bool mg_ota_write(const void *buf, size_t len) {
  10044. disable_wdt();
  10045. esp_err_t err = esp_ota_write(s_ota_update_handle, buf, len);
  10046. enable_wdt();
  10047. MG_INFO(("esp_ota_write(): %d", err));
  10048. s_ota_success = err == ESP_OK;
  10049. return s_ota_success;
  10050. }
  10051. bool mg_ota_end(void) {
  10052. esp_err_t err = esp_ota_end(s_ota_update_handle);
  10053. MG_DEBUG(("esp_ota_end(%p): %d", s_ota_update_handle, err));
  10054. if (s_ota_success && err == ESP_OK) {
  10055. err = esp_ota_set_boot_partition(s_ota_update_partition);
  10056. s_ota_success = (err == ESP_OK);
  10057. }
  10058. MG_DEBUG(("Finished ESP32 OTA, success: %d", s_ota_success));
  10059. s_ota_update_partition = NULL;
  10060. if (s_ota_success) {
  10061. MG_OTA_STATE_SET(MG_OTA_TESTING);
  10062. esp_restart();
  10063. }
  10064. return s_ota_success;
  10065. }
  10066. #endif
  10067. #ifdef MG_ENABLE_LINES
  10068. #line 1 "src/ota_imxrt.c"
  10069. #endif
  10070. #if MG_OTA >= MG_OTA_RT1020 && MG_OTA <= MG_OTA_RT1170
  10071. static bool mg_imxrt_write(void *, const void *, size_t);
  10072. static bool mg_imxrt_swap(void);
  10073. #if MG_OTA <= MG_OTA_RT1060
  10074. #define MG_IMXRT_FLASH_START 0x60000000
  10075. #define FLEXSPI_NOR_INSTANCE 0
  10076. #elif MG_OTA == MG_OTA_RT1064
  10077. #define MG_IMXRT_FLASH_START 0x70000000
  10078. #define FLEXSPI_NOR_INSTANCE 1
  10079. #else // RT1170
  10080. #define MG_IMXRT_FLASH_START 0x30000000
  10081. #define FLEXSPI_NOR_INSTANCE 1
  10082. #endif
  10083. #if MG_OTA == MG_OTA_RT1050
  10084. #define MG_IMXRT_SECTOR_SIZE (256 * 1024)
  10085. #define MG_IMXRT_PAGE_SIZE 512
  10086. #else
  10087. #define MG_IMXRT_SECTOR_SIZE (4 * 1024)
  10088. #define MG_IMXRT_PAGE_SIZE 256
  10089. #endif
  10090. // TODO(): fill at init, support more devices in a dynamic way
  10091. // TODO(): then, check alignment is <= 256, see Wizard's #251
  10092. static struct mg_flash s_mg_flash_imxrt = {
  10093. (void *) MG_IMXRT_FLASH_START, // Start,
  10094. 4 * 1024 * 1024, // Size, 4mb
  10095. MG_IMXRT_SECTOR_SIZE, // Sector size
  10096. MG_IMXRT_PAGE_SIZE, // Align
  10097. mg_imxrt_write,
  10098. mg_imxrt_swap,
  10099. };
  10100. struct mg_flexspi_lut_seq {
  10101. uint8_t seqNum;
  10102. uint8_t seqId;
  10103. uint16_t reserved;
  10104. };
  10105. struct mg_flexspi_mem_config {
  10106. uint32_t tag;
  10107. uint32_t version;
  10108. uint32_t reserved0;
  10109. uint8_t readSampleClkSrc;
  10110. uint8_t csHoldTime;
  10111. uint8_t csSetupTime;
  10112. uint8_t columnAddressWidth;
  10113. uint8_t deviceModeCfgEnable;
  10114. uint8_t deviceModeType;
  10115. uint16_t waitTimeCfgCommands;
  10116. struct mg_flexspi_lut_seq deviceModeSeq;
  10117. uint32_t deviceModeArg;
  10118. uint8_t configCmdEnable;
  10119. uint8_t configModeType[3];
  10120. struct mg_flexspi_lut_seq configCmdSeqs[3];
  10121. uint32_t reserved1;
  10122. uint32_t configCmdArgs[3];
  10123. uint32_t reserved2;
  10124. uint32_t controllerMiscOption;
  10125. uint8_t deviceType;
  10126. uint8_t sflashPadType;
  10127. uint8_t serialClkFreq;
  10128. uint8_t lutCustomSeqEnable;
  10129. uint32_t reserved3[2];
  10130. uint32_t sflashA1Size;
  10131. uint32_t sflashA2Size;
  10132. uint32_t sflashB1Size;
  10133. uint32_t sflashB2Size;
  10134. uint32_t csPadSettingOverride;
  10135. uint32_t sclkPadSettingOverride;
  10136. uint32_t dataPadSettingOverride;
  10137. uint32_t dqsPadSettingOverride;
  10138. uint32_t timeoutInMs;
  10139. uint32_t commandInterval;
  10140. uint16_t dataValidTime[2];
  10141. uint16_t busyOffset;
  10142. uint16_t busyBitPolarity;
  10143. uint32_t lookupTable[64];
  10144. struct mg_flexspi_lut_seq lutCustomSeq[12];
  10145. uint32_t reserved4[4];
  10146. };
  10147. struct mg_flexspi_nor_config {
  10148. struct mg_flexspi_mem_config memConfig;
  10149. uint32_t pageSize;
  10150. uint32_t sectorSize;
  10151. uint8_t ipcmdSerialClkFreq;
  10152. uint8_t isUniformBlockSize;
  10153. uint8_t reserved0[2];
  10154. uint8_t serialNorType;
  10155. uint8_t needExitNoCmdMode;
  10156. uint8_t halfClkForNonReadCmd;
  10157. uint8_t needRestoreNoCmdMode;
  10158. uint32_t blockSize;
  10159. uint32_t reserve2[11];
  10160. };
  10161. /* FLEXSPI memory config block related defintions */
  10162. #define MG_FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian
  10163. #define MG_FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0
  10164. #define MG_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
  10165. (MG_FLEXSPI_LUT_OPERAND0(op0) | MG_FLEXSPI_LUT_NUM_PADS0(pad0) | \
  10166. MG_FLEXSPI_LUT_OPCODE0(cmd0) | MG_FLEXSPI_LUT_OPERAND1(op1) | \
  10167. MG_FLEXSPI_LUT_NUM_PADS1(pad1) | MG_FLEXSPI_LUT_OPCODE1(cmd1))
  10168. #define MG_CMD_SDR 0x01
  10169. #define MG_CMD_DDR 0x21
  10170. #define MG_DUMMY_SDR 0x0C
  10171. #define MG_DUMMY_DDR 0x2C
  10172. #define MG_DUMMY_RWDS_DDR 0x2D
  10173. #define MG_RADDR_SDR 0x02
  10174. #define MG_RADDR_DDR 0x22
  10175. #define MG_CADDR_DDR 0x23
  10176. #define MG_READ_SDR 0x09
  10177. #define MG_READ_DDR 0x29
  10178. #define MG_WRITE_SDR 0x08
  10179. #define MG_WRITE_DDR 0x28
  10180. #define MG_STOP 0
  10181. #define MG_FLEXSPI_1PAD 0
  10182. #define MG_FLEXSPI_2PAD 1
  10183. #define MG_FLEXSPI_4PAD 2
  10184. #define MG_FLEXSPI_8PAD 3
  10185. #define MG_FLEXSPI_QSPI_LUT \
  10186. { \
  10187. [0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0xEB, MG_RADDR_SDR, \
  10188. MG_FLEXSPI_4PAD, 0x18), \
  10189. [1] = MG_FLEXSPI_LUT_SEQ(MG_DUMMY_SDR, MG_FLEXSPI_4PAD, 0x06, MG_READ_SDR, \
  10190. MG_FLEXSPI_4PAD, 0x04), \
  10191. [4 * 1 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x05, \
  10192. MG_READ_SDR, MG_FLEXSPI_1PAD, 0x04), \
  10193. [4 * 3 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x06, \
  10194. MG_STOP, MG_FLEXSPI_1PAD, 0x0), \
  10195. [4 * 5 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x20, \
  10196. MG_RADDR_SDR, MG_FLEXSPI_1PAD, 0x18), \
  10197. [4 * 8 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0xD8, \
  10198. MG_RADDR_SDR, MG_FLEXSPI_1PAD, 0x18), \
  10199. [4 * 9 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x02, \
  10200. MG_RADDR_SDR, MG_FLEXSPI_1PAD, 0x18), \
  10201. [4 * 9 + 1] = MG_FLEXSPI_LUT_SEQ(MG_WRITE_SDR, MG_FLEXSPI_1PAD, 0x04, \
  10202. MG_STOP, MG_FLEXSPI_1PAD, 0x0), \
  10203. [4 * 11 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x60, \
  10204. MG_STOP, MG_FLEXSPI_1PAD, 0x0), \
  10205. }
  10206. #define MG_FLEXSPI_HYPER_LUT \
  10207. { \
  10208. [0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xA0, MG_RADDR_DDR, \
  10209. MG_FLEXSPI_8PAD, 0x18), \
  10210. [1] = MG_FLEXSPI_LUT_SEQ(MG_CADDR_DDR, MG_FLEXSPI_8PAD, 0x10, \
  10211. MG_DUMMY_DDR, MG_FLEXSPI_8PAD, 0x0C), \
  10212. [2] = MG_FLEXSPI_LUT_SEQ(MG_READ_DDR, MG_FLEXSPI_8PAD, 0x04, MG_STOP, \
  10213. MG_FLEXSPI_1PAD, 0x0), \
  10214. [4 * 1 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10215. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10216. [4 * 1 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10217. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10218. [4 * 1 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10219. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
  10220. [4 * 1 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10221. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x70), \
  10222. [4 * 2 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xA0, \
  10223. MG_RADDR_DDR, MG_FLEXSPI_8PAD, 0x18), \
  10224. [4 * 2 + 1] = \
  10225. MG_FLEXSPI_LUT_SEQ(MG_CADDR_DDR, MG_FLEXSPI_8PAD, 0x10, \
  10226. MG_DUMMY_RWDS_DDR, MG_FLEXSPI_8PAD, 0x0B), \
  10227. [4 * 2 + 2] = MG_FLEXSPI_LUT_SEQ(MG_READ_DDR, MG_FLEXSPI_8PAD, 0x4, \
  10228. MG_STOP, MG_FLEXSPI_1PAD, 0x0), \
  10229. [4 * 3 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10230. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10231. [4 * 3 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10232. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10233. [4 * 3 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10234. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
  10235. [4 * 3 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10236. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10237. [4 * 4 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10238. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10239. [4 * 4 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10240. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
  10241. [4 * 4 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10242. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x02), \
  10243. [4 * 4 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10244. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
  10245. [4 * 5 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10246. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10247. [4 * 5 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10248. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10249. [4 * 5 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10250. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
  10251. [4 * 5 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10252. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x80), \
  10253. [4 * 6 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10254. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10255. [4 * 6 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10256. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10257. [4 * 6 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10258. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
  10259. [4 * 6 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10260. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10261. [4 * 7 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10262. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10263. [4 * 7 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10264. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
  10265. [4 * 7 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10266. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x02), \
  10267. [4 * 7 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10268. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
  10269. [4 * 8 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10270. MG_RADDR_DDR, MG_FLEXSPI_8PAD, 0x18), \
  10271. [4 * 8 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CADDR_DDR, MG_FLEXSPI_8PAD, 0x10, \
  10272. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10273. [4 * 8 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x30, \
  10274. MG_STOP, MG_FLEXSPI_1PAD, 0x0), \
  10275. [4 * 9 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10276. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10277. [4 * 9 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10278. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10279. [4 * 9 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10280. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
  10281. [4 * 9 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10282. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xA0), \
  10283. [4 * 10 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10284. MG_RADDR_DDR, MG_FLEXSPI_8PAD, 0x18), \
  10285. [4 * 10 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CADDR_DDR, MG_FLEXSPI_8PAD, 0x10, \
  10286. MG_WRITE_DDR, MG_FLEXSPI_8PAD, 0x80), \
  10287. [4 * 11 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10288. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10289. [4 * 11 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10290. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10291. [4 * 11 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10292. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
  10293. [4 * 11 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10294. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x80), \
  10295. [4 * 12 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10296. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10297. [4 * 12 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10298. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10299. [4 * 12 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10300. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
  10301. [4 * 12 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10302. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10303. [4 * 13 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10304. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10305. [4 * 13 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10306. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
  10307. [4 * 13 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10308. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x02), \
  10309. [4 * 13 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10310. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
  10311. [4 * 14 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10312. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
  10313. [4 * 14 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10314. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
  10315. [4 * 14 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10316. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
  10317. [4 * 14 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
  10318. MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x10), \
  10319. }
  10320. #define MG_LUT_CUSTOM_SEQ \
  10321. { \
  10322. {.seqNum = 0, .seqId = 0, .reserved = 0}, \
  10323. {.seqNum = 2, .seqId = 1, .reserved = 0}, \
  10324. {.seqNum = 2, .seqId = 3, .reserved = 0}, \
  10325. {.seqNum = 4, .seqId = 5, .reserved = 0}, \
  10326. {.seqNum = 2, .seqId = 9, .reserved = 0}, \
  10327. {.seqNum = 4, .seqId = 11, .reserved = 0}, \
  10328. }
  10329. #define MG_FLEXSPI_LUT_OPERAND0(x) (((uint32_t) (((uint32_t) (x)))) & 0xFFU)
  10330. #define MG_FLEXSPI_LUT_NUM_PADS0(x) \
  10331. (((uint32_t) (((uint32_t) (x)) << 8U)) & 0x300U)
  10332. #define MG_FLEXSPI_LUT_OPCODE0(x) \
  10333. (((uint32_t) (((uint32_t) (x)) << 10U)) & 0xFC00U)
  10334. #define MG_FLEXSPI_LUT_OPERAND1(x) \
  10335. (((uint32_t) (((uint32_t) (x)) << 16U)) & 0xFF0000U)
  10336. #define MG_FLEXSPI_LUT_NUM_PADS1(x) \
  10337. (((uint32_t) (((uint32_t) (x)) << 24U)) & 0x3000000U)
  10338. #define MG_FLEXSPI_LUT_OPCODE1(x) \
  10339. (((uint32_t) (((uint32_t) (x)) << 26U)) & 0xFC000000U)
  10340. #if MG_OTA == MG_OTA_RT1020 || MG_OTA == MG_OTA_RT1050
  10341. // RT102X and RT105x boards support ROM API version 1.4
  10342. struct mg_flexspi_nor_driver_interface {
  10343. uint32_t version;
  10344. int (*init)(uint32_t instance, struct mg_flexspi_nor_config *config);
  10345. int (*program)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10346. uint32_t dst_addr, const uint32_t *src);
  10347. uint32_t reserved;
  10348. int (*erase)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10349. uint32_t start, uint32_t lengthInBytes);
  10350. uint32_t reserved2;
  10351. int (*update_lut)(uint32_t instance, uint32_t seqIndex,
  10352. const uint32_t *lutBase, uint32_t seqNumber);
  10353. int (*xfer)(uint32_t instance, char *xfer);
  10354. void (*clear_cache)(uint32_t instance);
  10355. };
  10356. #elif MG_OTA <= MG_OTA_RT1064
  10357. // RT104x and RT106x support ROM API version 1.5
  10358. struct mg_flexspi_nor_driver_interface {
  10359. uint32_t version;
  10360. int (*init)(uint32_t instance, struct mg_flexspi_nor_config *config);
  10361. int (*program)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10362. uint32_t dst_addr, const uint32_t *src);
  10363. int (*erase_all)(uint32_t instance, struct mg_flexspi_nor_config *config);
  10364. int (*erase)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10365. uint32_t start, uint32_t lengthInBytes);
  10366. int (*read)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10367. uint32_t *dst, uint32_t addr, uint32_t lengthInBytes);
  10368. void (*clear_cache)(uint32_t instance);
  10369. int (*xfer)(uint32_t instance, char *xfer);
  10370. int (*update_lut)(uint32_t instance, uint32_t seqIndex,
  10371. const uint32_t *lutBase, uint32_t seqNumber);
  10372. int (*get_config)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10373. uint32_t *option);
  10374. };
  10375. #else
  10376. // RT117x support ROM API version 1.7
  10377. struct mg_flexspi_nor_driver_interface {
  10378. uint32_t version;
  10379. int (*init)(uint32_t instance, struct mg_flexspi_nor_config *config);
  10380. int (*program)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10381. uint32_t dst_addr, const uint32_t *src);
  10382. int (*erase_all)(uint32_t instance, struct mg_flexspi_nor_config *config);
  10383. int (*erase)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10384. uint32_t start, uint32_t lengthInBytes);
  10385. int (*read)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10386. uint32_t *dst, uint32_t addr, uint32_t lengthInBytes);
  10387. uint32_t reserved;
  10388. int (*xfer)(uint32_t instance, char *xfer);
  10389. int (*update_lut)(uint32_t instance, uint32_t seqIndex,
  10390. const uint32_t *lutBase, uint32_t seqNumber);
  10391. int (*get_config)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10392. uint32_t *option);
  10393. int (*erase_sector)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10394. uint32_t address);
  10395. int (*erase_block)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10396. uint32_t address);
  10397. void (*hw_reset)(uint32_t instance, uint32_t resetLogic);
  10398. int (*wait_busy)(uint32_t instance, struct mg_flexspi_nor_config *config,
  10399. bool isParallelMode, uint32_t address);
  10400. int (*set_clock_source)(uint32_t instance, uint32_t clockSrc);
  10401. void (*config_clock)(uint32_t instance, uint32_t freqOption,
  10402. uint32_t sampleClkMode);
  10403. };
  10404. #endif
  10405. #if MG_OTA <= MG_OTA_RT1064
  10406. #define MG_FLEXSPI_BASE 0x402A8000
  10407. #define flexspi_nor \
  10408. (*((struct mg_flexspi_nor_driver_interface **) (*(uint32_t *) 0x0020001c + \
  10409. 16)))
  10410. #else
  10411. #define MG_FLEXSPI_BASE 0x400CC000
  10412. #define flexspi_nor \
  10413. (*((struct mg_flexspi_nor_driver_interface **) (*(uint32_t *) 0x0021001c + \
  10414. 12)))
  10415. #endif
  10416. static bool s_flash_irq_disabled;
  10417. MG_IRAM static bool flash_page_start(volatile uint32_t *dst) {
  10418. char *base = (char *) s_mg_flash_imxrt.start,
  10419. *end = base + s_mg_flash_imxrt.size;
  10420. volatile char *p = (char *) dst;
  10421. return p >= base && p < end && ((p - base) % s_mg_flash_imxrt.secsz) == 0;
  10422. }
  10423. #if MG_OTA == MG_OTA_RT1050
  10424. // Configuration for Hyper flash memory
  10425. static struct mg_flexspi_nor_config default_config = {
  10426. .memConfig =
  10427. {
  10428. .tag = MG_FLEXSPI_CFG_BLK_TAG,
  10429. .version = MG_FLEXSPI_CFG_BLK_VERSION,
  10430. .readSampleClkSrc = 3, // ReadSampleClk_LoopbackFromDqsPad
  10431. .csHoldTime = 3,
  10432. .csSetupTime = 3,
  10433. .columnAddressWidth = 3u,
  10434. .controllerMiscOption =
  10435. MG_BIT(6) | MG_BIT(4) | MG_BIT(3) | MG_BIT(0),
  10436. .deviceType = 1, // serial NOR
  10437. .sflashPadType = 8,
  10438. .serialClkFreq = 7, // 133MHz
  10439. .sflashA1Size = 64 * 1024 * 1024,
  10440. .dataValidTime = {15, 0},
  10441. .busyOffset = 15,
  10442. .busyBitPolarity = 1,
  10443. .lutCustomSeqEnable = 0x1,
  10444. .lookupTable = MG_FLEXSPI_HYPER_LUT,
  10445. .lutCustomSeq = MG_LUT_CUSTOM_SEQ,
  10446. },
  10447. .pageSize = 512,
  10448. .sectorSize = 256 * 1024,
  10449. .ipcmdSerialClkFreq = 1,
  10450. .serialNorType = 1u,
  10451. .blockSize = 256 * 1024,
  10452. .isUniformBlockSize = true};
  10453. #else
  10454. // Note: this QSPI configuration works for RTs supporting QSPI
  10455. // Configuration for QSPI memory
  10456. static struct mg_flexspi_nor_config default_config = {
  10457. .memConfig = {.tag = MG_FLEXSPI_CFG_BLK_TAG,
  10458. .version = MG_FLEXSPI_CFG_BLK_VERSION,
  10459. .readSampleClkSrc = 1, // ReadSampleClk_LoopbackFromDqsPad
  10460. .csHoldTime = 3,
  10461. .csSetupTime = 3,
  10462. .controllerMiscOption = MG_BIT(4),
  10463. .deviceType = 1, // serial NOR
  10464. .sflashPadType = 4,
  10465. .serialClkFreq = 7, // 133MHz
  10466. .sflashA1Size = 8 * 1024 * 1024,
  10467. .lookupTable = MG_FLEXSPI_QSPI_LUT},
  10468. .pageSize = 256,
  10469. .sectorSize = 4 * 1024,
  10470. .ipcmdSerialClkFreq = 1,
  10471. .blockSize = 64 * 1024,
  10472. .isUniformBlockSize = false};
  10473. #endif
  10474. // must reside in RAM, as flash will be erased
  10475. MG_IRAM static int flexspi_nor_get_config(
  10476. struct mg_flexspi_nor_config **config) {
  10477. *config = &default_config;
  10478. return 0;
  10479. }
  10480. #if 0
  10481. // ROM API get_config call (ROM version >= 1.5)
  10482. MG_IRAM static int flexspi_nor_get_config(
  10483. struct mg_flexspi_nor_config **config) {
  10484. uint32_t options[] = {0xc0000000, 0x00};
  10485. MG_ARM_DISABLE_IRQ();
  10486. uint32_t status =
  10487. flexspi_nor->get_config(FLEXSPI_NOR_INSTANCE, *config, options);
  10488. if (!s_flash_irq_disabled) {
  10489. MG_ARM_ENABLE_IRQ();
  10490. }
  10491. if (status) {
  10492. MG_ERROR(("Failed to extract flash configuration: status %u", status));
  10493. }
  10494. return status;
  10495. }
  10496. #endif
  10497. MG_IRAM static void mg_spin(volatile uint32_t count) {
  10498. while (count--) (void) 0;
  10499. }
  10500. MG_IRAM static void flash_wait(void) {
  10501. while ((*((volatile uint32_t *) (MG_FLEXSPI_BASE + 0xE0)) & MG_BIT(1)) == 0)
  10502. mg_spin(1);
  10503. }
  10504. MG_IRAM static bool flash_erase(struct mg_flexspi_nor_config *config,
  10505. void *addr) {
  10506. if (flash_page_start(addr) == false) {
  10507. MG_ERROR(("%p is not on a sector boundary", addr));
  10508. return false;
  10509. }
  10510. void *dst = (void *) ((char *) addr - (char *) s_mg_flash_imxrt.start);
  10511. bool ok = (flexspi_nor->erase(FLEXSPI_NOR_INSTANCE, config, (uint32_t) dst,
  10512. s_mg_flash_imxrt.secsz) == 0);
  10513. MG_DEBUG(("Sector starting at %p erasure: %s", addr, ok ? "ok" : "fail"));
  10514. return ok;
  10515. }
  10516. #if 0
  10517. // standalone erase call
  10518. MG_IRAM static bool mg_imxrt_erase(void *addr) {
  10519. struct mg_flexspi_nor_config config, *config_ptr = &config;
  10520. bool ret;
  10521. // Interrupts must be disabled before calls to ROM API in RT1020 and 1060
  10522. MG_ARM_DISABLE_IRQ();
  10523. ret = (flexspi_nor_get_config(&config_ptr) == 0);
  10524. if (ret) ret = flash_erase(config_ptr, addr);
  10525. MG_ARM_ENABLE_IRQ();
  10526. return ret;
  10527. }
  10528. #endif
  10529. MG_IRAM static bool mg_imxrt_write(void *addr, const void *buf, size_t len) {
  10530. struct mg_flexspi_nor_config config, *config_ptr = &config;
  10531. bool ok = false;
  10532. // Interrupts must be disabled before calls to ROM API in RT1020 and 1060
  10533. MG_ARM_DISABLE_IRQ();
  10534. if (flexspi_nor_get_config(&config_ptr) != 0) goto fwxit;
  10535. if ((len % s_mg_flash_imxrt.align) != 0) {
  10536. MG_ERROR(("%lu is not aligned to %lu", len, s_mg_flash_imxrt.align));
  10537. goto fwxit;
  10538. }
  10539. if ((char *) addr < (char *) s_mg_flash_imxrt.start) {
  10540. MG_ERROR(("Invalid flash write address: %p", addr));
  10541. goto fwxit;
  10542. }
  10543. uint32_t *dst = (uint32_t *) addr;
  10544. uint32_t *src = (uint32_t *) buf;
  10545. uint32_t *end = (uint32_t *) ((char *) buf + len);
  10546. ok = true;
  10547. while (ok && src < end) {
  10548. if (flash_page_start(dst) && flash_erase(config_ptr, dst) == false) {
  10549. ok = false;
  10550. break;
  10551. }
  10552. uint32_t status;
  10553. uint32_t dst_ofs = (uint32_t) dst - (uint32_t) s_mg_flash_imxrt.start;
  10554. if ((char *) buf >= (char *) s_mg_flash_imxrt.start) {
  10555. // If we copy from FLASH to FLASH, then we first need to copy the source
  10556. // to RAM
  10557. size_t tmp_buf_size = s_mg_flash_imxrt.align / sizeof(uint32_t);
  10558. uint32_t tmp[tmp_buf_size];
  10559. for (size_t i = 0; i < tmp_buf_size; i++) {
  10560. flash_wait();
  10561. tmp[i] = src[i];
  10562. }
  10563. status = flexspi_nor->program(FLEXSPI_NOR_INSTANCE, config_ptr,
  10564. (uint32_t) dst_ofs, tmp);
  10565. } else {
  10566. status = flexspi_nor->program(FLEXSPI_NOR_INSTANCE, config_ptr,
  10567. (uint32_t) dst_ofs, src);
  10568. }
  10569. src = (uint32_t *) ((char *) src + s_mg_flash_imxrt.align);
  10570. dst = (uint32_t *) ((char *) dst + s_mg_flash_imxrt.align);
  10571. if (status != 0) {
  10572. ok = false;
  10573. }
  10574. }
  10575. MG_DEBUG(("Flash write %lu bytes @ %p: %s.", len, dst, ok ? "ok" : "fail"));
  10576. fwxit:
  10577. if (!s_flash_irq_disabled) MG_ARM_ENABLE_IRQ();
  10578. return ok;
  10579. }
  10580. MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss) {
  10581. char *scratch = p2 + s;
  10582. for (size_t ofs = 0; ofs < s; ofs += ss) {
  10583. MG_OTA_ROLLBACK_TIMER_FEED();
  10584. mg_imxrt_write(scratch, p1 + ofs, ss);
  10585. MG_OTA_ROLLBACK_TIMER_FEED();
  10586. mg_imxrt_write(p1 + ofs, p2 + ofs, ss);
  10587. MG_OTA_ROLLBACK_TIMER_FEED();
  10588. mg_imxrt_write(p2 + ofs, scratch, ss);
  10589. }
  10590. *(volatile unsigned long *) 0xe000ed0c = 0x5fa0004;
  10591. }
  10592. MG_IRAM static bool mg_imxrt_swap(void) {
  10593. size_t ss = s_mg_flash_imxrt.secsz;
  10594. char *p1 = (char *) s_mg_flash_imxrt.start;
  10595. char *p2 = p1 + s_mg_flash_imxrt.size / 2;
  10596. size_t s = s_mg_flash_imxrt.size / 2 - ss;
  10597. MG_INFO(("Swapping partitions, %u bytes", s));
  10598. MG_INFO(("Do NOT power off..."));
  10599. MG_OTA_ROLLBACK_TIMER_FEED();
  10600. mg_log_level = MG_LL_NONE;
  10601. s_flash_irq_disabled = true;
  10602. single_bank_swap(p1, p2, s, ss);
  10603. return true; // unreachable
  10604. }
  10605. bool mg_ota_begin(size_t new_firmware_size) {
  10606. size_t max = s_mg_flash_imxrt.size / 2 - s_mg_flash_imxrt.secsz;
  10607. if (new_firmware_size > max) {
  10608. MG_ERROR(("Firmware %lu too big for single-bank OTA, max %lu",
  10609. new_firmware_size, max));
  10610. return false;
  10611. }
  10612. return mg_ota_flash_begin(new_firmware_size, &s_mg_flash_imxrt);
  10613. }
  10614. bool mg_ota_write(const void *buf, size_t len) {
  10615. return mg_ota_flash_write(buf, len, &s_mg_flash_imxrt);
  10616. }
  10617. bool mg_ota_end(void) {
  10618. mg_ota_flash_end(&s_mg_flash_imxrt);
  10619. return false;
  10620. }
  10621. struct mg_flash *mg_flash = &s_mg_flash_imxrt;
  10622. #endif
  10623. #ifdef MG_ENABLE_LINES
  10624. #line 1 "src/ota_mcxn.c"
  10625. #endif
  10626. #if MG_OTA == MG_OTA_MCXN
  10627. // - Flash phrase: 16 bytes; smallest portion programmed in one operation.
  10628. // - Flash page: 128 bytes; largest portion programmed in one operation.
  10629. // - Flash sector: 8 KB; smallest portion that can be erased in one operation.
  10630. // - Flash API mg_flash_driver->program: "start" and "len" must be page-size
  10631. // aligned; to use 'phrase', FMU register access is needed. Using ROM
  10632. static bool mg_mcxn_write(void *, const void *, size_t);
  10633. static bool mg_mcxn_swap(void);
  10634. static struct mg_flash s_mg_flash_mcxn = {
  10635. (void *) 0, // Start, filled at init
  10636. 0, // Size, filled at init
  10637. 0, // Sector size, filled at init
  10638. 0, // Align, filled at init
  10639. mg_mcxn_write,
  10640. mg_mcxn_swap,
  10641. };
  10642. struct mg_flash_config {
  10643. uint32_t addr;
  10644. uint32_t size;
  10645. uint32_t blocks;
  10646. uint32_t page_size;
  10647. uint32_t sector_size;
  10648. uint32_t ffr[6];
  10649. uint32_t reserved0[5];
  10650. uint32_t *bootctx;
  10651. bool useahb;
  10652. };
  10653. struct mg_flash_driver_interface {
  10654. uint32_t version;
  10655. uint32_t (*init)(struct mg_flash_config *);
  10656. uint32_t (*erase)(struct mg_flash_config *, uint32_t start, uint32_t len,
  10657. uint32_t key);
  10658. uint32_t (*program)(struct mg_flash_config *, uint32_t start, uint8_t *src,
  10659. uint32_t len);
  10660. uint32_t (*verify_erase)(struct mg_flash_config *, uint32_t start,
  10661. uint32_t len);
  10662. uint32_t (*verify_program)(struct mg_flash_config *, uint32_t start,
  10663. uint32_t len, const uint8_t *expected,
  10664. uint32_t *addr, uint32_t *failed);
  10665. uint32_t reserved1[12];
  10666. uint32_t (*read)(struct mg_flash_config *, uint32_t start, uint8_t *dest,
  10667. uint32_t len);
  10668. uint32_t reserved2[4];
  10669. uint32_t (*deinit)(struct mg_flash_config *);
  10670. };
  10671. #define mg_flash_driver \
  10672. ((struct mg_flash_driver_interface *) (*((uint32_t *) 0x1303fc00 + 4)))
  10673. #define MG_MCXN_FLASK_KEY (('k' << 24) | ('e' << 16) | ('f' << 8) | 'l')
  10674. MG_IRAM static bool flash_sector_start(volatile uint32_t *dst) {
  10675. char *base = (char *) s_mg_flash_mcxn.start,
  10676. *end = base + s_mg_flash_mcxn.size;
  10677. volatile char *p = (char *) dst;
  10678. return p >= base && p < end && ((p - base) % s_mg_flash_mcxn.secsz) == 0;
  10679. }
  10680. MG_IRAM static bool flash_erase(struct mg_flash_config *config, void *addr) {
  10681. if (flash_sector_start(addr) == false) {
  10682. MG_ERROR(("%p is not on a sector boundary", addr));
  10683. return false;
  10684. }
  10685. uint32_t dst =
  10686. (uint32_t) addr - (uint32_t) s_mg_flash_mcxn.start; // future-proof
  10687. uint32_t status = mg_flash_driver->erase(config, dst, s_mg_flash_mcxn.secsz,
  10688. MG_MCXN_FLASK_KEY);
  10689. bool ok = (status == 0);
  10690. if (!ok) MG_ERROR(("Flash write error: %lu", status));
  10691. MG_DEBUG(("Sector starting at %p erasure: %s", addr, ok ? "ok" : "fail"));
  10692. return ok;
  10693. }
  10694. #if 0
  10695. // read-while-write, no need to disable IRQs for standalone usage
  10696. MG_IRAM static bool mg_mcxn_erase(void *addr) {
  10697. uint32_t status;
  10698. struct mg_flash_config config;
  10699. if ((status = mg_flash_driver->init(&config)) != 0) {
  10700. MG_ERROR(("Flash driver init error: %lu", status));
  10701. return false;
  10702. }
  10703. bool ok = flash_erase(&config, addr);
  10704. mg_flash_driver->deinit(&config);
  10705. return ok;
  10706. }
  10707. #endif
  10708. MG_IRAM static bool mg_mcxn_swap(void) {
  10709. // TODO(): no devices so far
  10710. return true;
  10711. }
  10712. static bool s_flash_irq_disabled;
  10713. MG_IRAM static bool mg_mcxn_write(void *addr, const void *buf, size_t len) {
  10714. bool ok = false;
  10715. uint32_t status;
  10716. struct mg_flash_config config;
  10717. if ((status = mg_flash_driver->init(&config)) != 0) {
  10718. MG_ERROR(("Flash driver init error: %lu", status));
  10719. return false;
  10720. }
  10721. if ((len % s_mg_flash_mcxn.align) != 0) {
  10722. MG_ERROR(("%lu is not aligned to %lu", len, s_mg_flash_mcxn.align));
  10723. goto fwxit;
  10724. }
  10725. if ((((size_t) addr - (size_t) s_mg_flash_mcxn.start) %
  10726. s_mg_flash_mcxn.align) != 0) {
  10727. MG_ERROR(("%p is not on a page boundary", addr));
  10728. goto fwxit;
  10729. }
  10730. uint32_t *dst = (uint32_t *) addr;
  10731. uint32_t *src = (uint32_t *) buf;
  10732. uint32_t *end = (uint32_t *) ((char *) buf + len);
  10733. ok = true;
  10734. MG_ARM_DISABLE_IRQ();
  10735. while (ok && src < end) {
  10736. if (flash_sector_start(dst) && flash_erase(&config, dst) == false) {
  10737. ok = false;
  10738. break;
  10739. }
  10740. uint32_t dst_ofs = (uint32_t) dst - (uint32_t) s_mg_flash_mcxn.start;
  10741. // assume source is in RAM or in a different bank or read-while-write
  10742. status = mg_flash_driver->program(&config, dst_ofs, (uint8_t *) src,
  10743. s_mg_flash_mcxn.align);
  10744. src = (uint32_t *) ((char *) src + s_mg_flash_mcxn.align);
  10745. dst = (uint32_t *) ((char *) dst + s_mg_flash_mcxn.align);
  10746. if (status != 0) {
  10747. MG_ERROR(("Flash write error: %lu", status));
  10748. ok = false;
  10749. }
  10750. }
  10751. if (!s_flash_irq_disabled) MG_ARM_ENABLE_IRQ();
  10752. MG_DEBUG(("Flash write %lu bytes @ %p: %s.", len, dst, ok ? "ok" : "fail"));
  10753. fwxit:
  10754. mg_flash_driver->deinit(&config);
  10755. return ok;
  10756. }
  10757. // try to swap (honor dual image), otherwise just overwrite
  10758. MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss) {
  10759. char *tmp = mg_calloc(1, ss);
  10760. // no stdlib calls here
  10761. for (size_t ofs = 0; ofs < s; ofs += ss) {
  10762. if (tmp != NULL)
  10763. for (size_t i = 0; i < ss; i++) tmp[i] = p1[ofs + i];
  10764. mg_mcxn_write(p1 + ofs, p2 + ofs, ss);
  10765. if (tmp != NULL) mg_mcxn_write(p2 + ofs, tmp, ss);
  10766. }
  10767. *(volatile unsigned long *) 0xe000ed0c = 0x5fa0004;
  10768. }
  10769. bool mg_ota_begin(size_t new_firmware_size) {
  10770. uint32_t status;
  10771. struct mg_flash_config config;
  10772. if ((status = mg_flash_driver->init(&config)) != 0) {
  10773. MG_ERROR(("Flash driver init error: %lu", status));
  10774. return false;
  10775. }
  10776. s_mg_flash_mcxn.start = (void *) config.addr;
  10777. s_mg_flash_mcxn.size = config.size;
  10778. s_mg_flash_mcxn.secsz = config.sector_size;
  10779. s_mg_flash_mcxn.align = config.page_size;
  10780. mg_flash_driver->deinit(&config);
  10781. MG_DEBUG(
  10782. ("%lu-byte flash @%p, using %lu-byte sectors with %lu-byte-aligned pages",
  10783. s_mg_flash_mcxn.size, s_mg_flash_mcxn.start, s_mg_flash_mcxn.secsz,
  10784. s_mg_flash_mcxn.align));
  10785. return mg_ota_flash_begin(new_firmware_size, &s_mg_flash_mcxn);
  10786. }
  10787. bool mg_ota_write(const void *buf, size_t len) {
  10788. return mg_ota_flash_write(buf, len, &s_mg_flash_mcxn);
  10789. }
  10790. bool mg_ota_end(void) {
  10791. if (mg_ota_flash_end(&s_mg_flash_mcxn)) {
  10792. if (0) { // is_dualbank()
  10793. // TODO(): no devices so far
  10794. *(volatile unsigned long *) 0xe000ed0c = 0x5fa0004;
  10795. } else {
  10796. // Swap partitions. Pray power does not go away
  10797. MG_INFO(("Swapping partitions, size %u (%u sectors)",
  10798. s_mg_flash_mcxn.size,
  10799. s_mg_flash_mcxn.size / s_mg_flash_mcxn.secsz));
  10800. MG_INFO(("Do NOT power off..."));
  10801. mg_log_level = MG_LL_NONE;
  10802. s_flash_irq_disabled = true;
  10803. // Runs in RAM, will reset when finished
  10804. single_bank_swap(
  10805. (char *) s_mg_flash_mcxn.start,
  10806. (char *) s_mg_flash_mcxn.start + s_mg_flash_mcxn.size / 2,
  10807. s_mg_flash_mcxn.size / 2, s_mg_flash_mcxn.secsz);
  10808. }
  10809. }
  10810. return false;
  10811. }
  10812. struct mg_flash *mg_flash = &s_mg_flash_mcxn;
  10813. #endif
  10814. #ifdef MG_ENABLE_LINES
  10815. #line 1 "src/ota_picosdk.c"
  10816. #endif
  10817. #if MG_OTA == MG_OTA_PICOSDK
  10818. // Both RP2040 and RP2350 have no flash, low-level flash access support in
  10819. // bootrom, and high-level support in Pico-SDK (2.0+ for the RP2350)
  10820. // - The RP2350 in RISC-V mode is not tested
  10821. // NOTE(): See OTA design notes
  10822. static bool mg_picosdk_write(void *, const void *, size_t);
  10823. static bool mg_picosdk_swap(void);
  10824. static struct mg_flash s_mg_flash_picosdk = {
  10825. (void *) 0x10000000, // Start; functions handle offset
  10826. #ifdef PICO_FLASH_SIZE_BYTES
  10827. PICO_FLASH_SIZE_BYTES, // Size, from board definitions
  10828. #else
  10829. 0x200000, // Size, guess... is 2M enough ?
  10830. #endif
  10831. FLASH_SECTOR_SIZE, // Sector size, from hardware_flash
  10832. FLASH_PAGE_SIZE, // Align, from hardware_flash
  10833. mg_picosdk_write, mg_picosdk_swap,
  10834. };
  10835. #define MG_MODULO2(x, m) ((x) & ((m) -1))
  10836. static bool __no_inline_not_in_flash_func(flash_sector_start)(
  10837. volatile uint32_t *dst) {
  10838. char *base = (char *) s_mg_flash_picosdk.start,
  10839. *end = base + s_mg_flash_picosdk.size;
  10840. volatile char *p = (char *) dst;
  10841. return p >= base && p < end &&
  10842. MG_MODULO2(p - base, s_mg_flash_picosdk.secsz) == 0;
  10843. }
  10844. static bool __no_inline_not_in_flash_func(flash_erase)(void *addr) {
  10845. if (flash_sector_start(addr) == false) {
  10846. MG_ERROR(("%p is not on a sector boundary", addr));
  10847. return false;
  10848. }
  10849. void *dst = (void *) ((char *) addr - (char *) s_mg_flash_picosdk.start);
  10850. flash_range_erase((uint32_t) dst, s_mg_flash_picosdk.secsz);
  10851. MG_DEBUG(("Sector starting at %p erasure", addr));
  10852. return true;
  10853. }
  10854. static bool s_flash_irq_disabled;
  10855. static bool __no_inline_not_in_flash_func(mg_picosdk_write)(void *addr,
  10856. const void *buf,
  10857. size_t len) {
  10858. if ((len % s_mg_flash_picosdk.align) != 0) {
  10859. MG_ERROR(("%lu is not aligned to %lu", len, s_mg_flash_picosdk.align));
  10860. return false;
  10861. }
  10862. if ((((size_t) addr - (size_t) s_mg_flash_picosdk.start) %
  10863. s_mg_flash_picosdk.align) != 0) {
  10864. MG_ERROR(("%p is not on a page boundary", addr));
  10865. return false;
  10866. }
  10867. uint32_t *dst = (uint32_t *) addr;
  10868. uint32_t *src = (uint32_t *) buf;
  10869. uint32_t *end = (uint32_t *) ((char *) buf + len);
  10870. #ifndef __riscv
  10871. MG_ARM_DISABLE_IRQ();
  10872. #else
  10873. asm volatile("csrrc zero, mstatus, %0" : : "i"(1 << 3) : "memory");
  10874. #endif
  10875. while (src < end) {
  10876. uint32_t dst_ofs = (uint32_t) dst - (uint32_t) s_mg_flash_picosdk.start;
  10877. if (flash_sector_start(dst) && flash_erase(dst) == false) break;
  10878. // flash_range_program() runs in RAM and handles writing up to
  10879. // FLASH_PAGE_SIZE bytes. Source must not be in flash
  10880. flash_range_program((uint32_t) dst_ofs, (uint8_t *) src,
  10881. s_mg_flash_picosdk.align);
  10882. src = (uint32_t *) ((char *) src + s_mg_flash_picosdk.align);
  10883. dst = (uint32_t *) ((char *) dst + s_mg_flash_picosdk.align);
  10884. }
  10885. if (!s_flash_irq_disabled) {
  10886. #ifndef __riscv
  10887. MG_ARM_ENABLE_IRQ();
  10888. #else
  10889. asm volatile("csrrs mstatus, %0" : : "i"(1 << 3) : "memory");
  10890. #endif
  10891. }
  10892. MG_DEBUG(("Flash write %lu bytes @ %p.", len, dst));
  10893. return true;
  10894. }
  10895. // just overwrite instead of swap
  10896. static void __no_inline_not_in_flash_func(single_bank_swap)(char *p1, char *p2,
  10897. size_t s,
  10898. size_t ss) {
  10899. char *tmp_1 = mg_calloc(1, ss); // copy from 1st partition
  10900. if (tmp_1 == NULL) return;
  10901. char *tmp_2 = mg_calloc(1, ss); // copy from 2nd partition
  10902. if (tmp_2 == NULL) return;
  10903. #if PICO_RP2040
  10904. uint32_t xip[256 / sizeof(uint32_t)];
  10905. void *dst_1 = (void *) ((char *) p1 - (char *) s_mg_flash_picosdk.start);
  10906. void *dst_2 = (void *) ((char *) p2- (char *) s_mg_flash_picosdk.start);
  10907. // use SDK function calls to get BootROM function pointers
  10908. rom_connect_internal_flash_fn connect = (rom_connect_internal_flash_fn) rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH);
  10909. rom_flash_exit_xip_fn xit = (rom_flash_exit_xip_fn) rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP);
  10910. rom_flash_range_program_fn program = (rom_flash_range_program_fn) rom_func_lookup(ROM_FUNC_FLASH_RANGE_PROGRAM);
  10911. rom_flash_flush_cache_fn flush = (rom_flash_flush_cache_fn) rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE);
  10912. // no stdlib calls here.
  10913. MG_ARM_DISABLE_IRQ();
  10914. // 2nd bootloader (XIP) is in flash, SDK functions copy it to RAM on entry
  10915. for (size_t i = 0; i < 256 / sizeof(uint32_t); i++)
  10916. xip[i] = ((uint32_t *) (s_mg_flash_picosdk.start))[i];
  10917. // flash has been erased, no XIP to copy. Only BootROM calls possible
  10918. for (uint32_t ofs = 0; ofs < s; ofs += ss) {
  10919. for (size_t i = 0; i < ss; i++) {
  10920. tmp_1[i] = p1[ofs + i];
  10921. tmp_2[i] = p2[ofs + i];
  10922. }
  10923. flash_range_erase((uint32_t) dst_1 + ofs, ss);
  10924. flash_range_erase((uint32_t) dst_2 + ofs, ss);
  10925. __compiler_memory_barrier();
  10926. connect();
  10927. xit();
  10928. program((uint32_t) dst_1 + ofs, tmp_2, ss);
  10929. program((uint32_t) dst_2 + ofs, tmp_1, ss);
  10930. flush();
  10931. ((void (*)(void))((intptr_t) xip + 1))(); // enter XIP again
  10932. }
  10933. *(volatile unsigned long *) 0xe000ed0c = 0x5fa0004; // AIRCR = SYSRESETREQ
  10934. #else
  10935. // RP2350 has BootRAM and copies second bootloader there, SDK uses that copy,
  10936. // It might also be able to take advantage of partition swapping
  10937. rom_reboot_fn reboot = (rom_reboot_fn) rom_func_lookup(ROM_FUNC_REBOOT);
  10938. for (size_t ofs = 0; ofs < s; ofs += ss) {
  10939. for (size_t i = 0; i < ss; i++) {
  10940. tmp_1[i] = p1[ofs + i];
  10941. tmp_2[i] = p2[ofs + i];
  10942. }
  10943. mg_picosdk_write(p1 + ofs, tmp_2, ss);
  10944. mg_picosdk_write(p2 + ofs, tmp_1, ss);
  10945. }
  10946. reboot(BOOT_TYPE_NORMAL | 0x100, 1, 0, 0); // 0x100: NO_RETURN_ON_SUCCESS
  10947. #endif
  10948. }
  10949. static bool __no_inline_not_in_flash_func(mg_picosdk_swap)(void) {
  10950. // TODO(): RP2350 might have some A/B functionality (DS 5.1)
  10951. // Swap partitions. Pray power does not go away
  10952. MG_INFO(("Swapping partitions, size %u (%u sectors)",
  10953. s_mg_flash_picosdk.size,
  10954. s_mg_flash_picosdk.size / s_mg_flash_picosdk.secsz));
  10955. MG_INFO(("Do NOT power off..."));
  10956. mg_log_level = MG_LL_NONE;
  10957. s_flash_irq_disabled = true;
  10958. // Runs in RAM, will reset when finished or return on failure
  10959. single_bank_swap(
  10960. (char *) s_mg_flash_picosdk.start,
  10961. (char *) s_mg_flash_picosdk.start + s_mg_flash_picosdk.size / 2,
  10962. s_mg_flash_picosdk.size / 2, s_mg_flash_picosdk.secsz);
  10963. return false;
  10964. }
  10965. bool mg_ota_begin(size_t new_firmware_size) {
  10966. return mg_ota_flash_begin(new_firmware_size, &s_mg_flash_picosdk);
  10967. }
  10968. bool mg_ota_write(const void *buf, size_t len) {
  10969. return mg_ota_flash_write(buf, len, &s_mg_flash_picosdk);
  10970. }
  10971. bool mg_ota_end(void) {
  10972. if (mg_ota_flash_end(&s_mg_flash_picosdk));
  10973. return false;
  10974. }
  10975. struct mg_flash *mg_flash = &s_mg_flash_picosdk;
  10976. #endif
  10977. #ifdef MG_ENABLE_LINES
  10978. #line 1 "src/ota_rw612.c"
  10979. #endif
  10980. #if MG_OTA == MG_OTA_RW612
  10981. MG_IRAM static bool mg_frdm_write(void *, const void *, size_t);
  10982. static bool mg_frdm_swap(void);
  10983. static struct mg_flash s_mg_flash_frdm = {(void *) 0x08000000, // Start,
  10984. 0x200000, // Size
  10985. 0x1000, // Sector size
  10986. 0x100, // Align
  10987. mg_frdm_write,
  10988. mg_frdm_swap};
  10989. struct mg_flexspi_lut_seq {
  10990. uint8_t seqNum;
  10991. uint8_t seqId;
  10992. uint16_t reserved;
  10993. };
  10994. struct mg_flexspi_mem_config {
  10995. uint32_t tag;
  10996. uint32_t version;
  10997. uint32_t reserved0;
  10998. uint8_t readSampleClkSrc;
  10999. uint8_t csHoldTime;
  11000. uint8_t csSetupTime;
  11001. uint8_t columnAddressWidth;
  11002. uint8_t deviceModeCfgEnable;
  11003. uint8_t deviceModeType;
  11004. uint16_t waitTimeCfgCommands;
  11005. struct mg_flexspi_lut_seq deviceModeSeq;
  11006. uint32_t deviceModeArg;
  11007. uint8_t configCmdEnable;
  11008. uint8_t configModeType[3];
  11009. struct mg_flexspi_lut_seq configCmdSeqs[3];
  11010. uint32_t reserved1;
  11011. uint32_t configCmdArgs[3];
  11012. uint32_t reserved2;
  11013. uint32_t controllerMiscOption;
  11014. uint8_t deviceType;
  11015. uint8_t sflashPadType;
  11016. uint8_t serialClkFreq;
  11017. uint8_t lutCustomSeqEnable;
  11018. uint32_t reserved3[2];
  11019. uint32_t sflashA1Size;
  11020. uint32_t sflashA2Size;
  11021. uint32_t sflashB1Size;
  11022. uint32_t sflashB2Size;
  11023. uint32_t csPadSettingOverride;
  11024. uint32_t sclkPadSettingOverride;
  11025. uint32_t dataPadSettingOverride;
  11026. uint32_t dqsPadSettingOverride;
  11027. uint32_t timeoutInMs;
  11028. uint32_t commandInterval;
  11029. uint16_t dataValidTime[2];
  11030. uint16_t busyOffset;
  11031. uint16_t busyBitPolarity;
  11032. uint32_t lookupTable[64];
  11033. struct mg_flexspi_lut_seq lutCustomSeq[12];
  11034. uint32_t reserved4[4];
  11035. };
  11036. struct mg_flexspi_nor_config {
  11037. struct mg_flexspi_mem_config memConfig;
  11038. uint32_t pageSize;
  11039. uint32_t sectorSize;
  11040. uint8_t ipcmdSerialClkFreq;
  11041. uint8_t isUniformBlockSize;
  11042. uint8_t isDataOrderSwapped;
  11043. uint8_t reserved0[1];
  11044. uint8_t serialNorType;
  11045. uint8_t needExitNoCmdMode;
  11046. uint8_t halfClkForNonReadCmd;
  11047. uint8_t needRestoreNoCmdMode;
  11048. uint32_t blockSize;
  11049. uint32_t flashStateCtx;
  11050. uint32_t reserve2[10];
  11051. };
  11052. struct mg_flexspi_nor_driver_interface {
  11053. uint32_t version;
  11054. uint32_t (*init)(uint32_t instance, struct mg_flexspi_nor_config *config);
  11055. uint32_t (*wait_busy)(uint32_t instance, struct mg_flexspi_nor_config *config,
  11056. uint32_t address, bool keepState);
  11057. uint32_t (*page_program)(uint32_t instance,
  11058. struct mg_flexspi_nor_config *config,
  11059. uint32_t dstAddr, const uint32_t *src,
  11060. bool keepState);
  11061. uint32_t (*erase_all)(uint32_t instance,
  11062. struct mg_flexspi_nor_config *config);
  11063. uint32_t (*erase)(uint32_t instance, struct mg_flexspi_nor_config *config,
  11064. uint32_t start, uint32_t length);
  11065. uint32_t (*erase_sector)(uint32_t instance,
  11066. struct mg_flexspi_nor_config *config,
  11067. uint32_t address);
  11068. uint32_t (*erase_block)(uint32_t instance,
  11069. struct mg_flexspi_nor_config *config,
  11070. uint32_t address);
  11071. uint32_t (*read)(uint32_t instance, struct mg_flexspi_nor_config *config,
  11072. uint32_t *dst, uint32_t start, uint32_t bytes);
  11073. void (*config_clock)(uint32_t instance, uint32_t freqOption,
  11074. uint32_t sampleClkMode);
  11075. uint32_t (*set_clock_source)(uint32_t clockSrc);
  11076. uint32_t (*get_config)(uint32_t instance,
  11077. struct mg_flexspi_nor_config *config,
  11078. uint32_t *option);
  11079. void (*hw_reset)(uint32_t instance, uint32_t reset_logic);
  11080. uint32_t (*xfer)(uint32_t instance, char *xfer);
  11081. uint32_t (*update_lut)(uint32_t instance, uint32_t seqIndex,
  11082. const uint32_t *lutBase, uint32_t numberOfSeq);
  11083. uint32_t (*partial_program)(uint32_t instance,
  11084. struct mg_flexspi_nor_config *config,
  11085. uint32_t dstAddr, const uint32_t *src,
  11086. uint32_t length, bool keepState);
  11087. };
  11088. #define MG_FLEXSPI_CFG_BLK_TAG (0x42464346UL)
  11089. #define MG_FLEXSPI_BASE 0x40134000UL
  11090. #define MG_CMD_SDR 0x01
  11091. #define MG_RADDR_SDR 0x02
  11092. #define MG_WRITE_SDR 0x08
  11093. #define MG_READ_SDR 0x09
  11094. #define MG_DUMMY_SDR 0x0C
  11095. #define MG_STOP_EXE 0
  11096. #define MG_FLEXSPI_1PAD 0
  11097. #define MG_FLEXSPI_4PAD 2
  11098. #define MG_FLEXSPI_LUT_OPERAND0(x) (((x) &0xFF) << 0)
  11099. #define MG_FLEXSPI_LUT_NUM_PADS0(x) (((x) &0x3) << 8)
  11100. #define MG_FLEXSPI_LUT_OPCODE0(x) (((x) &0x3F) << 10)
  11101. #define MG_FLEXSPI_LUT_OPERAND1(x) (((x) &0xFF) << 16)
  11102. #define MG_FLEXSPI_LUT_NUM_PADS1(x) (((x) &0x3) << 24)
  11103. #define MG_FLEXSPI_LUT_OPCODE1(x) (((x) &0x3F) << 26)
  11104. #define MG_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
  11105. (MG_FLEXSPI_LUT_OPERAND0(op0) | MG_FLEXSPI_LUT_NUM_PADS0(pad0) | \
  11106. MG_FLEXSPI_LUT_OPCODE0(cmd0) | MG_FLEXSPI_LUT_OPERAND1(op1) | \
  11107. MG_FLEXSPI_LUT_NUM_PADS1(pad1) | MG_FLEXSPI_LUT_OPCODE1(cmd1))
  11108. struct mg_flexspi_nor_config default_config = {
  11109. .memConfig =
  11110. {
  11111. .tag = MG_FLEXSPI_CFG_BLK_TAG,
  11112. .version = 0,
  11113. .readSampleClkSrc = 1,
  11114. .csHoldTime = 3,
  11115. .csSetupTime = 3,
  11116. .deviceModeCfgEnable = 1,
  11117. .deviceModeSeq = {.seqNum = 1, .seqId = 2},
  11118. .deviceModeArg = 0x0740,
  11119. .configCmdEnable = 0,
  11120. .deviceType = 0x1,
  11121. .sflashPadType = 4,
  11122. .serialClkFreq = 4,
  11123. .sflashA1Size = 0x4000000U,
  11124. .sflashA2Size = 0,
  11125. .sflashB1Size = 0,
  11126. .sflashB2Size = 0,
  11127. .lookupTable =
  11128. {
  11129. [0] =
  11130. MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0xEB,
  11131. MG_RADDR_SDR, MG_FLEXSPI_4PAD, 0x18),
  11132. [1] =
  11133. MG_FLEXSPI_LUT_SEQ(MG_DUMMY_SDR, MG_FLEXSPI_4PAD, 0x06,
  11134. MG_READ_SDR, MG_FLEXSPI_4PAD, 0x04),
  11135. [4 * 1 + 0] =
  11136. MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x05,
  11137. MG_READ_SDR, MG_FLEXSPI_1PAD, 0x04),
  11138. [4 * 2 + 0] =
  11139. MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x01,
  11140. MG_WRITE_SDR, MG_FLEXSPI_1PAD, 0x02),
  11141. [4 * 3 + 0] =
  11142. MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x06,
  11143. MG_STOP_EXE, MG_FLEXSPI_1PAD, 0x00),
  11144. [4 * 5 + 0] =
  11145. MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x20,
  11146. MG_RADDR_SDR, MG_FLEXSPI_1PAD, 0x18),
  11147. [4 * 8 + 0] =
  11148. MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x52,
  11149. MG_RADDR_SDR, MG_FLEXSPI_1PAD, 0x18),
  11150. [4 * 9 + 0] =
  11151. MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x02,
  11152. MG_RADDR_SDR, MG_FLEXSPI_1PAD, 0x18),
  11153. [4 * 9 + 1] =
  11154. MG_FLEXSPI_LUT_SEQ(MG_WRITE_SDR, MG_FLEXSPI_1PAD, 0x00,
  11155. MG_STOP_EXE, MG_FLEXSPI_1PAD, 0x00),
  11156. [4 * 11 + 0] =
  11157. MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x60,
  11158. MG_STOP_EXE, MG_FLEXSPI_1PAD, 0x00),
  11159. },
  11160. },
  11161. .pageSize = 0x100,
  11162. .sectorSize = 0x1000,
  11163. .ipcmdSerialClkFreq = 0,
  11164. .blockSize = 0x8000,
  11165. };
  11166. #define MG_FLEXSPI_NOR_INSTANCE 0
  11167. #define MG_ROMAPI_ADDRESS 0x13030000U
  11168. #define flexspi_nor \
  11169. ((struct mg_flexspi_nor_driver_interface *) (( \
  11170. (uint32_t *) MG_ROMAPI_ADDRESS)[5]))
  11171. MG_IRAM static bool flash_page_start(volatile uint32_t *dst) {
  11172. char *base = (char *) s_mg_flash_frdm.start,
  11173. *end = base + s_mg_flash_frdm.size;
  11174. volatile char *p = (char *) dst;
  11175. return p >= base && p < end && ((p - base) % s_mg_flash_frdm.secsz) == 0;
  11176. }
  11177. MG_IRAM static int flexspi_nor_get_config(
  11178. struct mg_flexspi_nor_config *config) {
  11179. uint32_t option = 0xc0000004;
  11180. return flexspi_nor->get_config(MG_FLEXSPI_NOR_INSTANCE, config, &option);
  11181. }
  11182. MG_IRAM static int flash_init(void) {
  11183. static bool initialized = false;
  11184. if (!initialized) {
  11185. struct mg_flexspi_nor_config config;
  11186. memset(&config, 0, sizeof(config));
  11187. flexspi_nor->set_clock_source(0);
  11188. flexspi_nor->config_clock(MG_FLEXSPI_NOR_INSTANCE, 1, 0);
  11189. if (flexspi_nor->init(MG_FLEXSPI_NOR_INSTANCE, &default_config)) {
  11190. return 1;
  11191. }
  11192. flexspi_nor_get_config(&config);
  11193. if (flexspi_nor->init(MG_FLEXSPI_NOR_INSTANCE, &config)) {
  11194. return 1;
  11195. }
  11196. initialized = true;
  11197. }
  11198. return 0;
  11199. }
  11200. MG_IRAM static bool flash_erase(struct mg_flexspi_nor_config *config,
  11201. void *addr) {
  11202. if (flash_page_start(addr) == false) {
  11203. MG_ERROR(("%p is not on a sector boundary", addr));
  11204. return false;
  11205. }
  11206. void *dst = (void *) ((char *) addr - (char *) s_mg_flash_frdm.start);
  11207. bool ok = (flexspi_nor->erase_sector(MG_FLEXSPI_NOR_INSTANCE, config,
  11208. (uint32_t) dst) == 0);
  11209. MG_INFO(("Sector starting at %p erasure: %s", addr, ok ? "ok" : "fail"));
  11210. return ok;
  11211. }
  11212. MG_IRAM bool mg_frdm_swap(void) {
  11213. return true;
  11214. }
  11215. MG_IRAM static void flash_wait(void) {
  11216. while ((*((volatile uint32_t *) (MG_FLEXSPI_BASE + 0xE0)) & MG_BIT(1)) == 0)
  11217. (void) 0;
  11218. }
  11219. static bool s_flash_irq_disabled;
  11220. MG_IRAM static bool mg_frdm_write(void *addr, const void *buf, size_t len) {
  11221. struct mg_flexspi_nor_config config;
  11222. bool ok = false;
  11223. MG_ARM_DISABLE_IRQ();
  11224. if (flash_init() != 0) goto fwxit;
  11225. if (flexspi_nor_get_config(&config) != 0) goto fwxit;
  11226. if ((len % s_mg_flash_frdm.align) != 0) {
  11227. MG_ERROR(("%lu is not aligned to %lu", len, s_mg_flash_frdm.align));
  11228. goto fwxit;
  11229. }
  11230. if ((char *) addr < (char *) s_mg_flash_frdm.start) {
  11231. MG_ERROR(("Invalid flash write address: %p", addr));
  11232. goto fwxit;
  11233. }
  11234. uint32_t *dst = (uint32_t *) addr;
  11235. uint32_t *src = (uint32_t *) buf;
  11236. uint32_t *end = (uint32_t *) ((char *) buf + len);
  11237. ok = true;
  11238. while (ok && src < end) {
  11239. if (flash_page_start(dst) && flash_erase(&config, dst) == false) {
  11240. ok = false;
  11241. break;
  11242. }
  11243. uint32_t status;
  11244. uint32_t dst_ofs = (uint32_t) dst - (uint32_t) s_mg_flash_frdm.start;
  11245. if ((char *) buf >= (char *) s_mg_flash_frdm.start &&
  11246. (char *) buf <
  11247. (char *) (s_mg_flash_frdm.start + s_mg_flash_frdm.size)) {
  11248. // If we copy from FLASH to FLASH, then we first need to copy the source
  11249. // to RAM
  11250. size_t tmp_buf_size = s_mg_flash_frdm.align / sizeof(uint32_t);
  11251. uint32_t tmp[tmp_buf_size];
  11252. for (size_t i = 0; i < tmp_buf_size; i++) {
  11253. flash_wait();
  11254. tmp[i] = src[i];
  11255. }
  11256. status = flexspi_nor->page_program(MG_FLEXSPI_NOR_INSTANCE, &config,
  11257. (uint32_t) dst_ofs, tmp, false);
  11258. } else {
  11259. status = flexspi_nor->page_program(MG_FLEXSPI_NOR_INSTANCE, &config,
  11260. (uint32_t) dst_ofs, src, false);
  11261. }
  11262. src = (uint32_t *) ((char *) src + s_mg_flash_frdm.align);
  11263. dst = (uint32_t *) ((char *) dst + s_mg_flash_frdm.align);
  11264. if (status != 0) {
  11265. ok = false;
  11266. }
  11267. }
  11268. MG_INFO(("Flash write %lu bytes @ %p: %s.", len, dst, ok ? "ok" : "fail"));
  11269. fwxit:
  11270. if (!s_flash_irq_disabled) MG_ARM_ENABLE_IRQ();
  11271. return ok;
  11272. }
  11273. // just overwrite instead of swap
  11274. MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss) {
  11275. // no stdlib calls here
  11276. for (size_t ofs = 0; ofs < s; ofs += ss) {
  11277. mg_frdm_write(p1 + ofs, p2 + ofs, ss);
  11278. }
  11279. *(volatile unsigned long *) 0xe000ed0c = 0x5fa0004;
  11280. }
  11281. bool mg_ota_begin(size_t new_firmware_size) {
  11282. return mg_ota_flash_begin(new_firmware_size, &s_mg_flash_frdm);
  11283. }
  11284. bool mg_ota_write(const void *buf, size_t len) {
  11285. return mg_ota_flash_write(buf, len, &s_mg_flash_frdm);
  11286. }
  11287. bool mg_ota_end(void) {
  11288. if (mg_ota_flash_end(&s_mg_flash_frdm)) {
  11289. if (0) { // is_dualbank()
  11290. // TODO(): no devices so far
  11291. *(volatile unsigned long *) 0xe000ed0c = 0x5fa0004;
  11292. } else {
  11293. // Swap partitions. Pray power does not go away
  11294. MG_INFO(("Swapping partitions, size %u (%u sectors)",
  11295. s_mg_flash_frdm.size,
  11296. s_mg_flash_frdm.size / s_mg_flash_frdm.secsz));
  11297. MG_INFO(("Do NOT power off..."));
  11298. mg_log_level = MG_LL_NONE;
  11299. s_flash_irq_disabled = true;
  11300. // Runs in RAM, will reset when finished
  11301. single_bank_swap(
  11302. (char *) s_mg_flash_frdm.start,
  11303. (char *) s_mg_flash_frdm.start + s_mg_flash_frdm.size / 2,
  11304. s_mg_flash_frdm.size / 2, s_mg_flash_frdm.secsz);
  11305. }
  11306. }
  11307. return false;
  11308. }
  11309. struct mg_flash *mg_flash = &s_mg_flash_frdm;
  11310. #endif
  11311. #ifdef MG_ENABLE_LINES
  11312. #line 1 "src/ota_stm32f.c"
  11313. #endif
  11314. #if MG_OTA == MG_OTA_STM32F
  11315. static bool mg_stm32f_write(void *, const void *, size_t);
  11316. static bool mg_stm32f_swap(void);
  11317. static struct mg_flash s_mg_flash_stm32f = {
  11318. (void *) 0x08000000, // Start
  11319. 0, // Size, FLASH_SIZE_REG
  11320. 0, // Irregular sector size
  11321. 32, // Align, 256 bit
  11322. mg_stm32f_write,
  11323. mg_stm32f_swap,
  11324. };
  11325. #define MG_FLASH_BASE 0x40023c00
  11326. #define MG_FLASH_KEYR 0x04
  11327. #define MG_FLASH_SR 0x0c
  11328. #define MG_FLASH_CR 0x10
  11329. #define MG_FLASH_OPTCR 0x14
  11330. #define MG_FLASH_SIZE_REG_F7 0x1FF0F442
  11331. #define MG_FLASH_SIZE_REG_F4 0x1FFF7A22
  11332. #define STM_DBGMCU_IDCODE 0xE0042000
  11333. #define STM_DEV_ID (MG_REG(STM_DBGMCU_IDCODE) & (MG_BIT(12) - 1))
  11334. #define SYSCFG_MEMRMP 0x40013800
  11335. #define MG_FLASH_SIZE_REG_LOCATION \
  11336. ((STM_DEV_ID >= 0x449) ? MG_FLASH_SIZE_REG_F7 : MG_FLASH_SIZE_REG_F4)
  11337. static size_t flash_size(void) {
  11338. return (MG_REG(MG_FLASH_SIZE_REG_LOCATION) & 0xFFFF) * 1024;
  11339. }
  11340. MG_IRAM static size_t last_sector_size(void) {
  11341. return (STM_DEV_ID >= 0x449 ? 256 : 128) * 1024;
  11342. }
  11343. MG_IRAM static int is_dualbank(void) {
  11344. // only F42x/F43x series (0x419) support dual bank
  11345. return STM_DEV_ID == 0x419;
  11346. }
  11347. MG_IRAM static void flash_unlock(void) {
  11348. if (MG_REG(MG_FLASH_BASE + MG_FLASH_CR) & MG_BIT(31)) {
  11349. MG_REG(MG_FLASH_BASE + MG_FLASH_KEYR) = 0x45670123;
  11350. MG_REG(MG_FLASH_BASE + MG_FLASH_KEYR) = 0xcdef89ab;
  11351. }
  11352. }
  11353. #define MG_FLASH_CONFIG_16_64_128 1 // used by STM32F7
  11354. #define MG_FLASH_CONFIG_32_128_256 2 // used by STM32F4 and F2
  11355. MG_IRAM static bool flash_page_start(volatile uint32_t *dst) {
  11356. char *base = (char *) s_mg_flash_stm32f.start;
  11357. char *end = base + s_mg_flash_stm32f.size;
  11358. if (is_dualbank() && dst >= (uint32_t *) (base + (end - base) / 2)) {
  11359. dst = (uint32_t *) ((uint32_t) dst - (end - base) / 2);
  11360. }
  11361. uint32_t flash_config = MG_FLASH_CONFIG_16_64_128;
  11362. if (STM_DEV_ID >= 0x449) {
  11363. flash_config = MG_FLASH_CONFIG_32_128_256;
  11364. }
  11365. volatile char *p = (char *) dst;
  11366. if (p >= base && p < end) {
  11367. if (p < base + 16 * 1024 * 4 * flash_config) {
  11368. if ((p - base) % (16 * 1024 * flash_config) == 0) return true;
  11369. } else if (p == base + 16 * 1024 * 4 * flash_config) {
  11370. return true;
  11371. } else if ((p - base) % (128 * 1024 * flash_config) == 0) {
  11372. return true;
  11373. }
  11374. }
  11375. return false;
  11376. }
  11377. MG_IRAM static int flash_sector(volatile uint32_t *addr) {
  11378. char *base = (char *) s_mg_flash_stm32f.start;
  11379. char *end = base + s_mg_flash_stm32f.size;
  11380. bool addr_in_bank_2 = false;
  11381. if (is_dualbank() && addr >= (uint32_t *) (base + (end - base) / 2)) {
  11382. addr = (uint32_t *) ((uint32_t) addr - (end - base) / 2);
  11383. addr_in_bank_2 = true;
  11384. }
  11385. volatile char *p = (char *) addr;
  11386. uint32_t flash_config = MG_FLASH_CONFIG_16_64_128;
  11387. if (STM_DEV_ID >= 0x449) {
  11388. flash_config = MG_FLASH_CONFIG_32_128_256;
  11389. }
  11390. int sector = -1;
  11391. if (p >= base && p < end) {
  11392. if (p < base + 16 * 1024 * 4 * flash_config) {
  11393. sector = (p - base) / (16 * 1024 * flash_config);
  11394. } else if (p >= base + 64 * 1024 * flash_config &&
  11395. p < base + 128 * 1024 * flash_config) {
  11396. sector = 4;
  11397. } else {
  11398. sector = (p - base) / (128 * 1024 * flash_config) + 4;
  11399. }
  11400. }
  11401. if (sector == -1) return -1;
  11402. if (addr_in_bank_2) sector += 12; // a bank has 12 sectors
  11403. return sector;
  11404. }
  11405. MG_IRAM static bool flash_is_err(void) {
  11406. return MG_REG(MG_FLASH_BASE + MG_FLASH_SR) & ((MG_BIT(7) - 1) << 1);
  11407. }
  11408. MG_IRAM static void flash_wait(void) {
  11409. while (MG_REG(MG_FLASH_BASE + MG_FLASH_SR) & (MG_BIT(16))) (void) 0;
  11410. }
  11411. MG_IRAM static void flash_clear_err(void) {
  11412. flash_wait(); // Wait until ready
  11413. MG_REG(MG_FLASH_BASE + MG_FLASH_SR) = 0xf2; // Clear all errors
  11414. }
  11415. MG_IRAM static bool mg_stm32f_erase(void *addr) {
  11416. bool ok = false;
  11417. if (flash_page_start(addr) == false) {
  11418. MG_ERROR(("%p is not on a sector boundary", addr));
  11419. } else {
  11420. int sector = flash_sector(addr);
  11421. if (sector < 0) return false;
  11422. uint32_t sector_reg = sector;
  11423. if (is_dualbank() && sector >= 12) {
  11424. // 3.9.8 Flash control register (FLASH_CR) for F42xxx and F43xxx
  11425. // BITS[7:3]
  11426. sector_reg -= 12;
  11427. sector_reg |= MG_BIT(4);
  11428. }
  11429. flash_unlock();
  11430. flash_wait();
  11431. uint32_t cr = MG_BIT(1); // SER
  11432. cr |= MG_BIT(16); // STRT
  11433. cr |= (sector_reg & 31) << 3; // sector
  11434. MG_REG(MG_FLASH_BASE + MG_FLASH_CR) = cr;
  11435. ok = !flash_is_err();
  11436. MG_DEBUG(("Erase sector %lu @ %p %s. CR %#lx SR %#lx", sector, addr,
  11437. ok ? "ok" : "fail", MG_REG(MG_FLASH_BASE + MG_FLASH_CR),
  11438. MG_REG(MG_FLASH_BASE + MG_FLASH_SR)));
  11439. // After we have erased the sector, set CR flags for programming
  11440. // 2 << 8 is word write parallelism, bit(0) is PG. RM0385, section 3.7.5
  11441. MG_REG(MG_FLASH_BASE + MG_FLASH_CR) = MG_BIT(0) | (2 << 8);
  11442. flash_clear_err();
  11443. }
  11444. return ok;
  11445. }
  11446. MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss);
  11447. static bool s_flash_irq_disabled;
  11448. MG_IRAM static bool mg_stm32f_write(void *addr, const void *buf, size_t len) {
  11449. if ((len % s_mg_flash_stm32f.align) != 0) {
  11450. MG_ERROR(("%lu is not aligned to %lu", len, s_mg_flash_stm32f.align));
  11451. return false;
  11452. }
  11453. uint32_t *dst = (uint32_t *) addr;
  11454. uint32_t *src = (uint32_t *) buf;
  11455. uint32_t *end = (uint32_t *) ((char *) buf + len);
  11456. bool ok = true;
  11457. MG_ARM_DISABLE_IRQ();
  11458. flash_unlock();
  11459. flash_clear_err();
  11460. MG_REG(MG_FLASH_BASE + MG_FLASH_CR) = MG_BIT(0) | MG_BIT(9); // PG, 32-bit
  11461. flash_wait();
  11462. MG_DEBUG(("Writing flash @ %p, %lu bytes", addr, len));
  11463. while (ok && src < end) {
  11464. if (flash_page_start(dst) && mg_stm32f_erase(dst) == false) break;
  11465. *(volatile uint32_t *) dst++ = *src++;
  11466. MG_DSB(); // ensure flash is written with no errors
  11467. flash_wait();
  11468. if (flash_is_err()) ok = false;
  11469. }
  11470. if (!s_flash_irq_disabled) MG_ARM_ENABLE_IRQ();
  11471. MG_DEBUG(("Flash write %lu bytes @ %p: %s. CR %#lx SR %#lx", len, dst,
  11472. ok ? "ok" : "fail", MG_REG(MG_FLASH_BASE + MG_FLASH_CR),
  11473. MG_REG(MG_FLASH_BASE + MG_FLASH_SR)));
  11474. MG_REG(MG_FLASH_BASE + MG_FLASH_CR) &= ~MG_BIT(0); // Clear programming flag
  11475. return ok;
  11476. }
  11477. MG_IRAM static bool mg_stm32f_swap(void) {
  11478. // STM32 F42x/F43x support dual bank, however, the memory mapping
  11479. // change will not be carried through a hard reset. Therefore, we use
  11480. // the single-bank scratch-sector swap for this family as well.
  11481. size_t ss = last_sector_size();
  11482. char *p1 = (char *) s_mg_flash_stm32f.start;
  11483. char *p2;
  11484. size_t s;
  11485. s_mg_flash_stm32f.size = flash_size();
  11486. p2 = p1 + s_mg_flash_stm32f.size / 2;
  11487. s = s_mg_flash_stm32f.size / 2 - ss;
  11488. MG_INFO(("Swapping partitions, %u bytes", s));
  11489. MG_INFO(("Do NOT power off..."));
  11490. MG_OTA_ROLLBACK_TIMER_FEED();
  11491. mg_log_level = MG_LL_NONE;
  11492. s_flash_irq_disabled = true;
  11493. single_bank_swap(p1, p2, s, ss);
  11494. return true; // unreachable
  11495. }
  11496. // True exchange between first half [p1..p1+s) and second half [p2..p2+s),
  11497. // using the last sector of the second half as scratch. Runs from RAM and resets.
  11498. MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss) {
  11499. char *scratch = p2 + s;
  11500. for (size_t ofs = 0; ofs < s; ofs += ss) {
  11501. MG_OTA_ROLLBACK_TIMER_FEED();
  11502. mg_stm32f_write(scratch, p1 + ofs, ss);
  11503. MG_OTA_ROLLBACK_TIMER_FEED();
  11504. mg_stm32f_write(p1 + ofs, p2 + ofs, ss);
  11505. MG_OTA_ROLLBACK_TIMER_FEED();
  11506. mg_stm32f_write(p2 + ofs, scratch, ss);
  11507. }
  11508. *(volatile uint32_t *) 0xe000ed0cU = 0x5fa0004U; // NVIC_SystemReset()
  11509. }
  11510. bool mg_ota_begin(size_t new_firmware_size) {
  11511. size_t max;
  11512. s_mg_flash_stm32f.size = flash_size();
  11513. #ifdef __ZEPHYR__
  11514. *((uint32_t *)0xE000ED94) = 0;
  11515. MG_DEBUG(("Jailbreak %s", *((uint32_t *)0xE000ED94) == 0 ? "successful" : "failed"));
  11516. #endif
  11517. max = s_mg_flash_stm32f.size / 2 - last_sector_size();
  11518. if (new_firmware_size > max) {
  11519. MG_ERROR(("Firmware %lu too big for single-bank OTA, max %lu",
  11520. new_firmware_size, max));
  11521. return false;
  11522. }
  11523. return mg_ota_flash_begin(new_firmware_size, &s_mg_flash_stm32f);
  11524. }
  11525. bool mg_ota_write(const void *buf, size_t len) {
  11526. return mg_ota_flash_write(buf, len, &s_mg_flash_stm32f);
  11527. }
  11528. bool mg_ota_end(void) {
  11529. mg_ota_flash_end(&s_mg_flash_stm32f);
  11530. return false;
  11531. }
  11532. struct mg_flash *mg_flash = &s_mg_flash_stm32f;
  11533. #endif
  11534. #ifdef MG_ENABLE_LINES
  11535. #line 1 "src/ota_stm32h5.c"
  11536. #endif
  11537. #if MG_OTA == MG_OTA_STM32H5
  11538. static bool mg_stm32h5_write(void *, const void *, size_t);
  11539. static bool mg_stm32h5_swap(void);
  11540. static struct mg_flash s_mg_flash_stm32h5 = {
  11541. (void *) 0x08000000, // Start
  11542. 0, // Size, FLASHSIZE_BASE
  11543. 8 * 1024, // Sector size, 8k
  11544. 16, // Align, 128 bit
  11545. mg_stm32h5_write,
  11546. mg_stm32h5_swap,
  11547. };
  11548. #define MG_FLASH_BASE 0x40022000 // Base address of the flash controller
  11549. #define FLASH_KEYR (MG_FLASH_BASE + 0x4) // See RM0481 7.11
  11550. #define FLASH_OPTKEYR (MG_FLASH_BASE + 0xc)
  11551. #define FLASH_OPTCR (MG_FLASH_BASE + 0x1c)
  11552. #define FLASH_NSSR (MG_FLASH_BASE + 0x20)
  11553. #define FLASH_NSCR (MG_FLASH_BASE + 0x28)
  11554. #define FLASH_NSCCR (MG_FLASH_BASE + 0x30)
  11555. #define FLASH_OPTSR_CUR (MG_FLASH_BASE + 0x50)
  11556. #define FLASH_OPTSR_PRG (MG_FLASH_BASE + 0x54)
  11557. #ifndef FLASHSIZE_BASE
  11558. #define FLASHSIZE_BASE 0x08FFF80CUL
  11559. #endif
  11560. static size_t flash_size(void) {
  11561. uint32_t kb = MG_REG(FLASHSIZE_BASE) & 0xFFFF;
  11562. return (kb == 0 || kb == 0xFFFF) ? 2 * 1024 * 1024 : kb * 1024;
  11563. }
  11564. static uint32_t sectors_per_bank(void) {
  11565. return (uint32_t) (s_mg_flash_stm32h5.size / 2 / s_mg_flash_stm32h5.secsz);
  11566. }
  11567. static void flash_unlock(void) {
  11568. if (MG_REG(FLASH_NSCR) & MG_BIT(0)) {
  11569. MG_REG(FLASH_KEYR) = 0x45670123;
  11570. MG_REG(FLASH_KEYR) = 0xcdef89ab;
  11571. }
  11572. if (MG_REG(FLASH_OPTCR) & MG_BIT(0)) {
  11573. MG_REG(FLASH_OPTKEYR) = 0x08192a3b;
  11574. MG_REG(FLASH_OPTKEYR) = 0x4c5d6e7f;
  11575. }
  11576. }
  11577. static int flash_page_start(volatile uint32_t *dst) {
  11578. char *base = (char *) s_mg_flash_stm32h5.start,
  11579. *end = base + s_mg_flash_stm32h5.size;
  11580. volatile char *p = (char *) dst;
  11581. return p >= base && p < end && ((p - base) % s_mg_flash_stm32h5.secsz) == 0;
  11582. }
  11583. static bool flash_is_err(void) {
  11584. return MG_REG(FLASH_NSSR) & ((MG_BIT(8) - 1) << 17); // RM0481 7.11.9
  11585. }
  11586. static void flash_wait(void) {
  11587. while ((MG_REG(FLASH_NSSR) & MG_BIT(0)) &&
  11588. (MG_REG(FLASH_NSSR) & MG_BIT(16)) == 0) {
  11589. (void) 0;
  11590. }
  11591. }
  11592. static void flash_clear_err(void) {
  11593. flash_wait(); // Wait until ready
  11594. MG_REG(FLASH_NSCCR) = ((MG_BIT(9) - 1) << 16U); // Clear all errors
  11595. }
  11596. static bool flash_bank_is_swapped(void) {
  11597. return MG_REG(FLASH_OPTCR) & MG_BIT(31); // RM0481 7.11.8
  11598. }
  11599. static bool mg_stm32h5_erase(void *location) {
  11600. bool ok = false;
  11601. if (flash_page_start(location) == false) {
  11602. MG_ERROR(("%p is not on a sector boundary"));
  11603. } else {
  11604. uintptr_t diff = (char *) location - (char *) s_mg_flash_stm32h5.start;
  11605. uint32_t sector = diff / s_mg_flash_stm32h5.secsz;
  11606. uint32_t bank_sectors = sectors_per_bank();
  11607. uint32_t saved_cr = MG_REG(FLASH_NSCR); // Save CR value
  11608. flash_unlock();
  11609. flash_clear_err();
  11610. MG_REG(FLASH_NSCR) = 0;
  11611. if ((sector < bank_sectors && flash_bank_is_swapped()) ||
  11612. (sector >= bank_sectors && !flash_bank_is_swapped())) {
  11613. MG_REG(FLASH_NSCR) |= MG_BIT(31); // Set FLASH_CR_BKSEL
  11614. }
  11615. if (sector >= bank_sectors) sector -= bank_sectors;
  11616. MG_REG(FLASH_NSCR) |= MG_BIT(2) | (sector << 6); // Erase | sector_num
  11617. MG_REG(FLASH_NSCR) |= MG_BIT(5); // Start erasing
  11618. flash_wait();
  11619. ok = !flash_is_err();
  11620. MG_DEBUG(("Erase sector %lu @ %p: %s. CR %#lx SR %#lx", sector, location,
  11621. ok ? "ok" : "fail", MG_REG(FLASH_NSCR), MG_REG(FLASH_NSSR)));
  11622. // mg_hexdump(location, 32);
  11623. MG_REG(FLASH_NSCR) = saved_cr; // Restore saved CR
  11624. }
  11625. return ok;
  11626. }
  11627. static bool mg_stm32h5_swap(void) {
  11628. uint32_t desired = flash_bank_is_swapped() ? 0 : MG_BIT(31);
  11629. flash_unlock();
  11630. flash_clear_err();
  11631. MG_SET_BITS(MG_REG(FLASH_OPTSR_PRG), MG_BIT(31), desired);
  11632. MG_REG(FLASH_OPTCR) |= MG_BIT(1); // OPTSTART; triggers auto-reset on H5
  11633. while ((MG_REG(FLASH_OPTSR_CUR) & MG_BIT(31)) != desired) (void) 0;
  11634. return true;
  11635. }
  11636. static bool mg_stm32h5_write(void *addr, const void *buf, size_t len) {
  11637. if ((len % s_mg_flash_stm32h5.align) != 0) {
  11638. MG_ERROR(("%lu is not aligned to %lu", len, s_mg_flash_stm32h5.align));
  11639. return false;
  11640. }
  11641. uint32_t *dst = (uint32_t *) addr;
  11642. uint32_t *src = (uint32_t *) buf;
  11643. uint32_t *end = (uint32_t *) ((char *) buf + len);
  11644. bool ok = true;
  11645. MG_ARM_DISABLE_IRQ();
  11646. flash_unlock();
  11647. flash_clear_err();
  11648. MG_REG(FLASH_NSCR) = MG_BIT(1); // Set programming flag
  11649. while (ok && src < end) {
  11650. if (flash_page_start(dst) && mg_stm32h5_erase(dst) == false) {
  11651. ok = false;
  11652. break;
  11653. }
  11654. *(volatile uint32_t *) dst++ = *src++;
  11655. flash_wait();
  11656. if (flash_is_err()) ok = false;
  11657. }
  11658. MG_ARM_ENABLE_IRQ();
  11659. MG_DEBUG(("Flash write %lu bytes @ %p: %s. CR %#lx SR %#lx", len, dst,
  11660. flash_is_err() ? "fail" : "ok", MG_REG(FLASH_NSCR),
  11661. MG_REG(FLASH_NSSR)));
  11662. MG_REG(FLASH_NSCR) = 0; // Clear flags
  11663. return ok;
  11664. }
  11665. bool mg_ota_begin(size_t new_firmware_size) {
  11666. s_mg_flash_stm32h5.size = flash_size();
  11667. #ifdef __ZEPHYR__
  11668. *((uint32_t *)0xE000ED94) = 0;
  11669. MG_DEBUG(("Jailbreak %s", *((uint32_t *)0xE000ED94) == 0 ? "successful" : "failed"));
  11670. #endif
  11671. return mg_ota_flash_begin(new_firmware_size, &s_mg_flash_stm32h5);
  11672. }
  11673. bool mg_ota_write(const void *buf, size_t len) {
  11674. return mg_ota_flash_write(buf, len, &s_mg_flash_stm32h5);
  11675. }
  11676. bool mg_ota_end(void) {
  11677. if (!mg_ota_flash_end(&s_mg_flash_stm32h5)) return false;
  11678. *(volatile uint32_t *) 0xe000ed0c = 0x5fa0004U; // NVIC_SystemReset()
  11679. return true;
  11680. }
  11681. struct mg_flash *mg_flash = &s_mg_flash_stm32h5;
  11682. #endif
  11683. #ifdef MG_ENABLE_LINES
  11684. #line 1 "src/ota_stm32h7.c"
  11685. #endif
  11686. #if MG_OTA == MG_OTA_STM32H7 || MG_OTA == MG_OTA_STM32H7_DUAL_CORE
  11687. // - H723/735 RM 4.3.3: Note: The application can simultaneously request a read
  11688. // and a write operation through the AXI interface.
  11689. // - We only need IRAM for partition swapping in the H723, however, all
  11690. // related functions must reside in IRAM for this to be possible.
  11691. // - Linker files for other devices won't define a .iram section so there's no
  11692. // associated penalty
  11693. static bool mg_stm32h7_write(void *, const void *, size_t);
  11694. static bool mg_stm32h7_swap(void);
  11695. static struct mg_flash s_mg_flash_stm32h7 = {
  11696. (void *) 0x08000000, // Start
  11697. 0, // Size, FLASH_SIZE_REG
  11698. 128 * 1024, // Sector size, 128k
  11699. 32, // Align, 256 bit
  11700. mg_stm32h7_write,
  11701. mg_stm32h7_swap,
  11702. };
  11703. #define FLASH_BASE1 0x52002000 // Base address for bank1
  11704. #define FLASH_BASE2 0x52002100 // Base address for bank2
  11705. #define FLASH_KEYR 0x04 // See RM0433 4.9.2
  11706. #define FLASH_OPTKEYR 0x08
  11707. #define FLASH_OPTCR 0x18
  11708. #define FLASH_SR 0x10
  11709. #define FLASH_CR 0x0c
  11710. #define FLASH_CCR 0x14
  11711. #define FLASH_OPTSR_CUR 0x1c
  11712. #define FLASH_OPTSR_PRG 0x20
  11713. #define FLASH_SIZE_REG 0x1ff1e880
  11714. #define IS_DUALCORE() (MG_OTA == MG_OTA_STM32H7_DUAL_CORE)
  11715. MG_IRAM static size_t flash_size(void) {
  11716. size_t size = MG_REG(FLASH_SIZE_REG) * 1024;
  11717. return IS_DUALCORE() ? size / 2 : size;
  11718. }
  11719. MG_IRAM static bool is_dualbank(void) {
  11720. if (IS_DUALCORE()) {
  11721. // H745/H755 and H747/H757 are running on dual core.
  11722. // Using only the 1st bank (mapped to CM7), in order not to interfere
  11723. // with the 2nd bank (CM4), possibly causing CM4 to boot unexpectedly.
  11724. return false;
  11725. }
  11726. return (s_mg_flash_stm32h7.size < 2 * 1024 * 1024) ? false : true;
  11727. }
  11728. MG_IRAM static void flash_unlock(void) {
  11729. if (MG_REG(FLASH_BASE1 + FLASH_CR) & MG_BIT(0)) {
  11730. MG_REG(FLASH_BASE1 + FLASH_KEYR) = 0x45670123;
  11731. MG_REG(FLASH_BASE1 + FLASH_KEYR) = 0xcdef89ab;
  11732. }
  11733. if (is_dualbank() && MG_REG(FLASH_BASE2 + FLASH_CR) & MG_BIT(0)) {
  11734. MG_REG(FLASH_BASE2 + FLASH_KEYR) = 0x45670123;
  11735. MG_REG(FLASH_BASE2 + FLASH_KEYR) = 0xcdef89ab;
  11736. }
  11737. if (MG_REG(FLASH_BASE1 + FLASH_OPTCR) & MG_BIT(0)) {
  11738. MG_REG(FLASH_BASE1 + FLASH_OPTKEYR) = 0x08192a3b; // opt reg is "shared"
  11739. MG_REG(FLASH_BASE1 + FLASH_OPTKEYR) = 0x4c5d6e7f; // thus unlock once
  11740. }
  11741. }
  11742. MG_IRAM static bool flash_page_start(volatile uint32_t *dst) {
  11743. char *base = (char *) s_mg_flash_stm32h7.start,
  11744. *end = base + s_mg_flash_stm32h7.size;
  11745. volatile char *p = (char *) dst;
  11746. return p >= base && p < end && ((p - base) % s_mg_flash_stm32h7.secsz) == 0;
  11747. }
  11748. MG_IRAM static bool flash_is_err(uint32_t bank) {
  11749. return MG_REG(bank + FLASH_SR) & ((MG_BIT(11) - 1) << 17); // RM0433 4.9.5
  11750. }
  11751. MG_IRAM static void flash_wait(uint32_t bank) {
  11752. while (MG_REG(bank + FLASH_SR) & (MG_BIT(0) | MG_BIT(2))) (void) 0;
  11753. }
  11754. MG_IRAM static void flash_clear_err(uint32_t bank) {
  11755. flash_wait(bank); // Wait until ready
  11756. MG_REG(bank + FLASH_CCR) = ((MG_BIT(11) - 1) << 16U); // Clear all errors
  11757. }
  11758. MG_IRAM static bool flash_bank_is_swapped(uint32_t bank) {
  11759. return MG_REG(bank + FLASH_OPTCR) & MG_BIT(31); // RM0433 4.9.7
  11760. }
  11761. // Figure out flash bank based on the address
  11762. MG_IRAM static uint32_t flash_bank(void *addr) {
  11763. size_t ofs = (char *) addr - (char *) s_mg_flash_stm32h7.start;
  11764. if (!is_dualbank()) return FLASH_BASE1;
  11765. return ofs < s_mg_flash_stm32h7.size / 2 ? FLASH_BASE1 : FLASH_BASE2;
  11766. }
  11767. // read-while-write, no need to disable IRQs for standalone usage
  11768. MG_IRAM static bool mg_stm32h7_erase(void *addr) {
  11769. bool ok = false;
  11770. if (flash_page_start(addr) == false) {
  11771. MG_ERROR(("%p is not on a sector boundary", addr));
  11772. } else {
  11773. uintptr_t diff = (char *) addr - (char *) s_mg_flash_stm32h7.start;
  11774. uint32_t sector = diff / s_mg_flash_stm32h7.secsz;
  11775. uint32_t bank = flash_bank(addr);
  11776. uint32_t saved_cr = MG_REG(bank + FLASH_CR); // Save CR value
  11777. flash_unlock();
  11778. if (sector > 7) sector -= 8;
  11779. flash_clear_err(bank);
  11780. MG_REG(bank + FLASH_CR) = MG_BIT(5); // 32-bit write parallelism
  11781. MG_REG(bank + FLASH_CR) |= (sector & 7U) << 8U; // Sector to erase
  11782. MG_REG(bank + FLASH_CR) |= MG_BIT(2); // Sector erase bit
  11783. MG_REG(bank + FLASH_CR) |= MG_BIT(7); // Start erasing
  11784. flash_wait(bank);
  11785. ok = !flash_is_err(bank);
  11786. MG_DEBUG(("Erase sector %lu @ %p %s. CR %#lx SR %#lx", sector, addr,
  11787. ok ? "ok" : "fail", MG_REG(bank + FLASH_CR),
  11788. MG_REG(bank + FLASH_SR)));
  11789. MG_REG(bank + FLASH_CR) = saved_cr; // Restore CR
  11790. }
  11791. return ok;
  11792. }
  11793. MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss);
  11794. static bool s_flash_irq_disabled;
  11795. MG_IRAM static bool mg_stm32h7_swap(void) {
  11796. s_mg_flash_stm32h7.size = flash_size();
  11797. if (!is_dualbank()) {
  11798. // True sector-by-sector swap using the last sector of the second half as
  11799. // scratch. Resets inside single_bank_swap, never returns.
  11800. size_t ss = s_mg_flash_stm32h7.secsz;
  11801. char *p1 = (char *) s_mg_flash_stm32h7.start;
  11802. char *p2 = p1 + s_mg_flash_stm32h7.size / 2;
  11803. size_t s = s_mg_flash_stm32h7.size / 2 - ss;
  11804. MG_INFO(("Swapping partitions, %u bytes (%u sectors)", s, s / ss));
  11805. MG_INFO(("Do NOT power off..."));
  11806. MG_OTA_ROLLBACK_TIMER_FEED();
  11807. mg_log_level = MG_LL_NONE;
  11808. s_flash_irq_disabled = true;
  11809. single_bank_swap(p1, p2, s, ss);
  11810. return true; // unreachable
  11811. }
  11812. uint32_t bank = FLASH_BASE1;
  11813. uint32_t desired = flash_bank_is_swapped(bank) ? 0 : MG_BIT(31);
  11814. flash_unlock();
  11815. flash_clear_err(bank);
  11816. MG_SET_BITS(MG_REG(bank + FLASH_OPTSR_PRG), MG_BIT(31), desired);
  11817. MG_REG(bank + FLASH_OPTCR) |= MG_BIT(1); // OPTSTART
  11818. while ((MG_REG(bank + FLASH_OPTSR_CUR) & MG_BIT(31)) != desired) (void) 0;
  11819. return true;
  11820. }
  11821. MG_IRAM static bool mg_stm32h7_write(void *addr, const void *buf, size_t len) {
  11822. if ((len % s_mg_flash_stm32h7.align) != 0) {
  11823. MG_ERROR(("%lu is not aligned to %lu", len, s_mg_flash_stm32h7.align));
  11824. return false;
  11825. }
  11826. uint32_t bank = flash_bank(addr);
  11827. uint32_t *dst = (uint32_t *) addr;
  11828. uint32_t *src = (uint32_t *) buf;
  11829. uint32_t *end = (uint32_t *) ((char *) buf + len);
  11830. bool ok = true;
  11831. MG_ARM_DISABLE_IRQ();
  11832. flash_unlock();
  11833. flash_clear_err(bank);
  11834. MG_REG(bank + FLASH_CR) = MG_BIT(1); // Set programming flag
  11835. MG_REG(bank + FLASH_CR) |= MG_BIT(5); // 32-bit write parallelism
  11836. while (ok && src < end) {
  11837. if (flash_page_start(dst) && mg_stm32h7_erase(dst) == false) {
  11838. ok = false;
  11839. break;
  11840. }
  11841. *(volatile uint32_t *) dst++ = *src++;
  11842. flash_wait(bank);
  11843. if (flash_is_err(bank)) ok = false;
  11844. }
  11845. if (!s_flash_irq_disabled) MG_ARM_ENABLE_IRQ();
  11846. MG_DEBUG(("Flash write %lu bytes @ %p: %s. CR %#lx SR %#lx", len, addr,
  11847. ok ? "ok" : "fail", MG_REG(bank + FLASH_CR),
  11848. MG_REG(bank + FLASH_SR)));
  11849. MG_REG(bank + FLASH_CR) &= ~MG_BIT(1); // Clear programming flag
  11850. return ok;
  11851. }
  11852. // True sector-by-sector exchange between first half [p1..p1+s) and second half
  11853. // [p2..p2+s), using the sector at p2+s as scratch. Runs from RAM. Resets on
  11854. // completion. Symmetric: calling twice returns flash to original state.
  11855. MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss) {
  11856. char *scratch = p2 + s; // Last sector of second half, reserved as scratch
  11857. for (size_t ofs = 0; ofs < s; ofs += ss) {
  11858. MG_OTA_ROLLBACK_TIMER_FEED();
  11859. mg_stm32h7_write(scratch, p1 + ofs, ss); // Save p1[i] to scratch
  11860. MG_OTA_ROLLBACK_TIMER_FEED();
  11861. mg_stm32h7_write(p1 + ofs, p2 + ofs, ss); // Copy p2[i] to p1[i]
  11862. MG_OTA_ROLLBACK_TIMER_FEED();
  11863. mg_stm32h7_write(p2 + ofs, scratch, ss); // Copy scratch to p2[i]
  11864. }
  11865. *(volatile uint32_t *) 0xe000ed0cU = 0x5fa0004U; // NVIC_SystemReset()
  11866. }
  11867. bool mg_ota_begin(size_t new_firmware_size) {
  11868. s_mg_flash_stm32h7.size = flash_size();
  11869. #ifdef __ZEPHYR__
  11870. *((uint32_t *) 0xE000ED94) = 0;
  11871. MG_DEBUG(("Jailbreak %s", *((uint32_t *) 0xE000ED94) == 0 ? "ok" : "failed"));
  11872. #endif
  11873. if (!is_dualbank()) {
  11874. // Last sector of the second half is reserved as swap scratch; enforce limit.
  11875. size_t max = s_mg_flash_stm32h7.size / 2 - s_mg_flash_stm32h7.secsz;
  11876. if (new_firmware_size > max) {
  11877. MG_ERROR(("Firmware %lu too big for single-bank OTA, max %lu", new_firmware_size, max));
  11878. return false;
  11879. }
  11880. }
  11881. return mg_ota_flash_begin(new_firmware_size, &s_mg_flash_stm32h7);
  11882. }
  11883. bool mg_ota_write(const void *buf, size_t len) {
  11884. return mg_ota_flash_write(buf, len, &s_mg_flash_stm32h7);
  11885. }
  11886. bool mg_ota_end(void) {
  11887. if (mg_ota_flash_end(&s_mg_flash_stm32h7)) {
  11888. if (is_dualbank()) {
  11889. // Bank swap is deferred until reset, been executing in flash, reset
  11890. *(volatile uint32_t *) 0xe000ed0cU = 0x5fa0004U; // NVIC_SystemReset()
  11891. }
  11892. }
  11893. return false;
  11894. }
  11895. struct mg_flash *mg_flash = &s_mg_flash_stm32h7;
  11896. #endif
  11897. #ifdef MG_ENABLE_LINES
  11898. #line 1 "src/printf.c"
  11899. #endif
  11900. size_t mg_queue_printf(struct mg_queue *q, const char *fmt, ...) {
  11901. char *buf;
  11902. size_t len;
  11903. va_list ap1, ap2;
  11904. va_start(ap1, fmt);
  11905. len = mg_vsnprintf(NULL, 0, fmt, &ap1);
  11906. va_end(ap1);
  11907. if (len == 0 || mg_queue_book(q, &buf, len + 1) < len + 1)
  11908. return 0; // Nah. Not enough space
  11909. va_start(ap2, fmt);
  11910. len = mg_vsnprintf(buf, len + 1, fmt, &ap2);
  11911. mg_queue_add(q, len);
  11912. va_end(ap2);
  11913. return len;
  11914. }
  11915. static void mg_pfn_iobuf_private(char ch, void *param, bool expand) {
  11916. struct mg_iobuf *io = (struct mg_iobuf *) param;
  11917. if (expand && io->len + 2 > io->size) mg_iobuf_resize(io, io->len + 2);
  11918. if (io->len + 2 <= io->size) {
  11919. io->buf[io->len++] = (uint8_t) ch;
  11920. io->buf[io->len] = 0;
  11921. } else if (io->len < io->size) {
  11922. io->buf[io->len++] = 0; // Guarantee to 0-terminate
  11923. }
  11924. }
  11925. void mg_pfn_iobuf_noresize(char ch, void *param) {
  11926. mg_pfn_iobuf_private(ch, param, false);
  11927. }
  11928. void mg_pfn_iobuf(char ch, void *param) {
  11929. mg_pfn_iobuf_private(ch, param, true);
  11930. }
  11931. size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
  11932. struct mg_iobuf io = {0, 0, 0, 0};
  11933. size_t n;
  11934. io.buf = (uint8_t *) buf, io.size = len;
  11935. n = mg_vxprintf(mg_pfn_iobuf_noresize, &io, fmt, ap);
  11936. if (n < len) buf[n] = '\0';
  11937. return n;
  11938. }
  11939. size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
  11940. va_list ap;
  11941. size_t n;
  11942. va_start(ap, fmt);
  11943. n = mg_vsnprintf(buf, len, fmt, &ap);
  11944. va_end(ap);
  11945. return n;
  11946. }
  11947. char *mg_vmprintf(const char *fmt, va_list *ap) {
  11948. struct mg_iobuf io = {0, 0, 0, 256};
  11949. mg_vxprintf(mg_pfn_iobuf, &io, fmt, ap);
  11950. return (char *) io.buf;
  11951. }
  11952. char *mg_mprintf(const char *fmt, ...) {
  11953. char *s;
  11954. va_list ap;
  11955. va_start(ap, fmt);
  11956. s = mg_vmprintf(fmt, &ap);
  11957. va_end(ap);
  11958. return s;
  11959. }
  11960. void mg_pfn_stdout(char c, void *param) {
  11961. putchar(c);
  11962. (void) param;
  11963. }
  11964. static size_t print_ip4(void (*out)(char, void *), void *arg, uint8_t *p) {
  11965. return mg_xprintf(out, arg, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  11966. }
  11967. static size_t print_ip6(void (*out)(char, void *), void *arg, uint16_t *p) {
  11968. return mg_xprintf(out, arg, "[%x:%x:%x:%x:%x:%x:%x:%x]", mg_ntohs(p[0]),
  11969. mg_ntohs(p[1]), mg_ntohs(p[2]), mg_ntohs(p[3]),
  11970. mg_ntohs(p[4]), mg_ntohs(p[5]), mg_ntohs(p[6]),
  11971. mg_ntohs(p[7]));
  11972. }
  11973. size_t mg_print_ip4(void (*out)(char, void *), void *arg, va_list *ap) {
  11974. uint8_t *p = va_arg(*ap, uint8_t *);
  11975. return print_ip4(out, arg, p);
  11976. }
  11977. size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap) {
  11978. uint16_t *p = va_arg(*ap, uint16_t *);
  11979. return print_ip6(out, arg, p);
  11980. }
  11981. size_t mg_print_ip(void (*out)(char, void *), void *arg, va_list *ap) {
  11982. struct mg_addr *addr = va_arg(*ap, struct mg_addr *);
  11983. if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->addr.ip);
  11984. return print_ip4(out, arg, (uint8_t *) &addr->addr.ip);
  11985. }
  11986. size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap) {
  11987. struct mg_addr *a = va_arg(*ap, struct mg_addr *);
  11988. return mg_xprintf(out, arg, "%M:%hu", mg_print_ip, a, mg_ntohs(a->port));
  11989. }
  11990. static size_t print_mac(void (*out)(char, void *), void *arg, uint8_t *p) {
  11991. return mg_xprintf(out, arg, "%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2],
  11992. p[3], p[4], p[5]);
  11993. }
  11994. size_t mg_print_mac(void (*out)(char, void *), void *arg, va_list *ap) {
  11995. uint8_t *p = va_arg(*ap, uint8_t *);
  11996. return print_mac(out, arg, p);
  11997. }
  11998. static size_t print_ieee64(void (*out)(char, void *), void *arg, uint8_t *p) {
  11999. return mg_xprintf(out, arg, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", p[0],
  12000. p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
  12001. }
  12002. size_t mg_print_ieee64(void (*out)(char, void *), void *arg, va_list *ap) {
  12003. uint8_t *p = va_arg(*ap, uint8_t *);
  12004. return print_ieee64(out, arg, p);
  12005. }
  12006. #if MG_ENABLE_TCPIP
  12007. size_t mg_print_l2addr(void (*out)(char, void *), void *arg, va_list *ap) {
  12008. enum mg_l2type type = (enum mg_l2type) va_arg(*ap, int);
  12009. switch (type) {
  12010. case MG_TCPIP_L2_ETH:
  12011. case MG_TCPIP_L2_PPPoE: {
  12012. uint8_t *p = va_arg(*ap, uint8_t *);
  12013. return print_mac(out, arg, p);
  12014. } break;
  12015. default: break;
  12016. }
  12017. return 0;
  12018. }
  12019. #endif
  12020. static char mg_esc(int c, bool esc) {
  12021. const char *p, *esc1 = "\b\f\n\r\t\\\"", *esc2 = "bfnrt\\\"";
  12022. for (p = esc ? esc1 : esc2; *p != '\0'; p++) {
  12023. if (*p == c) return esc ? esc2[p - esc1] : esc1[p - esc2];
  12024. }
  12025. return 0;
  12026. }
  12027. static char mg_escape(int c) {
  12028. return mg_esc(c, true);
  12029. }
  12030. static size_t qcpy(void (*out)(char, void *), void *ptr, char *buf,
  12031. size_t len) {
  12032. size_t i = 0, extra = 0;
  12033. for (i = 0; i < len && buf[i] != '\0'; i++) {
  12034. char c = mg_escape(buf[i]);
  12035. if (c) {
  12036. out('\\', ptr), out(c, ptr), extra++;
  12037. } else {
  12038. out(buf[i], ptr);
  12039. }
  12040. }
  12041. return i + extra;
  12042. }
  12043. static size_t bcpy(void (*out)(char, void *), void *arg, uint8_t *buf,
  12044. size_t len) {
  12045. size_t i, j, n = 0;
  12046. const char *t =
  12047. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  12048. for (i = 0; i < len; i += 3) {
  12049. uint8_t c1 = buf[i], c2 = i + 1 < len ? buf[i + 1] : 0,
  12050. c3 = i + 2 < len ? buf[i + 2] : 0;
  12051. char tmp[4] = {0, 0, '=', '='};
  12052. tmp[0] = t[c1 >> 2], tmp[1] = t[(c1 & 3) << 4 | (c2 >> 4)];
  12053. if (i + 1 < len) tmp[2] = t[(c2 & 15) << 2 | (c3 >> 6)];
  12054. if (i + 2 < len) tmp[3] = t[c3 & 63];
  12055. for (j = 0; j < sizeof(tmp) && tmp[j] != '\0'; j++) out(tmp[j], arg);
  12056. n += j;
  12057. }
  12058. return n;
  12059. }
  12060. size_t mg_print_hex(void (*out)(char, void *), void *arg, va_list *ap) {
  12061. size_t bl = (size_t) va_arg(*ap, int);
  12062. uint8_t *p = va_arg(*ap, uint8_t *);
  12063. const char *hex = "0123456789abcdef";
  12064. size_t j;
  12065. for (j = 0; j < bl; j++) {
  12066. out(hex[(p[j] >> 4) & 0x0F], arg);
  12067. out(hex[p[j] & 0x0F], arg);
  12068. }
  12069. return 2 * bl;
  12070. }
  12071. size_t mg_print_base64(void (*out)(char, void *), void *arg, va_list *ap) {
  12072. size_t len = (size_t) va_arg(*ap, int);
  12073. uint8_t *buf = va_arg(*ap, uint8_t *);
  12074. return bcpy(out, arg, buf, len);
  12075. }
  12076. size_t mg_print_esc(void (*out)(char, void *), void *arg, va_list *ap) {
  12077. size_t len = (size_t) va_arg(*ap, int);
  12078. char *p = va_arg(*ap, char *);
  12079. if (len == 0) len = p == NULL ? 0 : strlen(p);
  12080. return qcpy(out, arg, p, len);
  12081. }
  12082. size_t mg_print_html_esc(void (*out)(char, void *), void *arg, va_list *ap) {
  12083. size_t i, n = 0;
  12084. int len = va_arg(*ap, int);
  12085. const char *s = va_arg(*ap, const char *);
  12086. for (i = 0; i < (size_t) len; i++) {
  12087. const char *esc = NULL;
  12088. switch (s[i]) {
  12089. // clang-format off
  12090. case '&': esc = "&amp;"; break;
  12091. case '<': esc = "&lt;"; break;
  12092. case '>': esc = "&gt;"; break;
  12093. case '"': esc = "&quot;"; break;
  12094. default: break;
  12095. // clang-format on
  12096. }
  12097. if (esc != NULL) {
  12098. while (*esc != '\0') {
  12099. out(*esc++, arg);
  12100. n++;
  12101. }
  12102. } else {
  12103. out(s[i], arg);
  12104. n++;
  12105. }
  12106. }
  12107. return n;
  12108. }
  12109. #ifdef MG_ENABLE_LINES
  12110. #line 1 "src/queue.c"
  12111. #endif
  12112. #if (defined(__GNUC__) && (__GNUC__ > 4) || \
  12113. (defined(__GNUC_MINOR__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 1)) || \
  12114. defined(__clang__)
  12115. #define MG_MEMORY_BARRIER() __sync_synchronize()
  12116. #elif defined(_MSC_VER) && _MSC_VER >= 1700
  12117. #define MG_MEMORY_BARRIER() MemoryBarrier()
  12118. #elif !defined(MG_MEMORY_BARRIER)
  12119. #define MG_MEMORY_BARRIER()
  12120. #endif
  12121. // Every message in a queue is prepended by a 32-bit message length (ML).
  12122. // If ML is 0, then it is the end, and reader must wrap to the beginning.
  12123. //
  12124. // Queue when q->tail <= q->head:
  12125. // |----- free -----| ML | message1 | ML | message2 | ----- free ------|
  12126. // ^ ^ ^ ^
  12127. // buf tail head len
  12128. //
  12129. // Queue when q->tail > q->head:
  12130. // | ML | message2 |----- free ------| ML | message1 | 0 |---- free ----|
  12131. // ^ ^ ^ ^
  12132. // buf head tail len
  12133. void mg_queue_init(struct mg_queue *q, char *buf, size_t size) {
  12134. q->size = size;
  12135. q->buf = buf;
  12136. q->head = q->tail = 0;
  12137. }
  12138. static size_t mg_queue_read_len(struct mg_queue *q) {
  12139. uint32_t n = 0;
  12140. MG_MEMORY_BARRIER();
  12141. memcpy(&n, q->buf + q->tail, sizeof(n));
  12142. assert(q->tail + n + sizeof(n) <= q->size);
  12143. return n;
  12144. }
  12145. static void mg_queue_write_len(struct mg_queue *q, size_t len) {
  12146. uint32_t n = (uint32_t) len;
  12147. memcpy(q->buf + q->head, &n, sizeof(n));
  12148. MG_MEMORY_BARRIER();
  12149. }
  12150. size_t mg_queue_book(struct mg_queue *q, char **buf, size_t len) {
  12151. size_t space = 0, hs = sizeof(uint32_t) * 2; // *2 is for the 0 marker
  12152. if (q->head >= q->tail && q->head + len + hs <= q->size) {
  12153. space = q->size - q->head - hs; // There is enough space
  12154. } else if (q->head >= q->tail && q->tail > hs) {
  12155. mg_queue_write_len(q, 0); // Not enough space ahead
  12156. q->head = 0; // Wrap head to the beginning
  12157. }
  12158. if (q->head + hs + len < q->tail) space = q->tail - q->head - hs;
  12159. if (buf != NULL) *buf = q->buf + q->head + sizeof(uint32_t);
  12160. return space;
  12161. }
  12162. size_t mg_queue_next(struct mg_queue *q, char **buf) {
  12163. size_t len = 0;
  12164. if (q->tail != q->head) {
  12165. len = mg_queue_read_len(q);
  12166. if (len == 0) { // Zero (head wrapped) ?
  12167. q->tail = 0; // Reset tail to the start
  12168. if (q->head > q->tail) len = mg_queue_read_len(q); // Read again
  12169. }
  12170. }
  12171. if (buf != NULL) *buf = q->buf + q->tail + sizeof(uint32_t);
  12172. assert(q->tail + len <= q->size);
  12173. return len;
  12174. }
  12175. void mg_queue_add(struct mg_queue *q, size_t len) {
  12176. assert(len > 0);
  12177. mg_queue_write_len(q, len);
  12178. assert(q->head + sizeof(uint32_t) * 2 + len <= q->size);
  12179. q->head += len + sizeof(uint32_t);
  12180. }
  12181. void mg_queue_del(struct mg_queue *q, size_t len) {
  12182. q->tail += len + sizeof(uint32_t);
  12183. assert(q->tail + sizeof(uint32_t) <= q->size);
  12184. }
  12185. #ifdef MG_ENABLE_LINES
  12186. #line 1 "src/rpc.c"
  12187. #endif
  12188. void mg_rpc_add(struct mg_rpc **head, struct mg_str method,
  12189. void (*fn)(struct mg_rpc_req *), void *fn_data) {
  12190. struct mg_rpc *rpc = (struct mg_rpc *) mg_calloc(1, sizeof(*rpc));
  12191. if (rpc != NULL) {
  12192. rpc->method = mg_strdup(method);
  12193. rpc->fn = fn;
  12194. rpc->fn_data = fn_data;
  12195. rpc->next = *head, *head = rpc;
  12196. }
  12197. }
  12198. void mg_rpc_del(struct mg_rpc **head, void (*fn)(struct mg_rpc_req *)) {
  12199. struct mg_rpc *r;
  12200. while ((r = *head) != NULL) {
  12201. if (r->fn == fn || fn == NULL) {
  12202. *head = r->next;
  12203. mg_free((void *) r->method.buf);
  12204. mg_free(r);
  12205. } else {
  12206. head = &(*head)->next;
  12207. }
  12208. }
  12209. }
  12210. static void mg_rpc_call(struct mg_rpc_req *r, struct mg_str method) {
  12211. struct mg_rpc *h = r->head == NULL ? NULL : *r->head;
  12212. while (h != NULL && !mg_match(method, h->method, NULL)) h = h->next;
  12213. if (h != NULL) {
  12214. r->rpc = h;
  12215. h->fn(r);
  12216. } else {
  12217. mg_rpc_err(r, -32601, "\"%.*s not found\"", (int) method.len, method.buf);
  12218. }
  12219. }
  12220. void mg_rpc_process(struct mg_rpc_req *r) {
  12221. int len, off = mg_json_get(r->frame, "$.method", &len);
  12222. if (off > 0 && r->frame.buf[off] == '"') {
  12223. struct mg_str method = mg_str_n(&r->frame.buf[off + 1], (size_t) len - 2);
  12224. mg_rpc_call(r, method);
  12225. } else if ((off = mg_json_get(r->frame, "$.result", &len)) > 0 ||
  12226. (off = mg_json_get(r->frame, "$.error", &len)) > 0) {
  12227. mg_rpc_call(r, mg_str("")); // JSON response! call "" method handler
  12228. } else {
  12229. mg_rpc_err(r, -32700, "%m", mg_print_esc, (int) r->frame.len,
  12230. r->frame.buf); // Invalid
  12231. }
  12232. }
  12233. void mg_rpc_vok(struct mg_rpc_req *r, const char *fmt, va_list *ap) {
  12234. int len, off = mg_json_get(r->frame, "$.id", &len);
  12235. if (off > 0) {
  12236. mg_xprintf(r->pfn, r->pfn_data, "{%m:%.*s,%m:", mg_print_esc, 0, "id", len,
  12237. &r->frame.buf[off], mg_print_esc, 0, "result");
  12238. mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
  12239. mg_xprintf(r->pfn, r->pfn_data, "}");
  12240. }
  12241. }
  12242. void mg_rpc_ok(struct mg_rpc_req *r, const char *fmt, ...) {
  12243. va_list ap;
  12244. va_start(ap, fmt);
  12245. mg_rpc_vok(r, fmt, &ap);
  12246. va_end(ap);
  12247. }
  12248. void mg_rpc_verr(struct mg_rpc_req *r, int code, const char *fmt, va_list *ap) {
  12249. int len, off = mg_json_get(r->frame, "$.id", &len);
  12250. mg_xprintf(r->pfn, r->pfn_data, "{");
  12251. if (off > 0) {
  12252. mg_xprintf(r->pfn, r->pfn_data, "%m:%.*s,", mg_print_esc, 0, "id", len,
  12253. &r->frame.buf[off]);
  12254. }
  12255. mg_xprintf(r->pfn, r->pfn_data, "%m:{%m:%d,%m:", mg_print_esc, 0, "error",
  12256. mg_print_esc, 0, "code", code, mg_print_esc, 0, "message");
  12257. mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
  12258. mg_xprintf(r->pfn, r->pfn_data, "}}");
  12259. }
  12260. void mg_rpc_err(struct mg_rpc_req *r, int code, const char *fmt, ...) {
  12261. va_list ap;
  12262. va_start(ap, fmt);
  12263. mg_rpc_verr(r, code, fmt, &ap);
  12264. va_end(ap);
  12265. }
  12266. static size_t print_methods(mg_pfn_t pfn, void *pfn_data, va_list *ap) {
  12267. struct mg_rpc *h, **head = (struct mg_rpc **) va_arg(*ap, void **);
  12268. size_t len = 0;
  12269. for (h = *head; h != NULL; h = h->next) {
  12270. if (h->method.len == 0) continue; // Ignore response handler
  12271. len += mg_xprintf(pfn, pfn_data, "%s%m", h == *head ? "" : ",",
  12272. mg_print_esc, (int) h->method.len, h->method.buf);
  12273. }
  12274. return len;
  12275. }
  12276. void mg_rpc_list(struct mg_rpc_req *r) {
  12277. mg_rpc_ok(r, "[%M]", print_methods, r->head);
  12278. }
  12279. #ifdef MG_ENABLE_LINES
  12280. #line 1 "src/sha1.c"
  12281. #endif
  12282. /* Copyright(c) By Steve Reid <steve@edmweb.com> */
  12283. /* 100% Public Domain */
  12284. union char64long16 {
  12285. unsigned char c[64];
  12286. uint32_t l[16];
  12287. };
  12288. #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
  12289. static uint32_t blk0(union char64long16 *block, int i) {
  12290. if (MG_BIG_ENDIAN) {
  12291. } else {
  12292. block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) |
  12293. (rol(block->l[i], 8) & 0x00FF00FF);
  12294. }
  12295. return block->l[i];
  12296. }
  12297. /* Avoid redefine warning (ARM /usr/include/sys/ucontext.h define R0~R4) */
  12298. #undef blk
  12299. #undef R0
  12300. #undef R1
  12301. #undef R2
  12302. #undef R3
  12303. #undef R4
  12304. #define blk(i) \
  12305. (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ \
  12306. block->l[(i + 2) & 15] ^ block->l[i & 15], \
  12307. 1))
  12308. #define R0(v, w, x, y, z, i) \
  12309. z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5); \
  12310. w = rol(w, 30);
  12311. #define R1(v, w, x, y, z, i) \
  12312. z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
  12313. w = rol(w, 30);
  12314. #define R2(v, w, x, y, z, i) \
  12315. z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
  12316. w = rol(w, 30);
  12317. #define R3(v, w, x, y, z, i) \
  12318. z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
  12319. w = rol(w, 30);
  12320. #define R4(v, w, x, y, z, i) \
  12321. z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
  12322. w = rol(w, 30);
  12323. static void mg_sha1_transform(uint32_t state[5],
  12324. const unsigned char *buffer) {
  12325. uint32_t a, b, c, d, e;
  12326. union char64long16 block[1];
  12327. memcpy(block, buffer, 64);
  12328. a = state[0];
  12329. b = state[1];
  12330. c = state[2];
  12331. d = state[3];
  12332. e = state[4];
  12333. R0(a, b, c, d, e, 0);
  12334. R0(e, a, b, c, d, 1);
  12335. R0(d, e, a, b, c, 2);
  12336. R0(c, d, e, a, b, 3);
  12337. R0(b, c, d, e, a, 4);
  12338. R0(a, b, c, d, e, 5);
  12339. R0(e, a, b, c, d, 6);
  12340. R0(d, e, a, b, c, 7);
  12341. R0(c, d, e, a, b, 8);
  12342. R0(b, c, d, e, a, 9);
  12343. R0(a, b, c, d, e, 10);
  12344. R0(e, a, b, c, d, 11);
  12345. R0(d, e, a, b, c, 12);
  12346. R0(c, d, e, a, b, 13);
  12347. R0(b, c, d, e, a, 14);
  12348. R0(a, b, c, d, e, 15);
  12349. R1(e, a, b, c, d, 16);
  12350. R1(d, e, a, b, c, 17);
  12351. R1(c, d, e, a, b, 18);
  12352. R1(b, c, d, e, a, 19);
  12353. R2(a, b, c, d, e, 20);
  12354. R2(e, a, b, c, d, 21);
  12355. R2(d, e, a, b, c, 22);
  12356. R2(c, d, e, a, b, 23);
  12357. R2(b, c, d, e, a, 24);
  12358. R2(a, b, c, d, e, 25);
  12359. R2(e, a, b, c, d, 26);
  12360. R2(d, e, a, b, c, 27);
  12361. R2(c, d, e, a, b, 28);
  12362. R2(b, c, d, e, a, 29);
  12363. R2(a, b, c, d, e, 30);
  12364. R2(e, a, b, c, d, 31);
  12365. R2(d, e, a, b, c, 32);
  12366. R2(c, d, e, a, b, 33);
  12367. R2(b, c, d, e, a, 34);
  12368. R2(a, b, c, d, e, 35);
  12369. R2(e, a, b, c, d, 36);
  12370. R2(d, e, a, b, c, 37);
  12371. R2(c, d, e, a, b, 38);
  12372. R2(b, c, d, e, a, 39);
  12373. R3(a, b, c, d, e, 40);
  12374. R3(e, a, b, c, d, 41);
  12375. R3(d, e, a, b, c, 42);
  12376. R3(c, d, e, a, b, 43);
  12377. R3(b, c, d, e, a, 44);
  12378. R3(a, b, c, d, e, 45);
  12379. R3(e, a, b, c, d, 46);
  12380. R3(d, e, a, b, c, 47);
  12381. R3(c, d, e, a, b, 48);
  12382. R3(b, c, d, e, a, 49);
  12383. R3(a, b, c, d, e, 50);
  12384. R3(e, a, b, c, d, 51);
  12385. R3(d, e, a, b, c, 52);
  12386. R3(c, d, e, a, b, 53);
  12387. R3(b, c, d, e, a, 54);
  12388. R3(a, b, c, d, e, 55);
  12389. R3(e, a, b, c, d, 56);
  12390. R3(d, e, a, b, c, 57);
  12391. R3(c, d, e, a, b, 58);
  12392. R3(b, c, d, e, a, 59);
  12393. R4(a, b, c, d, e, 60);
  12394. R4(e, a, b, c, d, 61);
  12395. R4(d, e, a, b, c, 62);
  12396. R4(c, d, e, a, b, 63);
  12397. R4(b, c, d, e, a, 64);
  12398. R4(a, b, c, d, e, 65);
  12399. R4(e, a, b, c, d, 66);
  12400. R4(d, e, a, b, c, 67);
  12401. R4(c, d, e, a, b, 68);
  12402. R4(b, c, d, e, a, 69);
  12403. R4(a, b, c, d, e, 70);
  12404. R4(e, a, b, c, d, 71);
  12405. R4(d, e, a, b, c, 72);
  12406. R4(c, d, e, a, b, 73);
  12407. R4(b, c, d, e, a, 74);
  12408. R4(a, b, c, d, e, 75);
  12409. R4(e, a, b, c, d, 76);
  12410. R4(d, e, a, b, c, 77);
  12411. R4(c, d, e, a, b, 78);
  12412. R4(b, c, d, e, a, 79);
  12413. state[0] += a;
  12414. state[1] += b;
  12415. state[2] += c;
  12416. state[3] += d;
  12417. state[4] += e;
  12418. /* Erase working structures. The order of operations is important,
  12419. * used to ensure that compiler doesn't optimize those out. */
  12420. memset(block, 0, sizeof(block));
  12421. a = b = c = d = e = 0;
  12422. (void) a;
  12423. (void) b;
  12424. (void) c;
  12425. (void) d;
  12426. (void) e;
  12427. }
  12428. void mg_sha1_init(mg_sha1_ctx *context) {
  12429. context->state[0] = 0x67452301;
  12430. context->state[1] = 0xEFCDAB89;
  12431. context->state[2] = 0x98BADCFE;
  12432. context->state[3] = 0x10325476;
  12433. context->state[4] = 0xC3D2E1F0;
  12434. context->count[0] = context->count[1] = 0;
  12435. }
  12436. void mg_sha1_update(mg_sha1_ctx *context, const unsigned char *data,
  12437. size_t len) {
  12438. size_t i, j;
  12439. j = context->count[0];
  12440. if ((context->count[0] += (uint32_t) len << 3) < j) context->count[1]++;
  12441. context->count[1] += (uint32_t) (len >> 29);
  12442. j = (j >> 3) & 63;
  12443. if ((j + len) > 63) {
  12444. memcpy(&context->buffer[j], data, (i = 64 - j));
  12445. mg_sha1_transform(context->state, context->buffer);
  12446. for (; i + 63 < len; i += 64) {
  12447. mg_sha1_transform(context->state, &data[i]);
  12448. }
  12449. j = 0;
  12450. } else
  12451. i = 0;
  12452. memcpy(&context->buffer[j], &data[i], len - i);
  12453. }
  12454. void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *context) {
  12455. unsigned i;
  12456. unsigned char finalcount[8], c;
  12457. for (i = 0; i < 8; i++) {
  12458. finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >>
  12459. ((3 - (i & 3)) * 8)) &
  12460. 255);
  12461. }
  12462. c = 0200;
  12463. mg_sha1_update(context, &c, 1);
  12464. while ((context->count[0] & 504) != 448) {
  12465. c = 0000;
  12466. mg_sha1_update(context, &c, 1);
  12467. }
  12468. mg_sha1_update(context, finalcount, 8);
  12469. for (i = 0; i < 20; i++) {
  12470. digest[i] =
  12471. (unsigned char) ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
  12472. }
  12473. memset(context, '\0', sizeof(*context));
  12474. memset(&finalcount, '\0', sizeof(finalcount));
  12475. }
  12476. #ifdef MG_ENABLE_LINES
  12477. #line 1 "src/sha256.c"
  12478. #endif
  12479. // https://github.com/B-Con/crypto-algorithms
  12480. // Author: Brad Conte (brad AT bradconte.com)
  12481. // Disclaimer: This code is presented "as is" without any guarantees.
  12482. // Details: Defines the API for the corresponding SHA1 implementation.
  12483. // Copyright: public domain
  12484. #define ror(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
  12485. #define ch(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
  12486. #define maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
  12487. #define ep0(x) (ror(x, 2) ^ ror(x, 13) ^ ror(x, 22))
  12488. #define ep1(x) (ror(x, 6) ^ ror(x, 11) ^ ror(x, 25))
  12489. #define sig0(x) (ror(x, 7) ^ ror(x, 18) ^ ((x) >> 3))
  12490. #define sig1(x) (ror(x, 17) ^ ror(x, 19) ^ ((x) >> 10))
  12491. static const uint32_t mg_sha256_k[64] = {
  12492. 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
  12493. 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
  12494. 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
  12495. 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  12496. 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
  12497. 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
  12498. 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
  12499. 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  12500. 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
  12501. 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
  12502. 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
  12503. void mg_sha256_init(mg_sha256_ctx *ctx) {
  12504. ctx->len = 0;
  12505. ctx->bits = 0;
  12506. ctx->state[0] = 0x6a09e667;
  12507. ctx->state[1] = 0xbb67ae85;
  12508. ctx->state[2] = 0x3c6ef372;
  12509. ctx->state[3] = 0xa54ff53a;
  12510. ctx->state[4] = 0x510e527f;
  12511. ctx->state[5] = 0x9b05688c;
  12512. ctx->state[6] = 0x1f83d9ab;
  12513. ctx->state[7] = 0x5be0cd19;
  12514. }
  12515. static void mg_sha256_chunk(mg_sha256_ctx *ctx) {
  12516. int i, j;
  12517. uint32_t a, b, c, d, e, f, g, h;
  12518. uint32_t m[64];
  12519. for (i = 0, j = 0; i < 16; ++i, j += 4)
  12520. m[i] = (uint32_t) (((uint32_t) ctx->buffer[j] << 24) |
  12521. ((uint32_t) ctx->buffer[j + 1] << 16) |
  12522. ((uint32_t) ctx->buffer[j + 2] << 8) |
  12523. ((uint32_t) ctx->buffer[j + 3]));
  12524. for (; i < 64; ++i)
  12525. m[i] = sig1(m[i - 2]) + m[i - 7] + sig0(m[i - 15]) + m[i - 16];
  12526. a = ctx->state[0];
  12527. b = ctx->state[1];
  12528. c = ctx->state[2];
  12529. d = ctx->state[3];
  12530. e = ctx->state[4];
  12531. f = ctx->state[5];
  12532. g = ctx->state[6];
  12533. h = ctx->state[7];
  12534. for (i = 0; i < 64; ++i) {
  12535. uint32_t t1 = h + ep1(e) + ch(e, f, g) + mg_sha256_k[i] + m[i];
  12536. uint32_t t2 = ep0(a) + maj(a, b, c);
  12537. h = g;
  12538. g = f;
  12539. f = e;
  12540. e = d + t1;
  12541. d = c;
  12542. c = b;
  12543. b = a;
  12544. a = t1 + t2;
  12545. }
  12546. ctx->state[0] += a;
  12547. ctx->state[1] += b;
  12548. ctx->state[2] += c;
  12549. ctx->state[3] += d;
  12550. ctx->state[4] += e;
  12551. ctx->state[5] += f;
  12552. ctx->state[6] += g;
  12553. ctx->state[7] += h;
  12554. }
  12555. void mg_sha256_update(mg_sha256_ctx *ctx, const unsigned char *data,
  12556. size_t len) {
  12557. size_t i;
  12558. for (i = 0; i < len; i++) {
  12559. ctx->buffer[ctx->len] = data[i];
  12560. if ((++ctx->len) == 64) {
  12561. mg_sha256_chunk(ctx);
  12562. ctx->bits += 512;
  12563. ctx->len = 0;
  12564. }
  12565. }
  12566. }
  12567. // TODO: make final reusable (remove side effects)
  12568. void mg_sha256_final(unsigned char digest[32], mg_sha256_ctx *ctx) {
  12569. uint32_t i = ctx->len;
  12570. if (i < 56) {
  12571. ctx->buffer[i++] = 0x80;
  12572. while (i < 56) {
  12573. ctx->buffer[i++] = 0x00;
  12574. }
  12575. } else {
  12576. ctx->buffer[i++] = 0x80;
  12577. while (i < 64) {
  12578. ctx->buffer[i++] = 0x00;
  12579. }
  12580. mg_sha256_chunk(ctx);
  12581. memset(ctx->buffer, 0, 56);
  12582. }
  12583. ctx->bits += ctx->len * 8;
  12584. ctx->buffer[63] = (uint8_t) ((ctx->bits) & 0xff);
  12585. ctx->buffer[62] = (uint8_t) ((ctx->bits >> 8) & 0xff);
  12586. ctx->buffer[61] = (uint8_t) ((ctx->bits >> 16) & 0xff);
  12587. ctx->buffer[60] = (uint8_t) ((ctx->bits >> 24) & 0xff);
  12588. ctx->buffer[59] = (uint8_t) ((ctx->bits >> 32) & 0xff);
  12589. ctx->buffer[58] = (uint8_t) ((ctx->bits >> 40) & 0xff);
  12590. ctx->buffer[57] = (uint8_t) ((ctx->bits >> 48) & 0xff);
  12591. ctx->buffer[56] = (uint8_t) ((ctx->bits >> 56) & 0xff);
  12592. mg_sha256_chunk(ctx);
  12593. for (i = 0; i < 4; ++i) {
  12594. digest[i] = (uint8_t) ((ctx->state[0] >> (24 - i * 8)) & 0xff);
  12595. digest[i + 4] = (uint8_t) ((ctx->state[1] >> (24 - i * 8)) & 0xff);
  12596. digest[i + 8] = (uint8_t) ((ctx->state[2] >> (24 - i * 8)) & 0xff);
  12597. digest[i + 12] = (uint8_t) ((ctx->state[3] >> (24 - i * 8)) & 0xff);
  12598. digest[i + 16] = (uint8_t) ((ctx->state[4] >> (24 - i * 8)) & 0xff);
  12599. digest[i + 20] = (uint8_t) ((ctx->state[5] >> (24 - i * 8)) & 0xff);
  12600. digest[i + 24] = (uint8_t) ((ctx->state[6] >> (24 - i * 8)) & 0xff);
  12601. digest[i + 28] = (uint8_t) ((ctx->state[7] >> (24 - i * 8)) & 0xff);
  12602. }
  12603. }
  12604. void mg_sha256(uint8_t dst[32], uint8_t *data, size_t datasz) {
  12605. mg_sha256_ctx ctx;
  12606. mg_sha256_init(&ctx);
  12607. mg_sha256_update(&ctx, data, datasz);
  12608. mg_sha256_final(dst, &ctx);
  12609. }
  12610. void mg_hmac_sha256(uint8_t dst[32], uint8_t *key, size_t keysz, uint8_t *data,
  12611. size_t datasz) {
  12612. mg_sha256_ctx ctx;
  12613. uint8_t k[64] = {0};
  12614. uint8_t o_pad[64], i_pad[64];
  12615. unsigned int i;
  12616. memset(i_pad, 0x36, sizeof(i_pad));
  12617. memset(o_pad, 0x5c, sizeof(o_pad));
  12618. if (keysz < 64) {
  12619. if (keysz > 0) memmove(k, key, keysz);
  12620. } else {
  12621. mg_sha256_init(&ctx);
  12622. mg_sha256_update(&ctx, key, keysz);
  12623. mg_sha256_final(k, &ctx);
  12624. }
  12625. for (i = 0; i < sizeof(k); i++) {
  12626. i_pad[i] ^= k[i];
  12627. o_pad[i] ^= k[i];
  12628. }
  12629. mg_sha256_init(&ctx);
  12630. mg_sha256_update(&ctx, i_pad, sizeof(i_pad));
  12631. mg_sha256_update(&ctx, data, datasz);
  12632. mg_sha256_final(dst, &ctx);
  12633. mg_sha256_init(&ctx);
  12634. mg_sha256_update(&ctx, o_pad, sizeof(o_pad));
  12635. mg_sha256_update(&ctx, dst, 32);
  12636. mg_sha256_final(dst, &ctx);
  12637. }
  12638. #define rotr64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
  12639. #define ep064(x) (rotr64(x, 28) ^ rotr64(x, 34) ^ rotr64(x, 39))
  12640. #define ep164(x) (rotr64(x, 14) ^ rotr64(x, 18) ^ rotr64(x, 41))
  12641. #define sig064(x) (rotr64(x, 1) ^ rotr64(x, 8) ^ ((x) >> 7))
  12642. #define sig164(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ ((x) >> 6))
  12643. static const uint64_t mg_sha256_k2[80] = {
  12644. #if defined(__DCC__)
  12645. 0x428a2f98d728ae22ull, 0x7137449123ef65cdull, 0xb5c0fbcfec4d3b2full,
  12646. 0xe9b5dba58189dbbcull, 0x3956c25bf348b538ull, 0x59f111f1b605d019ull,
  12647. 0x923f82a4af194f9bull, 0xab1c5ed5da6d8118ull, 0xd807aa98a3030242ull,
  12648. 0x12835b0145706fbeull, 0x243185be4ee4b28cull, 0x550c7dc3d5ffb4e2ull,
  12649. 0x72be5d74f27b896full, 0x80deb1fe3b1696b1ull, 0x9bdc06a725c71235ull,
  12650. 0xc19bf174cf692694ull, 0xe49b69c19ef14ad2ull, 0xefbe4786384f25e3ull,
  12651. 0x0fc19dc68b8cd5b5ull, 0x240ca1cc77ac9c65ull, 0x2de92c6f592b0275ull,
  12652. 0x4a7484aa6ea6e483ull, 0x5cb0a9dcbd41fbd4ull, 0x76f988da831153b5ull,
  12653. 0x983e5152ee66dfabull, 0xa831c66d2db43210ull, 0xb00327c898fb213full,
  12654. 0xbf597fc7beef0ee4ull, 0xc6e00bf33da88fc2ull, 0xd5a79147930aa725ull,
  12655. 0x06ca6351e003826full, 0x142929670a0e6e70ull, 0x27b70a8546d22ffcull,
  12656. 0x2e1b21385c26c926ull, 0x4d2c6dfc5ac42aedull, 0x53380d139d95b3dfull,
  12657. 0x650a73548baf63deull, 0x766a0abb3c77b2a8ull, 0x81c2c92e47edaee6ull,
  12658. 0x92722c851482353bull, 0xa2bfe8a14cf10364ull, 0xa81a664bbc423001ull,
  12659. 0xc24b8b70d0f89791ull, 0xc76c51a30654be30ull, 0xd192e819d6ef5218ull,
  12660. 0xd69906245565a910ull, 0xf40e35855771202aull, 0x106aa07032bbd1b8ull,
  12661. 0x19a4c116b8d2d0c8ull, 0x1e376c085141ab53ull, 0x2748774cdf8eeb99ull,
  12662. 0x34b0bcb5e19b48a8ull, 0x391c0cb3c5c95a63ull, 0x4ed8aa4ae3418acbull,
  12663. 0x5b9cca4f7763e373ull, 0x682e6ff3d6b2b8a3ull, 0x748f82ee5defb2fcull,
  12664. 0x78a5636f43172f60ull, 0x84c87814a1f0ab72ull, 0x8cc702081a6439ecull,
  12665. 0x90befffa23631e28ull, 0xa4506cebde82bde9ull, 0xbef9a3f7b2c67915ull,
  12666. 0xc67178f2e372532bull, 0xca273eceea26619cull, 0xd186b8c721c0c207ull,
  12667. 0xeada7dd6cde0eb1eull, 0xf57d4f7fee6ed178ull, 0x06f067aa72176fbaull,
  12668. 0x0a637dc5a2c898a6ull, 0x113f9804bef90daeull, 0x1b710b35131c471bull,
  12669. 0x28db77f523047d84ull, 0x32caab7b40c72493ull, 0x3c9ebe0a15c9bebcull,
  12670. 0x431d67c49c100d4cull, 0x4cc5d4becb3e42b6ull, 0x597f299cfc657e2aull,
  12671. 0x5fcb6fab3ad6faecull, 0x6c44198c4a475817ull
  12672. #else
  12673. 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
  12674. 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
  12675. 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
  12676. 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
  12677. 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
  12678. 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
  12679. 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
  12680. 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
  12681. 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
  12682. 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
  12683. 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
  12684. 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
  12685. 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
  12686. 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
  12687. 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
  12688. 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
  12689. 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
  12690. 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
  12691. 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
  12692. 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
  12693. 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
  12694. 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
  12695. 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
  12696. 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
  12697. 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
  12698. 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
  12699. 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
  12700. #endif
  12701. };
  12702. static void mg_sha384_transform(mg_sha384_ctx *ctx, const uint8_t data[]) {
  12703. uint64_t m[80];
  12704. uint64_t a, b, c, d, e, f, g, h;
  12705. int i, j;
  12706. for (i = 0, j = 0; i < 16; ++i, j += 8)
  12707. m[i] = ((uint64_t) data[j] << 56) | ((uint64_t) data[j + 1] << 48) |
  12708. ((uint64_t) data[j + 2] << 40) | ((uint64_t) data[j + 3] << 32) |
  12709. ((uint64_t) data[j + 4] << 24) | ((uint64_t) data[j + 5] << 16) |
  12710. ((uint64_t) data[j + 6] << 8) | ((uint64_t) data[j + 7]);
  12711. for (; i < 80; ++i)
  12712. m[i] = sig164(m[i - 2]) + m[i - 7] + sig064(m[i - 15]) + m[i - 16];
  12713. a = ctx->state[0];
  12714. b = ctx->state[1];
  12715. c = ctx->state[2];
  12716. d = ctx->state[3];
  12717. e = ctx->state[4];
  12718. f = ctx->state[5];
  12719. g = ctx->state[6];
  12720. h = ctx->state[7];
  12721. for (i = 0; i < 80; ++i) {
  12722. uint64_t t1 = h + ep164(e) + ch(e, f, g) + mg_sha256_k2[i] + m[i];
  12723. uint64_t t2 = ep064(a) + maj(a, b, c);
  12724. h = g;
  12725. g = f;
  12726. f = e;
  12727. e = d + t1;
  12728. d = c;
  12729. c = b;
  12730. b = a;
  12731. a = t1 + t2;
  12732. }
  12733. ctx->state[0] += a;
  12734. ctx->state[1] += b;
  12735. ctx->state[2] += c;
  12736. ctx->state[3] += d;
  12737. ctx->state[4] += e;
  12738. ctx->state[5] += f;
  12739. ctx->state[6] += g;
  12740. ctx->state[7] += h;
  12741. }
  12742. void mg_sha384_init(mg_sha384_ctx *ctx) {
  12743. ctx->datalen = 0;
  12744. ctx->bitlen[0] = 0;
  12745. ctx->bitlen[1] = 0;
  12746. #if defined(__DCC__)
  12747. ctx->state[0] = 0xcbbb9d5dc1059ed8ull;
  12748. ctx->state[1] = 0x629a292a367cd507ull;
  12749. ctx->state[2] = 0x9159015a3070dd17ull;
  12750. ctx->state[3] = 0x152fecd8f70e5939ull;
  12751. ctx->state[4] = 0x67332667ffc00b31ull;
  12752. ctx->state[5] = 0x8eb44a8768581511ull;
  12753. ctx->state[6] = 0xdb0c2e0d64f98fa7ull;
  12754. ctx->state[7] = 0x47b5481dbefa4fa4ull;
  12755. #else
  12756. ctx->state[0] = 0xcbbb9d5dc1059ed8;
  12757. ctx->state[1] = 0x629a292a367cd507;
  12758. ctx->state[2] = 0x9159015a3070dd17;
  12759. ctx->state[3] = 0x152fecd8f70e5939;
  12760. ctx->state[4] = 0x67332667ffc00b31;
  12761. ctx->state[5] = 0x8eb44a8768581511;
  12762. ctx->state[6] = 0xdb0c2e0d64f98fa7;
  12763. ctx->state[7] = 0x47b5481dbefa4fa4;
  12764. #endif
  12765. }
  12766. void mg_sha384_update(mg_sha384_ctx *ctx, const uint8_t *data, size_t len) {
  12767. size_t i;
  12768. for (i = 0; i < len; ++i) {
  12769. ctx->buffer[ctx->datalen] = data[i];
  12770. ctx->datalen++;
  12771. if (ctx->datalen == 128) {
  12772. mg_sha384_transform(ctx, ctx->buffer);
  12773. ctx->bitlen[1] += 1024;
  12774. if (ctx->bitlen[1] < 1024) ctx->bitlen[0]++;
  12775. ctx->datalen = 0;
  12776. }
  12777. }
  12778. }
  12779. void mg_sha384_final(uint8_t hash[48], mg_sha384_ctx *ctx) {
  12780. size_t i = ctx->datalen;
  12781. if (ctx->datalen < 112) {
  12782. ctx->buffer[i++] = 0x80;
  12783. while (i < 112) ctx->buffer[i++] = 0x00;
  12784. } else {
  12785. ctx->buffer[i++] = 0x80;
  12786. while (i < 128) ctx->buffer[i++] = 0x00;
  12787. mg_sha384_transform(ctx, ctx->buffer);
  12788. memset(ctx->buffer, 0, 112);
  12789. }
  12790. ctx->bitlen[1] += ctx->datalen * 8;
  12791. if (ctx->bitlen[1] < ctx->datalen * 8) ctx->bitlen[0]++;
  12792. ctx->buffer[127] = (uint8_t) (ctx->bitlen[1]);
  12793. ctx->buffer[126] = (uint8_t) (ctx->bitlen[1] >> 8);
  12794. ctx->buffer[125] = (uint8_t) (ctx->bitlen[1] >> 16);
  12795. ctx->buffer[124] = (uint8_t) (ctx->bitlen[1] >> 24);
  12796. ctx->buffer[123] = (uint8_t) (ctx->bitlen[1] >> 32);
  12797. ctx->buffer[122] = (uint8_t) (ctx->bitlen[1] >> 40);
  12798. ctx->buffer[121] = (uint8_t) (ctx->bitlen[1] >> 48);
  12799. ctx->buffer[120] = (uint8_t) (ctx->bitlen[1] >> 56);
  12800. ctx->buffer[119] = (uint8_t) (ctx->bitlen[0]);
  12801. ctx->buffer[118] = (uint8_t) (ctx->bitlen[0] >> 8);
  12802. ctx->buffer[117] = (uint8_t) (ctx->bitlen[0] >> 16);
  12803. ctx->buffer[116] = (uint8_t) (ctx->bitlen[0] >> 24);
  12804. ctx->buffer[115] = (uint8_t) (ctx->bitlen[0] >> 32);
  12805. ctx->buffer[114] = (uint8_t) (ctx->bitlen[0] >> 40);
  12806. ctx->buffer[113] = (uint8_t) (ctx->bitlen[0] >> 48);
  12807. ctx->buffer[112] = (uint8_t) (ctx->bitlen[0] >> 56);
  12808. mg_sha384_transform(ctx, ctx->buffer);
  12809. for (i = 0; i < 6; ++i) {
  12810. hash[i * 8] = (uint8_t) ((ctx->state[i] >> 56) & 0xff);
  12811. hash[i * 8 + 1] = (uint8_t) ((ctx->state[i] >> 48) & 0xff);
  12812. hash[i * 8 + 2] = (uint8_t) ((ctx->state[i] >> 40) & 0xff);
  12813. hash[i * 8 + 3] = (uint8_t) ((ctx->state[i] >> 32) & 0xff);
  12814. hash[i * 8 + 4] = (uint8_t) ((ctx->state[i] >> 24) & 0xff);
  12815. hash[i * 8 + 5] = (uint8_t) ((ctx->state[i] >> 16) & 0xff);
  12816. hash[i * 8 + 6] = (uint8_t) ((ctx->state[i] >> 8) & 0xff);
  12817. hash[i * 8 + 7] = (uint8_t) (ctx->state[i] & 0xff);
  12818. }
  12819. }
  12820. void mg_sha384(uint8_t dst[48], uint8_t *data, size_t datasz) {
  12821. mg_sha384_ctx ctx;
  12822. mg_sha384_init(&ctx);
  12823. mg_sha384_update(&ctx, data, datasz);
  12824. mg_sha384_final(dst, &ctx);
  12825. }
  12826. #ifdef MG_ENABLE_LINES
  12827. #line 1 "src/sntp.c"
  12828. #endif
  12829. #define SNTP_TIME_OFFSET 2208988800U // (1970 - 1900) in seconds
  12830. #define SNTP_MAX_FRAC 4294967295.0 // 2 ** 32 - 1
  12831. uint64_t mg_boot_timestamp_ms = 0; // Updated by SNTP
  12832. uint64_t mg_now(void) {
  12833. return mg_millis() + mg_boot_timestamp_ms;
  12834. }
  12835. static int64_t gettimestamp(const uint32_t *data) {
  12836. uint32_t sec = mg_ntohl(data[0]), frac = mg_ntohl(data[1]);
  12837. if (sec) sec -= SNTP_TIME_OFFSET;
  12838. return ((int64_t) sec) * 1000 + (int64_t) (frac / SNTP_MAX_FRAC * 1000.0);
  12839. }
  12840. int64_t mg_sntp_parse(const unsigned char *buf, size_t len) {
  12841. int64_t epoch_milliseconds = -1;
  12842. int mode = len > 0 ? buf[0] & 7 : 0;
  12843. int version = len > 0 ? (buf[0] >> 3) & 7 : 0;
  12844. if (len < 48) {
  12845. MG_ERROR(("%s", "corrupt packet"));
  12846. } else if (mode != 4 && mode != 5) {
  12847. MG_ERROR(("%s", "not a server reply"));
  12848. } else if (buf[1] == 0) {
  12849. MG_ERROR(("%s", "server sent a kiss of death"));
  12850. } else if (version == 4 || version == 3) {
  12851. // int64_t ref = gettimestamp((uint32_t *) &buf[16]);
  12852. int64_t origin_time = gettimestamp((uint32_t *) &buf[24]);
  12853. int64_t receive_time = gettimestamp((uint32_t *) &buf[32]);
  12854. int64_t transmit_time = gettimestamp((uint32_t *) &buf[40]);
  12855. int64_t now = (int64_t) mg_millis();
  12856. int64_t latency = (now - origin_time) - (transmit_time - receive_time);
  12857. epoch_milliseconds = transmit_time + latency / 2;
  12858. mg_boot_timestamp_ms = (uint64_t) (epoch_milliseconds - now);
  12859. } else {
  12860. MG_ERROR(("unexpected version: %d", version));
  12861. }
  12862. return epoch_milliseconds;
  12863. }
  12864. static void sntp_cb(struct mg_connection *c, int ev, void *ev_data) {
  12865. uint64_t *expiration_time = (uint64_t *) c->data;
  12866. if (ev == MG_EV_OPEN) {
  12867. *expiration_time = mg_millis() + 3000; // Store expiration time in 3s
  12868. } else if (ev == MG_EV_CONNECT) {
  12869. mg_sntp_request(c);
  12870. } else if (ev == MG_EV_READ) {
  12871. int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len);
  12872. if (milliseconds > 0) {
  12873. mg_boot_timestamp_ms = (uint64_t) milliseconds - mg_millis();
  12874. mg_call(c, MG_EV_SNTP_TIME, (uint64_t *) &milliseconds);
  12875. MG_DEBUG(("%lu got time: %lld ms from epoch", c->id, milliseconds));
  12876. }
  12877. // mg_iobuf_del(&c->recv, 0, c->recv.len); // Free receive buffer
  12878. c->is_closing = 1;
  12879. } else if (ev == MG_EV_POLL) {
  12880. if (mg_millis() > *expiration_time) c->is_closing = 1;
  12881. } else if (ev == MG_EV_CLOSE) {
  12882. }
  12883. (void) ev_data;
  12884. }
  12885. void mg_sntp_request(struct mg_connection *c) {
  12886. if (c->is_resolving) {
  12887. MG_ERROR(("%lu wait until resolved", c->id));
  12888. } else {
  12889. int64_t now = (int64_t) mg_millis(); // Use int64_t, for vc98
  12890. uint8_t buf[48] = {0};
  12891. uint32_t *t = (uint32_t *) &buf[40];
  12892. double frac = ((double) (now % 1000)) / 1000.0 * SNTP_MAX_FRAC;
  12893. buf[0] = (0 << 6) | (4 << 3) | 3;
  12894. t[0] = mg_htonl((uint32_t) (now / 1000) + SNTP_TIME_OFFSET);
  12895. t[1] = mg_htonl((uint32_t) frac);
  12896. mg_send(c, buf, sizeof(buf));
  12897. }
  12898. }
  12899. struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
  12900. mg_event_handler_t fn, void *fn_data) {
  12901. if (url == NULL) url = "udp://time.google.com:123";
  12902. return mg_connect_svc(mgr, url, fn, fn_data, sntp_cb, NULL);
  12903. }
  12904. #ifdef MG_ENABLE_LINES
  12905. #line 1 "src/sock.c"
  12906. #endif
  12907. #if MG_ENABLE_SOCKET
  12908. #ifndef closesocket
  12909. #define closesocket(x) close(x)
  12910. #endif
  12911. #define FD(c_) ((MG_SOCKET_TYPE) (size_t) (c_)->fd)
  12912. #define S2PTR(s_) ((void *) (size_t) (s_))
  12913. #ifndef MSG_NONBLOCKING
  12914. #define MSG_NONBLOCKING 0
  12915. #endif
  12916. #ifndef AF_INET6
  12917. #define AF_INET6 10
  12918. #endif
  12919. #ifndef MG_SOCK_ERR
  12920. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? errno : 0)
  12921. #endif
  12922. #ifndef MG_SOCK_INTR
  12923. #define MG_SOCK_INTR(fd) (fd == MG_INVALID_SOCKET && MG_SOCK_ERR(-1) == EINTR)
  12924. #endif
  12925. #ifndef MG_SOCK_PENDING
  12926. #define MG_SOCK_PENDING(errcode) \
  12927. (((errcode) < 0) && (errno == EINPROGRESS || errno == EWOULDBLOCK))
  12928. #endif
  12929. #ifndef MG_SOCK_RESET
  12930. #define MG_SOCK_RESET(errcode) \
  12931. (((errcode) < 0) && (errno == EPIPE || errno == ECONNRESET))
  12932. #endif
  12933. union usa {
  12934. struct sockaddr sa;
  12935. struct sockaddr_in sin;
  12936. #if MG_ENABLE_IPV6
  12937. struct sockaddr_in6 sin6;
  12938. #endif
  12939. };
  12940. static socklen_t tousa(struct mg_addr *a, union usa *usa) {
  12941. socklen_t len = sizeof(usa->sin);
  12942. memset(usa, 0, sizeof(*usa));
  12943. usa->sin.sin_family = AF_INET;
  12944. usa->sin.sin_port = a->port;
  12945. memcpy(&usa->sin.sin_addr, a->addr.ip, sizeof(uint32_t));
  12946. #if MG_ENABLE_IPV6
  12947. if (a->is_ip6) {
  12948. usa->sin.sin_family = AF_INET6;
  12949. usa->sin6.sin6_port = a->port;
  12950. usa->sin6.sin6_scope_id = a->scope_id;
  12951. memcpy(&usa->sin6.sin6_addr, a->addr.ip, sizeof(a->addr.ip));
  12952. len = sizeof(usa->sin6);
  12953. }
  12954. #endif
  12955. return len;
  12956. }
  12957. static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
  12958. a->is_ip6 = is_ip6;
  12959. #if MG_ENABLE_IPV6
  12960. if (is_ip6) {
  12961. memcpy(a->addr.ip, &usa->sin6.sin6_addr, sizeof(a->addr.ip));
  12962. a->port = usa->sin6.sin6_port;
  12963. a->scope_id = (uint8_t) usa->sin6.sin6_scope_id;
  12964. } else
  12965. #endif
  12966. {
  12967. a->port = usa->sin.sin_port;
  12968. memcpy(&a->addr.ip, &usa->sin.sin_addr, sizeof(uint32_t));
  12969. }
  12970. }
  12971. static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
  12972. union usa usa;
  12973. socklen_t n = sizeof(usa);
  12974. if (getsockname(fd, &usa.sa, &n) == 0) {
  12975. tomgaddr(&usa, addr, n != sizeof(usa.sin));
  12976. }
  12977. }
  12978. // Get the local 'addr' the stack will use to connect to 'to'
  12979. void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to,
  12980. struct mg_addr *addr);
  12981. void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to,
  12982. struct mg_addr *addr) {
  12983. union usa usa;
  12984. socklen_t slen;
  12985. MG_SOCKET_TYPE fd;
  12986. int rc, af = to->is_ip6 ? AF_INET6 : AF_INET;
  12987. fd = socket(af, SOCK_DGRAM, IPPROTO_UDP);
  12988. if (fd == MG_INVALID_SOCKET) {
  12989. mg_error(c, "socket(): %d", MG_SOCK_ERR(-1));
  12990. return;
  12991. }
  12992. // NOTE(): TI-RTOS NDK may require binding
  12993. slen = tousa(to, &usa);
  12994. if ((rc = connect(fd, &usa.sa, slen)) != 0) {
  12995. mg_error(c, "connect: %d", MG_SOCK_ERR(rc));
  12996. } else {
  12997. setlocaddr(fd, addr);
  12998. }
  12999. closesocket(fd);
  13000. }
  13001. static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
  13002. if (n == MG_IO_WAIT) {
  13003. // Do nothing
  13004. } else if (n <= 0) {
  13005. c->is_closing = 1; // Termination. Don't call mg_error(): #1529
  13006. } else if (n > 0) {
  13007. if (c->is_hexdumping) {
  13008. MG_INFO(("\n-- %lu %M %s %M %ld", c->id, mg_print_ip_port, &c->loc,
  13009. r ? "<-" : "->", mg_print_ip_port, &c->rem, n));
  13010. mg_hexdump(buf, (size_t) n);
  13011. }
  13012. if (r) {
  13013. c->recv.len += (size_t) n;
  13014. mg_call(c, MG_EV_READ, &n);
  13015. } else {
  13016. mg_iobuf_del(&c->send, 0, (size_t) n);
  13017. // if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
  13018. if (c->send.len == 0) {
  13019. MG_EPOLL_MOD(c, 0);
  13020. }
  13021. mg_call(c, MG_EV_WRITE, &n);
  13022. }
  13023. }
  13024. }
  13025. long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
  13026. long n;
  13027. if (c->is_udp) {
  13028. union usa usa;
  13029. socklen_t slen = tousa(&c->rem, &usa);
  13030. n = sendto(FD(c), (char *) buf, len, 0, &usa.sa, slen);
  13031. if (n > 0) setlocaddr(FD(c), &c->loc);
  13032. } else {
  13033. n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
  13034. }
  13035. MG_VERBOSE(("%lu %ld %d", c->id, n, MG_SOCK_ERR(n)));
  13036. if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
  13037. if (MG_SOCK_RESET(n)) return MG_IO_ERR; // See #1507, #3031
  13038. if (n <= 0) return MG_IO_ERR;
  13039. return n;
  13040. }
  13041. bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
  13042. if (c->is_udp) {
  13043. long n = mg_io_send(c, buf, len);
  13044. MG_DEBUG(("%lu %ld %lu:%lu:%lu %ld err %d", c->id, c->fd, c->send.len,
  13045. c->recv.len, c->rtls.len, n, MG_SOCK_ERR(n)));
  13046. iolog(c, (char *) buf, n, false);
  13047. return n > 0;
  13048. } else {
  13049. return len == 0 || mg_iobuf_add(&c->send, c->send.len, buf, len) > 0;
  13050. // returning 0 means an OOM condition (iobuf couldn't resize), yet this is
  13051. // so far recoverable, let the caller decide
  13052. }
  13053. }
  13054. static void mg_set_non_blocking_mode(MG_SOCKET_TYPE fd) {
  13055. #if defined(MG_CUSTOM_NONBLOCK)
  13056. MG_CUSTOM_NONBLOCK(fd);
  13057. #elif MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
  13058. unsigned long on = 1;
  13059. ioctlsocket(fd, FIONBIO, &on);
  13060. #elif MG_ENABLE_RL
  13061. unsigned long on = 1;
  13062. ioctlsocket(fd, FIONBIO, &on);
  13063. #elif MG_ENABLE_FREERTOS_TCP
  13064. const BaseType_t off = 0;
  13065. if (setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off)) != 0) (void) 0;
  13066. if (setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off)) != 0) (void) 0;
  13067. #elif MG_ENABLE_LWIP
  13068. lwip_fcntl(fd, F_SETFL, O_NONBLOCK);
  13069. #elif MG_ARCH == MG_ARCH_THREADX
  13070. // NetxDuo fails to send large blocks of data to the non-blocking sockets
  13071. (void) fd;
  13072. // fcntl(fd, F_SETFL, O_NONBLOCK);
  13073. #elif MG_ARCH == MG_ARCH_TIRTOS
  13074. int val = 0;
  13075. setsockopt(fd, SOL_SOCKET, SO_BLOCKING, &val, sizeof(val));
  13076. // SPRU524J section 3.3.3 page 63, SO_SNDLOWAT
  13077. int sz = sizeof(val);
  13078. getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &sz);
  13079. val /= 2; // set send low-water mark at half send buffer size
  13080. setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val));
  13081. #else
  13082. fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); // Non-blocking mode
  13083. fcntl(fd, F_SETFD, FD_CLOEXEC); // Set close-on-exec
  13084. #endif
  13085. }
  13086. void mg_multicast_add(struct mg_connection *c, char *ip);
  13087. void mg_multicast_add(struct mg_connection *c, char *ip) {
  13088. #if MG_ENABLE_RL
  13089. MG_ERROR(("unsupported"));
  13090. #elif MG_ENABLE_FREERTOS_TCP
  13091. // TODO(): prvAllowIPPacketIPv4()
  13092. #else
  13093. // lwIP, Unix, Windows, Zephyr 4+(, AzureRTOS ?)
  13094. #if MG_ENABLE_LWIP && !LWIP_IGMP
  13095. MG_ERROR(("LWIP_IGMP not defined, no multicast support"));
  13096. #else
  13097. #if defined(__ZEPHYR__) && ZEPHYR_VERSION_CODE < 0x40000
  13098. MG_ERROR(("struct ip_mreq not defined"));
  13099. #else
  13100. struct ip_mreq mreq;
  13101. mreq.imr_multiaddr.s_addr = inet_addr(ip);
  13102. mreq.imr_interface.s_addr = mg_htonl(INADDR_ANY);
  13103. setsockopt(FD(c), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq,
  13104. sizeof(mreq));
  13105. #endif // !Zephyr
  13106. #endif // !lwIP
  13107. #endif
  13108. }
  13109. bool mg_open_listener(struct mg_connection *c, const char *url) {
  13110. MG_SOCKET_TYPE fd = MG_INVALID_SOCKET;
  13111. bool success = false;
  13112. c->loc.port = mg_htons(mg_url_port(url));
  13113. if (!mg_aton(mg_url_host(url), &c->loc)) {
  13114. MG_ERROR(("invalid listening URL: %s", url));
  13115. } else {
  13116. union usa usa;
  13117. socklen_t slen = tousa(&c->loc, &usa);
  13118. int rc, on = 1, af = c->loc.is_ip6 ? AF_INET6 : AF_INET;
  13119. int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
  13120. int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
  13121. (void) on;
  13122. if ((fd = socket(af, type, proto)) == MG_INVALID_SOCKET) {
  13123. MG_ERROR(("socket: %d", MG_SOCK_ERR(-1)));
  13124. #if defined(SO_EXCLUSIVEADDRUSE)
  13125. } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
  13126. (char *) &on, sizeof(on))) != 0) {
  13127. // "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
  13128. MG_ERROR(("setsockopt(SO_EXCLUSIVEADDRUSE): %d %d", on, MG_SOCK_ERR(rc)));
  13129. #elif defined(SO_REUSEADDR) && (!defined(LWIP_SOCKET) || SO_REUSE)
  13130. } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
  13131. sizeof(on))) != 0) {
  13132. // 1. SO_REUSEADDR semantics on UNIX and Windows is different. On
  13133. // Windows, SO_REUSEADDR allows to bind a socket to a port without error
  13134. // even if the port is already open by another program. This is not the
  13135. // behavior SO_REUSEADDR was designed for, and leads to hard-to-track
  13136. // failure scenarios.
  13137. //
  13138. // 2. For LWIP, SO_REUSEADDR should be explicitly enabled by defining
  13139. // SO_REUSE = 1 in lwipopts.h, otherwise the code below will compile but
  13140. // won't work! (setsockopt will return EINVAL)
  13141. MG_ERROR(("setsockopt(SO_REUSEADDR): %d", MG_SOCK_ERR(rc)));
  13142. #endif
  13143. #if MG_IPV6_V6ONLY
  13144. // Bind only to the V6 address, not V4 address on this port
  13145. } else if (c->loc.is_ip6 &&
  13146. (rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &on,
  13147. sizeof(on))) != 0) {
  13148. // See #2089. Allow to bind v4 and v6 sockets on the same port
  13149. MG_ERROR(("setsockopt(IPV6_V6ONLY): %d", MG_SOCK_ERR(rc)));
  13150. #endif
  13151. } else if ((rc = bind(fd, &usa.sa, slen)) != 0) {
  13152. MG_ERROR(("bind: %d", MG_SOCK_ERR(rc)));
  13153. } else if ((type == SOCK_STREAM &&
  13154. (rc = listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE)) != 0)) {
  13155. // NOTE(lsm): FreeRTOS uses backlog value as a connection limit
  13156. // In case port was set to 0, get the real port number
  13157. MG_ERROR(("listen: %d", MG_SOCK_ERR(rc)));
  13158. } else {
  13159. setlocaddr(fd, &c->loc);
  13160. mg_set_non_blocking_mode(fd);
  13161. c->fd = S2PTR(fd);
  13162. MG_EPOLL_ADD(c);
  13163. success = true;
  13164. }
  13165. }
  13166. if (success == false && fd != MG_INVALID_SOCKET) closesocket(fd);
  13167. return success;
  13168. }
  13169. static long recv_raw(struct mg_connection *c, void *buf, size_t len) {
  13170. long n = 0;
  13171. if (c->is_udp) {
  13172. union usa usa;
  13173. socklen_t slen = tousa(&c->rem, &usa);
  13174. n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen);
  13175. if (n > 0) tomgaddr(&usa, &c->rem, slen != sizeof(usa.sin));
  13176. } else {
  13177. n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
  13178. }
  13179. MG_VERBOSE(("%lu %ld %d", c->id, n, MG_SOCK_ERR(n)));
  13180. if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
  13181. if (MG_SOCK_RESET(n)) return MG_IO_ERR; // See #1507, #3031
  13182. if (n <= 0) return MG_IO_ERR;
  13183. return n;
  13184. }
  13185. static bool ioalloc(struct mg_connection *c, struct mg_iobuf *io) {
  13186. bool res = false;
  13187. if (io->len >= MG_MAX_RECV_SIZE) {
  13188. mg_error(c, "MG_MAX_RECV_SIZE");
  13189. } else if (io->size <= io->len &&
  13190. !mg_iobuf_resize(io, io->size + MG_IO_SIZE)) {
  13191. mg_error(c, "OOM");
  13192. } else {
  13193. res = true;
  13194. }
  13195. return res;
  13196. }
  13197. // NOTE(lsm): do only one iteration of reads, cause some systems
  13198. // (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data
  13199. static void read_conn(struct mg_connection *c) {
  13200. long n = MG_IO_WAIT;
  13201. if (ioalloc(c, &c->recv) == false) return; // Oopsie poopsie, OOM
  13202. if (c->is_tls) {
  13203. size_t rtls = c->rtls.len, pending = mg_tls_pending(c);
  13204. long m = MG_IO_WAIT;
  13205. if (c->rtls.len < 16 * 1024 + 40) { // TLS record, header, MAC, padding
  13206. if (!ioalloc(c, &c->rtls)) return;
  13207. n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len],
  13208. c->rtls.size - c->rtls.len);
  13209. if (n > 0) c->rtls.len += (size_t) n;
  13210. }
  13211. // There can still be > 16K from last iteration, always mg_tls_recv()
  13212. if (c->is_tls_hs) {
  13213. if (n != MG_IO_ERR || c->rtls.len > 0 || pending > 0) {
  13214. mg_tls_handshake(c);
  13215. }
  13216. } else {
  13217. m = mg_tls_recv(c, &c->recv.buf[c->recv.len], c->recv.size - c->recv.len);
  13218. }
  13219. if (n == MG_IO_ERR &&
  13220. (m == MG_IO_ERR || (c->rtls.len == 0 && mg_tls_pending(c) == 0) ||
  13221. (c->is_tls_hs && c->rtls.len == rtls &&
  13222. mg_tls_pending(c) == pending))) {
  13223. // Close only when we have fully drained both rtls and TLS buffers
  13224. c->is_closing = 1; // or there's nothing we can do about it.
  13225. if (m < 0) m = MG_IO_ERR; // but return last record data, see #3104
  13226. }
  13227. n = m;
  13228. } else {
  13229. n = recv_raw(c, &c->recv.buf[c->recv.len], c->recv.size - c->recv.len);
  13230. }
  13231. MG_DEBUG(("%lu %ld %lu:%lu:%lu %ld err %d", c->id, c->fd, c->send.len,
  13232. c->recv.len, c->rtls.len, n, MG_SOCK_ERR(n)));
  13233. iolog(c, (char *) &c->recv.buf[c->recv.len], n, true);
  13234. }
  13235. static void write_conn(struct mg_connection *c) {
  13236. char *buf = (char *) c->send.buf;
  13237. size_t len = c->send.len;
  13238. long n = c->is_tls ? mg_tls_send(c, buf, len) : mg_io_send(c, buf, len);
  13239. // TODO(): mg_tls_send() may return 0 forever on steady OOM
  13240. MG_DEBUG(("%lu %ld snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
  13241. (long) c->send.len, (long) c->send.size, (long) c->recv.len,
  13242. (long) c->recv.size, n, MG_SOCK_ERR(n)));
  13243. iolog(c, buf, n, false);
  13244. }
  13245. static void close_conn(struct mg_connection *c) {
  13246. if (FD(c) != MG_INVALID_SOCKET) {
  13247. #if MG_ENABLE_EPOLL
  13248. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_DEL, FD(c), NULL);
  13249. #endif
  13250. closesocket(FD(c));
  13251. #if MG_ENABLE_FREERTOS_TCP
  13252. FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL);
  13253. #endif
  13254. }
  13255. mg_close_conn(c);
  13256. }
  13257. static void connect_conn(struct mg_connection *c) {
  13258. union usa usa;
  13259. socklen_t n = sizeof(usa);
  13260. // Use getpeername() to test whether we have connected
  13261. if (getpeername(FD(c), &usa.sa, &n) == 0) {
  13262. c->is_connecting = 0;
  13263. setlocaddr(FD(c), &c->loc);
  13264. mg_call(c, MG_EV_CONNECT, NULL);
  13265. MG_EPOLL_MOD(c, 0);
  13266. if (c->is_tls_hs) mg_tls_handshake(c);
  13267. if (!c->is_tls_hs) c->is_tls = 0; // user did not call mg_tls_init()
  13268. } else {
  13269. mg_error(c, "socket error");
  13270. }
  13271. }
  13272. static void setsockopts(struct mg_connection *c) {
  13273. #if MG_ENABLE_FREERTOS_TCP || MG_ARCH == MG_ARCH_THREADX || \
  13274. MG_ARCH == MG_ARCH_TIRTOS
  13275. (void) c;
  13276. #else
  13277. int on = 1;
  13278. #if !defined(SOL_TCP)
  13279. #define SOL_TCP IPPROTO_TCP
  13280. #endif
  13281. if (setsockopt(FD(c), SOL_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) != 0)
  13282. (void) 0;
  13283. if (setsockopt(FD(c), SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) !=
  13284. 0)
  13285. (void) 0;
  13286. #endif
  13287. }
  13288. void mg_connect_resolved(struct mg_connection *c) {
  13289. int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM;
  13290. int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
  13291. int rc, af = c->rem.is_ip6 ? AF_INET6 : AF_INET; // c->rem has resolved IP
  13292. c->fd = S2PTR(socket(af, type, proto)); // Create outbound socket
  13293. c->is_resolving = 0; // Clear resolving flag
  13294. if (FD(c) == MG_INVALID_SOCKET) {
  13295. mg_error(c, "socket(): %d", MG_SOCK_ERR(-1));
  13296. } else if (c->is_udp) {
  13297. MG_EPOLL_ADD(c);
  13298. #if MG_ARCH == MG_ARCH_TIRTOS
  13299. union usa usa; // TI-RTOS NDK requires binding to receive on UDP sockets
  13300. socklen_t slen = tousa(&c->loc, &usa);
  13301. if ((rc = bind(c->fd, &usa.sa, slen)) != 0)
  13302. MG_ERROR(("bind: %d", MG_SOCK_ERR(rc)));
  13303. #endif
  13304. setlocaddr(FD(c), &c->loc);
  13305. mg_call(c, MG_EV_RESOLVE, NULL);
  13306. mg_call(c, MG_EV_CONNECT, NULL);
  13307. } else {
  13308. union usa usa;
  13309. socklen_t slen = tousa(&c->rem, &usa);
  13310. mg_set_non_blocking_mode(FD(c));
  13311. setsockopts(c);
  13312. MG_EPOLL_ADD(c);
  13313. mg_call(c, MG_EV_RESOLVE, NULL);
  13314. rc = connect(FD(c), &usa.sa, slen); // Attempt to connect
  13315. if (rc == 0) { // Success
  13316. setlocaddr(FD(c), &c->loc);
  13317. mg_call(c, MG_EV_CONNECT, NULL); // Send MG_EV_CONNECT to the user
  13318. if (c->is_tls_hs) mg_tls_handshake(c);
  13319. if (!c->is_tls_hs) c->is_tls = 0; // user did not call mg_tls_init()
  13320. } else if (MG_SOCK_PENDING(rc)) { // Need to wait for TCP handshake
  13321. MG_DEBUG(("%lu %ld -> %M pend", c->id, c->fd, mg_print_ip_port, &c->rem));
  13322. c->is_connecting = 1;
  13323. } else {
  13324. mg_error(c, "connect: %d", MG_SOCK_ERR(rc));
  13325. }
  13326. }
  13327. }
  13328. static MG_SOCKET_TYPE raccept(MG_SOCKET_TYPE sock, union usa *usa,
  13329. socklen_t *len) {
  13330. MG_SOCKET_TYPE fd = MG_INVALID_SOCKET;
  13331. do {
  13332. memset(usa, 0, sizeof(*usa));
  13333. fd = accept(sock, &usa->sa, len);
  13334. #if MG_ENABLE_FREERTOS_TCP
  13335. // FreeRTOS_accept() returns NULL to mean "no pending connection",
  13336. // therefore we avoid retrying it forever on non-blocking listeners
  13337. if (fd == NULL) {
  13338. fd = MG_INVALID_SOCKET;
  13339. break;
  13340. }
  13341. #endif
  13342. } while (MG_SOCK_INTR(fd));
  13343. return fd;
  13344. }
  13345. static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
  13346. struct mg_connection *c = NULL;
  13347. union usa usa;
  13348. socklen_t sa_len = sizeof(usa);
  13349. MG_SOCKET_TYPE fd = raccept(FD(lsn), &usa, &sa_len);
  13350. if (fd == MG_INVALID_SOCKET) {
  13351. #if MG_ARCH == MG_ARCH_THREADX || defined(__ECOS)
  13352. // NetxDuo, in non-block socket mode can mark listening socket readable
  13353. // even it is not. See comment for 'select' func implementation in
  13354. // nx_bsd.c That's not an error, just should try later
  13355. if (errno != EAGAIN)
  13356. #endif
  13357. MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERR(-1)));
  13358. #if (MG_ARCH != MG_ARCH_WIN32) && !MG_ENABLE_FREERTOS_TCP && \
  13359. (MG_ARCH != MG_ARCH_TIRTOS) && !MG_ENABLE_POLL && !MG_ENABLE_EPOLL
  13360. } else if ((long) fd >= FD_SETSIZE) {
  13361. MG_ERROR(("%ld > %ld", (long) fd, (long) FD_SETSIZE));
  13362. closesocket(fd);
  13363. #endif
  13364. } else if ((c = mg_alloc_conn(mgr)) == NULL) {
  13365. MG_ERROR(("%lu OOM", lsn->id));
  13366. closesocket(fd);
  13367. } else {
  13368. tomgaddr(&usa, &c->rem, sa_len != sizeof(usa.sin));
  13369. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  13370. c->fd = S2PTR(fd);
  13371. MG_EPOLL_ADD(c);
  13372. mg_set_non_blocking_mode(FD(c));
  13373. setsockopts(c);
  13374. c->is_accepted = 1;
  13375. c->is_hexdumping = lsn->is_hexdumping;
  13376. setlocaddr(fd, &c->loc); // set local addr to where the client connected to
  13377. c->pfn = lsn->pfn;
  13378. c->pfn_data = lsn->pfn_data;
  13379. c->fn = lsn->fn;
  13380. c->fn_data = lsn->fn_data;
  13381. c->is_tls = lsn->is_tls;
  13382. MG_DEBUG(("%lu %ld accepted %M -> %M", c->id, c->fd, mg_print_ip_port,
  13383. &c->rem, mg_print_ip_port, &c->loc));
  13384. mg_call(c, MG_EV_OPEN, NULL);
  13385. mg_call(c, MG_EV_ACCEPT, NULL);
  13386. if (!c->is_tls_hs) c->is_tls = 0; // user did not call mg_tls_init()
  13387. }
  13388. }
  13389. static bool can_read(const struct mg_connection *c) {
  13390. return c->is_full == false;
  13391. }
  13392. static bool can_write(const struct mg_connection *c) {
  13393. return c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0);
  13394. }
  13395. static bool skip_iotest(const struct mg_connection *c) {
  13396. return (c->is_closing || c->is_resolving || FD(c) == MG_INVALID_SOCKET) ||
  13397. (can_read(c) == false && can_write(c) == false);
  13398. }
  13399. static void mg_iotest(struct mg_mgr *mgr, int ms) {
  13400. #if MG_ENABLE_FREERTOS_TCP
  13401. struct mg_connection *c;
  13402. for (c = mgr->conns; c != NULL; c = c->next) {
  13403. c->is_readable = c->is_writable = 0;
  13404. if (skip_iotest(c)) continue;
  13405. if (can_read(c))
  13406. FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_READ | eSELECT_EXCEPT);
  13407. if (can_write(c)) FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_WRITE);
  13408. if (c->is_closing) ms = 1;
  13409. }
  13410. FreeRTOS_select(mgr->ss, pdMS_TO_TICKS(ms));
  13411. for (c = mgr->conns; c != NULL; c = c->next) {
  13412. EventBits_t bits = FreeRTOS_FD_ISSET(c->fd, mgr->ss);
  13413. c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1U : 0;
  13414. c->is_writable = bits & eSELECT_WRITE ? 1U : 0;
  13415. if (c->fd != MG_INVALID_SOCKET)
  13416. FreeRTOS_FD_CLR(c->fd, mgr->ss,
  13417. eSELECT_READ | eSELECT_EXCEPT | eSELECT_WRITE);
  13418. }
  13419. #elif MG_ENABLE_EPOLL
  13420. size_t max = 1;
  13421. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
  13422. c->is_readable = c->is_writable = 0;
  13423. if (c->rtls.len > 0 || mg_tls_pending(c) > 0) ms = 1, c->is_readable = 1;
  13424. if (can_write(c)) MG_EPOLL_MOD(c, 1);
  13425. if (c->is_closing) ms = 1;
  13426. max++;
  13427. }
  13428. struct epoll_event *evs = (struct epoll_event *) alloca(max * sizeof(evs[0]));
  13429. int n = epoll_wait(mgr->epoll_fd, evs, (int) max, ms);
  13430. for (int i = 0; i < n; i++) {
  13431. struct mg_connection *c = (struct mg_connection *) evs[i].data.ptr;
  13432. if (evs[i].events & EPOLLERR) {
  13433. mg_error(c, "socket error");
  13434. } else if (c->is_readable == 0) {
  13435. bool rd = evs[i].events & (EPOLLIN | EPOLLHUP);
  13436. bool wr = evs[i].events & EPOLLOUT;
  13437. c->is_readable = can_read(c) && rd ? 1U : 0;
  13438. c->is_writable = can_write(c) && wr ? 1U : 0;
  13439. if (c->rtls.len > 0 || mg_tls_pending(c) > 0) c->is_readable = 1;
  13440. }
  13441. }
  13442. (void) skip_iotest;
  13443. #elif MG_ENABLE_POLL
  13444. nfds_t n = 0;
  13445. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) n++;
  13446. struct pollfd *fds = (struct pollfd *) alloca(n * sizeof(fds[0]));
  13447. memset(fds, 0, n * sizeof(fds[0]));
  13448. n = 0;
  13449. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
  13450. c->is_readable = c->is_writable = 0;
  13451. if (c->is_closing) ms = 1;
  13452. if (skip_iotest(c)) {
  13453. // Socket not valid, ignore
  13454. } else {
  13455. // Don't wait if TLS is ready
  13456. if (c->rtls.len > 0 || mg_tls_pending(c) > 0) ms = 1;
  13457. fds[n].fd = FD(c);
  13458. if (can_read(c)) fds[n].events |= POLLIN;
  13459. if (can_write(c)) fds[n].events |= POLLOUT;
  13460. n++;
  13461. }
  13462. }
  13463. // MG_INFO(("poll n=%d ms=%d", (int) n, ms));
  13464. if (poll(fds, n, ms) < 0) {
  13465. #if MG_ARCH == MG_ARCH_WIN32
  13466. if (n == 0) Sleep(ms); // On Windows, poll fails if no sockets
  13467. #endif
  13468. memset(fds, 0, n * sizeof(fds[0]));
  13469. }
  13470. n = 0;
  13471. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
  13472. if (skip_iotest(c)) {
  13473. // Socket not valid, ignore
  13474. } else {
  13475. if (fds[n].revents & POLLERR) {
  13476. mg_error(c, "socket error");
  13477. } else {
  13478. c->is_readable =
  13479. (unsigned) (fds[n].revents & (POLLIN | POLLHUP) ? 1 : 0);
  13480. c->is_writable = (unsigned) (fds[n].revents & POLLOUT ? 1 : 0);
  13481. if (c->rtls.len > 0 || mg_tls_pending(c) > 0) c->is_readable = 1;
  13482. }
  13483. n++;
  13484. }
  13485. }
  13486. #else
  13487. struct timeval tv = {ms / 1000, (ms % 1000) * 1000}, tv_1ms = {0, 1000}, *tvp;
  13488. struct mg_connection *c;
  13489. fd_set rset, wset, eset;
  13490. MG_SOCKET_TYPE maxfd = 0;
  13491. int rc;
  13492. FD_ZERO(&rset);
  13493. FD_ZERO(&wset);
  13494. FD_ZERO(&eset);
  13495. tvp = ms < 0 ? NULL : &tv;
  13496. for (c = mgr->conns; c != NULL; c = c->next) {
  13497. c->is_readable = c->is_writable = 0;
  13498. if (skip_iotest(c)) continue;
  13499. FD_SET(FD(c), &eset);
  13500. if (can_read(c)) FD_SET(FD(c), &rset);
  13501. if (can_write(c)) FD_SET(FD(c), &wset);
  13502. if (c->rtls.len > 0 || mg_tls_pending(c) > 0) tvp = &tv_1ms;
  13503. if (FD(c) > maxfd) maxfd = FD(c);
  13504. if (c->is_closing) tvp = &tv_1ms;
  13505. }
  13506. if ((rc = select((int) maxfd + 1, &rset, &wset, &eset, tvp)) <= 0) {
  13507. #if MG_ARCH == MG_ARCH_WIN32
  13508. if (maxfd == 0) Sleep(ms); // On Windows, select fails if no sockets
  13509. #else
  13510. if (rc < 0) MG_ERROR(("select: %d %d", rc, MG_SOCK_ERR(rc)));
  13511. #endif
  13512. FD_ZERO(&rset);
  13513. FD_ZERO(&wset);
  13514. FD_ZERO(&eset);
  13515. }
  13516. for (c = mgr->conns; c != NULL; c = c->next) {
  13517. if (FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &eset)) {
  13518. #if MG_ARCH == MG_ARCH_THREADX
  13519. // NetxDuo stack returns exceptions for listening connection after accept
  13520. if (c->is_listening == 0) mg_error(c, "socket error");
  13521. #else
  13522. mg_error(c, "socket error");
  13523. #endif
  13524. } else {
  13525. c->is_readable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &rset);
  13526. c->is_writable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &wset);
  13527. if (c->rtls.len > 0 || mg_tls_pending(c) > 0) c->is_readable = 1;
  13528. }
  13529. }
  13530. #endif
  13531. }
  13532. static bool mg_socketpair(MG_SOCKET_TYPE sp[2], union usa usa[2]) {
  13533. socklen_t n = sizeof(usa[0].sin);
  13534. bool success = false;
  13535. sp[0] = sp[1] = MG_INVALID_SOCKET;
  13536. (void) memset(&usa[0], 0, sizeof(usa[0]));
  13537. usa[0].sin.sin_family = AF_INET;
  13538. *(uint32_t *) &usa->sin.sin_addr = mg_htonl(0x7f000001U); // 127.0.0.1
  13539. usa[1] = usa[0];
  13540. if ((sp[0] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != MG_INVALID_SOCKET &&
  13541. (sp[1] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != MG_INVALID_SOCKET &&
  13542. bind(sp[0], &usa[0].sa, n) == 0 && //
  13543. bind(sp[1], &usa[1].sa, n) == 0 && //
  13544. getsockname(sp[0], &usa[0].sa, &n) == 0 && //
  13545. getsockname(sp[1], &usa[1].sa, &n) == 0 && //
  13546. connect(sp[0], &usa[1].sa, n) == 0 && //
  13547. connect(sp[1], &usa[0].sa, n) == 0) { //
  13548. success = true;
  13549. }
  13550. if (!success) {
  13551. if (sp[0] != MG_INVALID_SOCKET) closesocket(sp[0]);
  13552. if (sp[1] != MG_INVALID_SOCKET) closesocket(sp[1]);
  13553. sp[0] = sp[1] = MG_INVALID_SOCKET;
  13554. }
  13555. return success;
  13556. }
  13557. // mg_wakeup() event handler
  13558. static void wufn(struct mg_connection *c, int ev, void *ev_data) {
  13559. if (ev == MG_EV_READ) {
  13560. unsigned long *id = (unsigned long *) c->recv.buf;
  13561. // MG_INFO(("Got data"));
  13562. // mg_hexdump(c->recv.buf, c->recv.len);
  13563. if (c->recv.len >= sizeof(*id)) {
  13564. struct mg_connection *t;
  13565. for (t = c->mgr->conns; t != NULL; t = t->next) {
  13566. if (t->id == *id) {
  13567. struct mg_str data = mg_str_n((char *) c->recv.buf + sizeof(*id),
  13568. c->recv.len - sizeof(*id));
  13569. mg_call(t, MG_EV_WAKEUP, &data);
  13570. }
  13571. }
  13572. }
  13573. c->recv.len = 0; // Consume received data
  13574. } else if (ev == MG_EV_CLOSE) {
  13575. closesocket(c->mgr->pipe.fd); // When we're closing, close the other
  13576. c->mgr->pipe.fd = MG_INVALID_SOCKET; // side of the socketpair, too
  13577. }
  13578. (void) ev_data;
  13579. }
  13580. bool mg_wakeup_init(struct mg_mgr *mgr) {
  13581. bool ok = false;
  13582. if (mgr->pipe.fd == MG_INVALID_SOCKET) {
  13583. union usa usa[2];
  13584. MG_SOCKET_TYPE sp[2] = {MG_INVALID_SOCKET, MG_INVALID_SOCKET};
  13585. struct mg_connection *c = NULL;
  13586. if (!mg_socketpair(sp, usa)) {
  13587. MG_ERROR(("Cannot create socket pair"));
  13588. } else if ((c = mg_wrapfd(mgr, (int) sp[1], wufn, NULL)) == NULL) {
  13589. closesocket(sp[0]);
  13590. closesocket(sp[1]);
  13591. sp[0] = sp[1] = MG_INVALID_SOCKET;
  13592. } else {
  13593. tomgaddr(&usa[0], &c->rem, false);
  13594. MG_DEBUG(("%lu %ld pipe %ld", c->id, c->fd, (long) sp[0]));
  13595. mgr->pipe.fd = sp[0];
  13596. ok = true;
  13597. }
  13598. }
  13599. return ok;
  13600. }
  13601. bool mg_wakeup(struct mg_mgr *mgr, unsigned long conn_id, const void *buf,
  13602. size_t len) {
  13603. if (mgr->pipe.fd != MG_INVALID_SOCKET && conn_id > 0) {
  13604. char *extended_buf = (char *) alloca(len + sizeof(conn_id));
  13605. memcpy(extended_buf, &conn_id, sizeof(conn_id));
  13606. memcpy(extended_buf + sizeof(conn_id), buf, len);
  13607. send(mgr->pipe.fd, extended_buf, len + sizeof(conn_id), MSG_NONBLOCKING);
  13608. return true;
  13609. }
  13610. return false;
  13611. }
  13612. void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
  13613. struct mg_connection *c, *tmp;
  13614. uint64_t now;
  13615. mg_iotest(mgr, ms);
  13616. now = mg_millis();
  13617. mg_timer_poll(&mgr->timers, now);
  13618. mg_ota_poll(mgr);
  13619. for (c = mgr->conns; c != NULL; c = tmp) {
  13620. bool is_resp = c->is_resp;
  13621. tmp = c->next;
  13622. mg_call(c, MG_EV_POLL, &now);
  13623. if (is_resp && !c->is_resp) {
  13624. long n = 0;
  13625. mg_call(c, MG_EV_READ, &n);
  13626. }
  13627. MG_VERBOSE(("%lu %c%c %c%c%c%c%c %lu %lu", c->id,
  13628. c->is_readable ? 'r' : '-', c->is_writable ? 'w' : '-',
  13629. c->is_tls ? 'T' : 't', c->is_connecting ? 'C' : 'c',
  13630. c->is_tls_hs ? 'H' : 'h', c->is_resolving ? 'R' : 'r',
  13631. c->is_closing ? 'C' : 'c', mg_tls_pending(c), c->rtls.len));
  13632. if (c->is_resolving || c->is_closing) {
  13633. // Do nothing
  13634. } else if (c->is_listening && c->is_udp == 0) {
  13635. if (c->is_readable) accept_conn(mgr, c);
  13636. } else if (c->is_connecting) {
  13637. if (c->is_readable || c->is_writable) connect_conn(c);
  13638. } else {
  13639. if (c->is_readable) read_conn(c);
  13640. if (c->is_writable) write_conn(c);
  13641. if (c->is_tls && !c->is_tls_hs && c->send.len == 0) mg_tls_flush(c);
  13642. }
  13643. if (c->is_draining && c->send.len == 0) c->is_closing = 1;
  13644. if (c->is_closing) close_conn(c);
  13645. }
  13646. }
  13647. #endif
  13648. #ifdef MG_ENABLE_LINES
  13649. #line 1 "src/ssi.c"
  13650. #endif
  13651. #ifndef MG_MAX_SSI_DEPTH
  13652. #define MG_MAX_SSI_DEPTH 5
  13653. #endif
  13654. #ifndef MG_SSI_BUFSIZ
  13655. #define MG_SSI_BUFSIZ 1024
  13656. #endif
  13657. #if MG_ENABLE_SSI
  13658. static char *mg_ssi(const char *path, const char *root, int depth) {
  13659. struct mg_iobuf b = {NULL, 0, 0, MG_IO_SIZE};
  13660. FILE *fp = fopen(path, "rb");
  13661. if (fp != NULL) {
  13662. char buf[MG_SSI_BUFSIZ], arg[sizeof(buf)];
  13663. int ch, intag = 0;
  13664. size_t len = 0;
  13665. buf[0] = arg[0] = '\0';
  13666. while ((ch = fgetc(fp)) != EOF) {
  13667. if (intag && ch == '>' && len >= 2 && buf[len - 1] == '-' && buf[len - 2] == '-') {
  13668. buf[len++] = (char) (ch & 0xff);
  13669. buf[len] = '\0';
  13670. if (sscanf(buf, "<!--#include file=\"%[^\"]", arg) > 0) {
  13671. char tmp[MG_PATH_MAX + MG_SSI_BUFSIZ + 10],
  13672. *p = (char *) path + strlen(path), *data;
  13673. while (p > path && p[-1] != MG_DIRSEP && p[-1] != '/') p--;
  13674. mg_snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
  13675. if (!mg_path_is_sane(mg_str(tmp))) {
  13676. MG_ERROR(("SSI include path traversal blocked: %s", arg));
  13677. } else if (depth < MG_MAX_SSI_DEPTH &&
  13678. (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
  13679. size_t datalen = strlen(data);
  13680. size_t ret = mg_iobuf_add(&b, b.len, data, datalen);
  13681. mg_free(data);
  13682. if (datalen > 0 && ret == 0) goto fail;
  13683. } else {
  13684. MG_ERROR(("%s: file=%s error or too deep", path, arg));
  13685. } // TODO(): or OOM at recursive call
  13686. } else if (sscanf(buf, "<!--#include virtual=\"%[^\"]", arg) > 0) {
  13687. char tmp[MG_PATH_MAX + MG_SSI_BUFSIZ + 10], *data;
  13688. mg_snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
  13689. if (!mg_path_is_sane(mg_str(tmp))) {
  13690. MG_ERROR(("SSI include path traversal blocked: %s", arg));
  13691. } else if (depth < MG_MAX_SSI_DEPTH &&
  13692. (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
  13693. size_t datalen = strlen(data);
  13694. size_t ret = mg_iobuf_add(&b, b.len, data, datalen);
  13695. mg_free(data);
  13696. if (datalen > 0 && ret == 0) goto fail;
  13697. } else {
  13698. MG_ERROR(("%s: virtual=%s error or too deep", path, arg));
  13699. } // TODO(): or OOM at recursive call
  13700. } else {
  13701. // Unknown SSI tag
  13702. MG_ERROR(("Unknown SSI tag: %.*s", (int) len, buf));
  13703. if (len > 0 && mg_iobuf_add(&b, b.len, buf, len) == 0) goto fail;
  13704. }
  13705. intag = 0;
  13706. len = 0;
  13707. } else if (ch == '<') {
  13708. intag = 1;
  13709. if (len > 0 && mg_iobuf_add(&b, b.len, buf, len) == 0) goto fail;
  13710. len = 0;
  13711. buf[len++] = (char) (ch & 0xff);
  13712. } else if (intag) {
  13713. if (len == 5 && strncmp(buf, "<!--#", 5) != 0) {
  13714. intag = 0;
  13715. } else if (len >= sizeof(buf) - 2) {
  13716. MG_ERROR(("%s: SSI tag is too large", path));
  13717. len = 0;
  13718. }
  13719. buf[len++] = (char) (ch & 0xff);
  13720. } else {
  13721. buf[len++] = (char) (ch & 0xff);
  13722. if (len >= sizeof(buf)) {
  13723. if (mg_iobuf_add(&b, b.len, buf, len) == 0) goto fail;
  13724. len = 0;
  13725. }
  13726. }
  13727. }
  13728. if (len > 0 && mg_iobuf_add(&b, b.len, buf, len) == 0) goto fail;
  13729. if (b.len > 0 && mg_iobuf_add(&b, b.len, "", 1) == 0) // nul-terminate
  13730. goto fail;
  13731. fclose(fp);
  13732. }
  13733. (void) depth;
  13734. (void) root;
  13735. return (char *) b.buf;
  13736. fail:
  13737. fclose(fp);
  13738. mg_iobuf_free(&b);
  13739. return NULL;
  13740. }
  13741. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  13742. const char *fullpath) {
  13743. const char *headers = "Content-Type: text/html; charset=utf-8\r\n";
  13744. char *data = mg_ssi(fullpath, root, 0);
  13745. if (data == NULL) {
  13746. mg_error(c, "OOM");
  13747. return;
  13748. }
  13749. mg_http_reply(c, 200, headers, "%s", data == NULL ? "" : data);
  13750. mg_free(data);
  13751. }
  13752. #else
  13753. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  13754. const char *fullpath) {
  13755. mg_http_reply(c, 501, NULL, "SSI not enabled");
  13756. (void) root, (void) fullpath;
  13757. }
  13758. #endif
  13759. #ifdef MG_ENABLE_LINES
  13760. #line 1 "src/str.c"
  13761. #endif
  13762. struct mg_str mg_str_s(const char *s) {
  13763. struct mg_str str;
  13764. str.buf = (char *) s, str.len = (s == NULL) ? 0 : strlen(s);
  13765. return str;
  13766. }
  13767. struct mg_str mg_str_n(const char *s, size_t n) {
  13768. struct mg_str str;
  13769. str.buf = (char *) s, str.len = n;
  13770. return str;
  13771. }
  13772. static int mg_tolc(char c) {
  13773. return (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
  13774. }
  13775. int mg_casecmp(const char *s1, const char *s2) {
  13776. int diff = 0;
  13777. do {
  13778. int c = mg_tolc(*s1++), d = mg_tolc(*s2++);
  13779. diff = c - d;
  13780. } while (diff == 0 && s1[-1] != '\0');
  13781. return diff;
  13782. }
  13783. struct mg_str mg_strdup(const struct mg_str s) {
  13784. struct mg_str r = {NULL, 0};
  13785. if (s.len > 0 && s.buf != NULL) {
  13786. char *sc = (char *) mg_calloc(1, s.len + 1);
  13787. if (sc != NULL) {
  13788. memcpy(sc, s.buf, s.len);
  13789. sc[s.len] = '\0';
  13790. r.buf = sc;
  13791. r.len = s.len;
  13792. }
  13793. }
  13794. return r;
  13795. }
  13796. int mg_strcmp(const struct mg_str str1, const struct mg_str str2) {
  13797. size_t i = 0;
  13798. while (i < str1.len && i < str2.len) {
  13799. int c1 = str1.buf[i];
  13800. int c2 = str2.buf[i];
  13801. if (c1 < c2) return -1;
  13802. if (c1 > c2) return 1;
  13803. i++;
  13804. }
  13805. if (i < str1.len) return 1;
  13806. if (i < str2.len) return -1;
  13807. return 0;
  13808. }
  13809. int mg_strcasecmp(const struct mg_str str1, const struct mg_str str2) {
  13810. size_t i = 0;
  13811. while (i < str1.len && i < str2.len) {
  13812. int c1 = mg_tolc(str1.buf[i]);
  13813. int c2 = mg_tolc(str2.buf[i]);
  13814. if (c1 < c2) return -1;
  13815. if (c1 > c2) return 1;
  13816. i++;
  13817. }
  13818. if (i < str1.len) return 1;
  13819. if (i < str2.len) return -1;
  13820. return 0;
  13821. }
  13822. bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
  13823. size_t i = 0, j = 0, ni = 0, nj = 0;
  13824. if (caps) caps->buf = NULL, caps->len = 0;
  13825. while (i < p.len || j < s.len) {
  13826. if (i < p.len && j < s.len &&
  13827. (p.buf[i] == '?' ||
  13828. (p.buf[i] != '*' && p.buf[i] != '#' && s.buf[j] == p.buf[i]))) {
  13829. if (caps == NULL) {
  13830. } else if (p.buf[i] == '?') {
  13831. caps->buf = &s.buf[j], caps->len = 1; // Finalize `?` cap
  13832. caps++, caps->buf = NULL, caps->len = 0; // Init next cap
  13833. } else if (caps->buf != NULL && caps->len == 0) {
  13834. caps->len = (size_t) (&s.buf[j] - caps->buf); // Finalize current cap
  13835. caps++, caps->len = 0, caps->buf = NULL; // Init next cap
  13836. }
  13837. i++, j++;
  13838. } else if (i < p.len && (p.buf[i] == '*' || p.buf[i] == '#')) {
  13839. if (caps && !caps->buf) caps->len = 0, caps->buf = &s.buf[j]; // Init cap
  13840. ni = i++, nj = j + 1;
  13841. } else if (nj > 0 && nj <= s.len &&
  13842. ((ni < p.len && p.buf[ni] == '#') ||
  13843. (j < s.len && s.buf[j] != '/'))) {
  13844. i = ni, j = nj;
  13845. if (caps && caps->buf == NULL && caps->len == 0) {
  13846. caps--, caps->len = 0; // Restart previous cap
  13847. }
  13848. } else {
  13849. return false;
  13850. }
  13851. }
  13852. if (caps && caps->buf && caps->len == 0) {
  13853. caps->len = (size_t) (&s.buf[j] - caps->buf);
  13854. }
  13855. return true;
  13856. }
  13857. bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char sep) {
  13858. if (s.len == 0 || s.buf == NULL) {
  13859. return false; // Empty string, nothing to span - fail
  13860. } else {
  13861. size_t len = 0;
  13862. while (len < s.len && s.buf[len] != sep) len++; // Find separator
  13863. if (a) *a = mg_str_n(s.buf, len); // Init a
  13864. if (b) *b = mg_str_n(s.buf + len, s.len - len); // Init b
  13865. if (b && len < s.len) b->buf++, b->len--; // Skip separator
  13866. return true;
  13867. }
  13868. }
  13869. bool mg_str_to_num(struct mg_str str, int base, void *val, size_t val_len) {
  13870. size_t i = 0, ndigits = 0;
  13871. uint64_t max = val_len == sizeof(uint8_t) ? 0xFF
  13872. : val_len == sizeof(uint16_t) ? 0xFFFF
  13873. : val_len == sizeof(uint32_t) ? 0xFFFFFFFF
  13874. : (uint64_t) ~0;
  13875. uint64_t result = 0;
  13876. if (max == (uint64_t) ~0 && val_len != sizeof(uint64_t)) return false;
  13877. if (base == 0 && str.len >= 2) {
  13878. if (str.buf[i] == '0') {
  13879. i++;
  13880. base = str.buf[i] == 'b' ? 2 : str.buf[i] == 'x' ? 16 : 10;
  13881. if (base != 10) ++i;
  13882. } else {
  13883. base = 10;
  13884. }
  13885. }
  13886. switch (base) {
  13887. case 2:
  13888. while (i < str.len && (str.buf[i] == '0' || str.buf[i] == '1')) {
  13889. uint64_t digit = (uint64_t) (str.buf[i] - '0');
  13890. if (result > max / 2) return false; // Overflow
  13891. result *= 2;
  13892. if (result > max - digit) return false; // Overflow
  13893. result += digit;
  13894. i++, ndigits++;
  13895. }
  13896. break;
  13897. case 10:
  13898. while (i < str.len && str.buf[i] >= '0' && str.buf[i] <= '9') {
  13899. uint64_t digit = (uint64_t) (str.buf[i] - '0');
  13900. if (result > max / 10) return false; // Overflow
  13901. result *= 10;
  13902. if (result > max - digit) return false; // Overflow
  13903. result += digit;
  13904. i++, ndigits++;
  13905. }
  13906. break;
  13907. case 16:
  13908. while (i < str.len) {
  13909. char c = str.buf[i];
  13910. uint64_t digit = (c >= '0' && c <= '9') ? (uint64_t) (c - '0')
  13911. : (c >= 'A' && c <= 'F') ? (uint64_t) (c - '7')
  13912. : (c >= 'a' && c <= 'f') ? (uint64_t) (c - 'W')
  13913. : (uint64_t) ~0;
  13914. if (digit == (uint64_t) ~0) break;
  13915. if (result > max / 16) return false; // Overflow
  13916. result *= 16;
  13917. if (result > max - digit) return false; // Overflow
  13918. result += digit;
  13919. i++, ndigits++;
  13920. }
  13921. break;
  13922. default: return false;
  13923. }
  13924. if (ndigits == 0) return false;
  13925. if (i != str.len) return false;
  13926. if (val_len == 1) {
  13927. *((uint8_t *) val) = (uint8_t) result;
  13928. } else if (val_len == 2) {
  13929. *((uint16_t *) val) = (uint16_t) result;
  13930. } else if (val_len == 4) {
  13931. *((uint32_t *) val) = (uint32_t) result;
  13932. } else {
  13933. *((uint64_t *) val) = (uint64_t) result;
  13934. }
  13935. return true;
  13936. }
  13937. #ifdef MG_ENABLE_LINES
  13938. #line 1 "src/timer.c"
  13939. #endif
  13940. void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms,
  13941. unsigned flags, void (*fn)(void *), void *arg) {
  13942. t->period_ms = ms, t->expire = 0;
  13943. t->flags = flags, t->fn = fn, t->arg = arg, t->next = *head;
  13944. *head = t;
  13945. }
  13946. void mg_timer_free(struct mg_timer **head, struct mg_timer *t) {
  13947. while (*head && *head != t) head = &(*head)->next;
  13948. if (*head) *head = t->next;
  13949. }
  13950. // t: expiration time, prd: period, now: current time. Return true if expired
  13951. bool mg_timer_expired(uint64_t *t, uint64_t prd, uint64_t now) {
  13952. if (now + prd < *t) *t = 0; // Time wrapped? Reset timer
  13953. if (*t == 0) *t = now + prd; // Firt poll? Set expiration
  13954. if (*t > now) return false; // Not expired yet, return
  13955. *t = (now - *t) > prd ? now + prd : *t + prd; // Next expiration time
  13956. return true; // Expired, return true
  13957. }
  13958. void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
  13959. struct mg_timer *t, *tmp;
  13960. for (t = *head; t != NULL; t = tmp) {
  13961. bool once = t->expire == 0 && (t->flags & MG_TIMER_RUN_NOW) &&
  13962. !(t->flags & MG_TIMER_CALLED); // Handle MG_TIMER_NOW only once
  13963. bool expired = mg_timer_expired(&t->expire, t->period_ms, now_ms);
  13964. tmp = t->next;
  13965. if (!once && !expired) continue;
  13966. if ((t->flags & MG_TIMER_REPEAT) || !(t->flags & MG_TIMER_CALLED)) {
  13967. t->fn(t->arg);
  13968. }
  13969. t->flags |= MG_TIMER_CALLED;
  13970. // If this timer is not repeating and marked AUTODELETE, remove it
  13971. if (!(t->flags & MG_TIMER_REPEAT) && (t->flags & MG_TIMER_AUTODELETE)) {
  13972. mg_timer_free(head, t);
  13973. mg_free(t);
  13974. }
  13975. }
  13976. }
  13977. #ifdef MG_ENABLE_LINES
  13978. #line 1 "src/tls_aes128.c"
  13979. #endif
  13980. /******************************************************************************
  13981. *
  13982. * THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
  13983. *
  13984. * This is a simple and straightforward implementation of the AES Rijndael
  13985. * 128-bit block cipher designed by Vincent Rijmen and Joan Daemen. The focus
  13986. * of this work was correctness & accuracy. It is written in 'C' without any
  13987. * particular focus upon optimization or speed. It should be endian (memory
  13988. * byte order) neutral since the few places that care are handled explicitly.
  13989. *
  13990. * This implementation of Rijndael was created by Steven M. Gibson of GRC.com.
  13991. *
  13992. * It is intended for general purpose use, but was written in support of GRC's
  13993. * reference implementation of the SQRL (Secure Quick Reliable Login) client.
  13994. *
  13995. * See: http://csrc.nist.gov/archive/aes/rijndael/wsdindex.html
  13996. *
  13997. * NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
  13998. * REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
  13999. *
  14000. *******************************************************************************/
  14001. #if MG_TLS == MG_TLS_BUILTIN
  14002. /******************************************************************************/
  14003. #define AES_DECRYPTION 1 // whether AES decryption is supported
  14004. /******************************************************************************/
  14005. #define MG_ENCRYPT 1 // specify whether we're encrypting
  14006. #define MG_DECRYPT 0 // or decrypting
  14007. /******************************************************************************
  14008. * AES_INIT_KEYGEN_TABLES : MUST be called once before any AES use
  14009. ******************************************************************************/
  14010. static void aes_init_keygen_tables(void);
  14011. /******************************************************************************
  14012. * AES_SETKEY : called to expand the key for encryption or decryption
  14013. ******************************************************************************/
  14014. static int aes_setkey(
  14015. aes_context *ctx, // pointer to context
  14016. int mode, // 1 or 0 for Encrypt/Decrypt
  14017. const unsigned char *key, // AES input key
  14018. unsigned int keysize); // size in bytes (must be 16, 24, 32 for
  14019. // 128, 192 or 256-bit keys respectively)
  14020. // returns 0 for success
  14021. /******************************************************************************
  14022. * AES_CIPHER : called to encrypt or decrypt ONE 128-bit block of data
  14023. ******************************************************************************/
  14024. static int aes_cipher(
  14025. aes_context *ctx, // pointer to context
  14026. const unsigned char input[16], // 128-bit block to en/decipher
  14027. unsigned char output[16]); // 128-bit output result block
  14028. // returns 0 for success
  14029. /******************************************************************************
  14030. * GCM_CONTEXT : GCM context / holds keytables, instance data, and AES ctx
  14031. ******************************************************************************/
  14032. typedef struct {
  14033. int mode; // cipher direction: encrypt/decrypt
  14034. uint64_t len; // cipher data length processed so far
  14035. uint64_t add_len; // total add data length
  14036. uint64_t HL[16]; // precalculated lo-half HTable
  14037. uint64_t HH[16]; // precalculated hi-half HTable
  14038. unsigned char base_ectr[16]; // first counter-mode cipher output for tag
  14039. unsigned char y[16]; // the current cipher-input IV|Counter value
  14040. unsigned char buf[16]; // buf working value
  14041. aes_context aes_ctx; // cipher context used
  14042. } gcm_context;
  14043. /******************************************************************************
  14044. * GCM_SETKEY : sets the GCM (and AES) keying material for use
  14045. ******************************************************************************/
  14046. static int gcm_setkey(
  14047. gcm_context *ctx, // caller-provided context ptr
  14048. const unsigned char *key, // pointer to cipher key
  14049. const unsigned int keysize // size in bytes (must be 16, 24, 32 for
  14050. // 128, 192 or 256-bit keys respectively)
  14051. ); // returns 0 for success
  14052. /******************************************************************************
  14053. *
  14054. * GCM_CRYPT_AND_TAG
  14055. *
  14056. * This either encrypts or decrypts the user-provided data and, either
  14057. * way, generates an authentication tag of the requested length. It must be
  14058. * called with a GCM context whose key has already been set with GCM_SETKEY.
  14059. *
  14060. * The user would typically call this explicitly to ENCRYPT a buffer of data
  14061. * and optional associated data, and produce its an authentication tag.
  14062. *
  14063. * To reverse the process the user would typically call the companion
  14064. * GCM_AUTH_DECRYPT function to decrypt data and verify a user-provided
  14065. * authentication tag. The GCM_AUTH_DECRYPT function calls this function
  14066. * to perform its decryption and tag generation, which it then compares.
  14067. *
  14068. ******************************************************************************/
  14069. static int gcm_crypt_and_tag(
  14070. gcm_context *ctx, // gcm context with key already setup
  14071. int mode, // cipher direction: MG_ENCRYPT (1) or MG_DECRYPT (0)
  14072. const unsigned char *iv, // pointer to the 12-byte initialization vector
  14073. size_t iv_len, // byte length if the IV. should always be 12
  14074. const unsigned char *add, // pointer to the non-ciphered additional data
  14075. size_t add_len, // byte length of the additional AEAD data
  14076. const unsigned char *input, // pointer to the cipher data source
  14077. unsigned char *output, // pointer to the cipher data destination
  14078. size_t length, // byte length of the cipher data
  14079. unsigned char *tag, // pointer to the tag to be generated
  14080. size_t tag_len); // byte length of the tag to be generated
  14081. /******************************************************************************
  14082. *
  14083. * GCM_START
  14084. *
  14085. * Given a user-provided GCM context, this initializes it, sets the encryption
  14086. * mode, and preprocesses the initialization vector and additional AEAD data.
  14087. *
  14088. ******************************************************************************/
  14089. static int gcm_start(
  14090. gcm_context *ctx, // pointer to user-provided GCM context
  14091. int mode, // MG_ENCRYPT (1) or MG_DECRYPT (0)
  14092. const unsigned char *iv, // pointer to initialization vector
  14093. size_t iv_len, // IV length in bytes (should == 12)
  14094. const unsigned char *add, // pointer to additional AEAD data (NULL if none)
  14095. size_t add_len); // length of additional AEAD data (bytes)
  14096. /******************************************************************************
  14097. *
  14098. * GCM_UPDATE
  14099. *
  14100. * This is called once or more to process bulk plaintext or ciphertext data.
  14101. * We give this some number of bytes of input and it returns the same number
  14102. * of output bytes. If called multiple times (which is fine) all but the final
  14103. * invocation MUST be called with length mod 16 == 0. (Only the final call can
  14104. * have a partial block length of < 128 bits.)
  14105. *
  14106. ******************************************************************************/
  14107. static int gcm_update(gcm_context *ctx, // pointer to user-provided GCM context
  14108. size_t length, // length, in bytes, of data to process
  14109. const unsigned char *input, // pointer to source data
  14110. unsigned char *output); // pointer to destination data
  14111. /******************************************************************************
  14112. *
  14113. * GCM_FINISH
  14114. *
  14115. * This is called once after all calls to GCM_UPDATE to finalize the GCM.
  14116. * It performs the final GHASH to produce the resulting authentication TAG.
  14117. *
  14118. ******************************************************************************/
  14119. static int gcm_finish(
  14120. gcm_context *ctx, // pointer to user-provided GCM context
  14121. unsigned char *tag, // ptr to tag buffer - NULL if tag_len = 0
  14122. size_t tag_len); // length, in bytes, of the tag-receiving buf
  14123. /******************************************************************************
  14124. *
  14125. * GCM_ZERO_CTX
  14126. *
  14127. * The GCM context contains both the GCM context and the AES context.
  14128. * This includes keying and key-related material which is security-
  14129. * sensitive, so it MUST be zeroed after use. This function does that.
  14130. *
  14131. ******************************************************************************/
  14132. static void gcm_zero_ctx(gcm_context *ctx);
  14133. /******************************************************************************
  14134. *
  14135. * THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
  14136. *
  14137. * This is a simple and straightforward implementation of the AES Rijndael
  14138. * 128-bit block cipher designed by Vincent Rijmen and Joan Daemen. The focus
  14139. * of this work was correctness & accuracy. It is written in 'C' without any
  14140. * particular focus upon optimization or speed. It should be endian (memory
  14141. * byte order) neutral since the few places that care are handled explicitly.
  14142. *
  14143. * This implementation of Rijndael was created by Steven M. Gibson of GRC.com.
  14144. *
  14145. * It is intended for general purpose use, but was written in support of GRC's
  14146. * reference implementation of the SQRL (Secure Quick Reliable Login) client.
  14147. *
  14148. * See: http://csrc.nist.gov/archive/aes/rijndael/wsdindex.html
  14149. *
  14150. * NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
  14151. * REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
  14152. *
  14153. *******************************************************************************/
  14154. static int aes_tables_inited = 0; // run-once flag for performing key
  14155. // expasion table generation (see below)
  14156. /*
  14157. * The following static local tables must be filled-in before the first use of
  14158. * the GCM or AES ciphers. They are used for the AES key expansion/scheduling
  14159. * and once built are read-only and thread safe. The "gcm_initialize" function
  14160. * must be called once during system initialization to populate these arrays
  14161. * for subsequent use by the AES key scheduler. If they have not been built
  14162. * before attempted use, an error will be returned to the caller.
  14163. *
  14164. * NOTE: GCM Encryption/Decryption does NOT REQUIRE AES decryption. Since
  14165. * GCM uses AES in counter-mode, where the AES cipher output is XORed with
  14166. * the GCM input, we ONLY NEED AES encryption. Thus, to save space AES
  14167. * decryption is typically disabled by setting AES_DECRYPTION to 0 in aes.h.
  14168. */
  14169. // We always need our forward tables
  14170. static unsigned char FSb[256]; // Forward substitution box (FSb)
  14171. static uint32_t FT0[256]; // Forward key schedule assembly tables
  14172. static uint32_t FT1[256];
  14173. static uint32_t FT2[256];
  14174. static uint32_t FT3[256];
  14175. #if AES_DECRYPTION // We ONLY need reverse for decryption
  14176. static unsigned char RSb[256]; // Reverse substitution box (RSb)
  14177. static uint32_t RT0[256]; // Reverse key schedule assembly tables
  14178. static uint32_t RT1[256];
  14179. static uint32_t RT2[256];
  14180. static uint32_t RT3[256];
  14181. #endif /* AES_DECRYPTION */
  14182. static uint32_t RCON[10]; // AES round constants
  14183. /*
  14184. * Platform Endianness Neutralizing Load and Store Macro definitions
  14185. * AES wants platform-neutral Little Endian (LE) byte ordering
  14186. */
  14187. #define GET_UINT32_LE(n, b, i) \
  14188. { \
  14189. (n) = ((uint32_t) (b)[(i)]) | ((uint32_t) (b)[(i) + 1] << 8) | \
  14190. ((uint32_t) (b)[(i) + 2] << 16) | ((uint32_t) (b)[(i) + 3] << 24); \
  14191. }
  14192. #define PUT_UINT32_LE(n, b, i) \
  14193. { \
  14194. (b)[(i)] = (unsigned char) ((n)); \
  14195. (b)[(i) + 1] = (unsigned char) ((n) >> 8); \
  14196. (b)[(i) + 2] = (unsigned char) ((n) >> 16); \
  14197. (b)[(i) + 3] = (unsigned char) ((n) >> 24); \
  14198. }
  14199. /*
  14200. * AES forward and reverse encryption round processing macros
  14201. */
  14202. #define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
  14203. { \
  14204. X0 = *RK++ ^ FT0[(Y0) & 0xFF] ^ FT1[(Y1 >> 8) & 0xFF] ^ \
  14205. FT2[(Y2 >> 16) & 0xFF] ^ FT3[(Y3 >> 24) & 0xFF]; \
  14206. \
  14207. X1 = *RK++ ^ FT0[(Y1) & 0xFF] ^ FT1[(Y2 >> 8) & 0xFF] ^ \
  14208. FT2[(Y3 >> 16) & 0xFF] ^ FT3[(Y0 >> 24) & 0xFF]; \
  14209. \
  14210. X2 = *RK++ ^ FT0[(Y2) & 0xFF] ^ FT1[(Y3 >> 8) & 0xFF] ^ \
  14211. FT2[(Y0 >> 16) & 0xFF] ^ FT3[(Y1 >> 24) & 0xFF]; \
  14212. \
  14213. X3 = *RK++ ^ FT0[(Y3) & 0xFF] ^ FT1[(Y0 >> 8) & 0xFF] ^ \
  14214. FT2[(Y1 >> 16) & 0xFF] ^ FT3[(Y2 >> 24) & 0xFF]; \
  14215. }
  14216. #define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
  14217. { \
  14218. X0 = *RK++ ^ RT0[(Y0) & 0xFF] ^ RT1[(Y3 >> 8) & 0xFF] ^ \
  14219. RT2[(Y2 >> 16) & 0xFF] ^ RT3[(Y1 >> 24) & 0xFF]; \
  14220. \
  14221. X1 = *RK++ ^ RT0[(Y1) & 0xFF] ^ RT1[(Y0 >> 8) & 0xFF] ^ \
  14222. RT2[(Y3 >> 16) & 0xFF] ^ RT3[(Y2 >> 24) & 0xFF]; \
  14223. \
  14224. X2 = *RK++ ^ RT0[(Y2) & 0xFF] ^ RT1[(Y1 >> 8) & 0xFF] ^ \
  14225. RT2[(Y0 >> 16) & 0xFF] ^ RT3[(Y3 >> 24) & 0xFF]; \
  14226. \
  14227. X3 = *RK++ ^ RT0[(Y3) & 0xFF] ^ RT1[(Y2 >> 8) & 0xFF] ^ \
  14228. RT2[(Y1 >> 16) & 0xFF] ^ RT3[(Y0 >> 24) & 0xFF]; \
  14229. }
  14230. /*
  14231. * These macros improve the readability of the key
  14232. * generation initialization code by collapsing
  14233. * repetitive common operations into logical pieces.
  14234. */
  14235. #define ROTL8(x) ((x << 8) & 0xFFFFFFFF) | (x >> 24)
  14236. #define XTIME(x) ((x << 1) ^ ((x & 0x80) ? 0x1B : 0x00))
  14237. #define MUL(x, y) ((x && y) ? pow[(log[x] + log[y]) % 255] : 0)
  14238. #define MIX(x, y) \
  14239. { \
  14240. y = ((y << 1) | (y >> 7)) & 0xFF; \
  14241. x ^= y; \
  14242. }
  14243. #define CPY128 \
  14244. { \
  14245. *RK++ = *SK++; \
  14246. *RK++ = *SK++; \
  14247. *RK++ = *SK++; \
  14248. *RK++ = *SK++; \
  14249. }
  14250. /******************************************************************************
  14251. *
  14252. * AES_INIT_KEYGEN_TABLES
  14253. *
  14254. * Fills the AES key expansion tables allocated above with their static
  14255. * data. This is not "per key" data, but static system-wide read-only
  14256. * table data. THIS FUNCTION IS NOT THREAD SAFE. It must be called once
  14257. * at system initialization to setup the tables for all subsequent use.
  14258. *
  14259. ******************************************************************************/
  14260. void aes_init_keygen_tables(void) {
  14261. int i, x, y, z; // general purpose iteration and computation locals
  14262. int pow[256];
  14263. int log[256];
  14264. if (aes_tables_inited) return;
  14265. // fill the 'pow' and 'log' tables over GF(2^8)
  14266. for (i = 0, x = 1; i < 256; i++) {
  14267. pow[i] = x;
  14268. log[x] = i;
  14269. x = (x ^ XTIME(x)) & 0xFF;
  14270. }
  14271. // compute the round constants
  14272. for (i = 0, x = 1; i < 10; i++) {
  14273. RCON[i] = (uint32_t) x;
  14274. x = XTIME(x) & 0xFF;
  14275. }
  14276. // fill the forward and reverse substitution boxes
  14277. FSb[0x00] = 0x63;
  14278. #if AES_DECRYPTION // whether AES decryption is supported
  14279. RSb[0x63] = 0x00;
  14280. #endif /* AES_DECRYPTION */
  14281. for (i = 1; i < 256; i++) {
  14282. x = y = pow[255 - log[i]];
  14283. MIX(x, y);
  14284. MIX(x, y);
  14285. MIX(x, y);
  14286. MIX(x, y);
  14287. FSb[i] = (unsigned char) (x ^= 0x63);
  14288. #if AES_DECRYPTION // whether AES decryption is supported
  14289. RSb[x] = (unsigned char) i;
  14290. #endif /* AES_DECRYPTION */
  14291. }
  14292. // generate the forward and reverse key expansion tables
  14293. for (i = 0; i < 256; i++) {
  14294. x = FSb[i];
  14295. y = XTIME(x) & 0xFF;
  14296. z = (y ^ x) & 0xFF;
  14297. FT0[i] = ((uint32_t) y) ^ ((uint32_t) x << 8) ^ ((uint32_t) x << 16) ^
  14298. ((uint32_t) z << 24);
  14299. FT1[i] = ROTL8(FT0[i]);
  14300. FT2[i] = ROTL8(FT1[i]);
  14301. FT3[i] = ROTL8(FT2[i]);
  14302. #if AES_DECRYPTION // whether AES decryption is supported
  14303. x = RSb[i];
  14304. RT0[i] = ((uint32_t) MUL(0x0E, x)) ^ ((uint32_t) MUL(0x09, x) << 8) ^
  14305. ((uint32_t) MUL(0x0D, x) << 16) ^ ((uint32_t) MUL(0x0B, x) << 24);
  14306. RT1[i] = ROTL8(RT0[i]);
  14307. RT2[i] = ROTL8(RT1[i]);
  14308. RT3[i] = ROTL8(RT2[i]);
  14309. #endif /* AES_DECRYPTION */
  14310. }
  14311. aes_tables_inited = 1; // flag that the tables have been generated
  14312. } // to permit subsequent use of the AES cipher
  14313. /******************************************************************************
  14314. *
  14315. * AES_SET_ENCRYPTION_KEY
  14316. *
  14317. * This is called by 'aes_setkey' when we're establishing a key for
  14318. * subsequent encryption. We give it a pointer to the encryption
  14319. * context, a pointer to the key, and the key's length in bytes.
  14320. * Valid lengths are: 16, 24 or 32 bytes (128, 192, 256 bits).
  14321. *
  14322. ******************************************************************************/
  14323. static int aes_set_encryption_key(aes_context *ctx, const unsigned char *key,
  14324. unsigned int keysize) {
  14325. unsigned int i; // general purpose iteration local
  14326. uint32_t *RK = ctx->rk; // initialize our RoundKey buffer pointer
  14327. for (i = 0; i < (keysize >> 2); i++) {
  14328. GET_UINT32_LE(RK[i], key, i << 2);
  14329. }
  14330. switch (ctx->rounds) {
  14331. case 10:
  14332. for (i = 0; i < 10; i++, RK += 4) {
  14333. RK[4] = RK[0] ^ RCON[i] ^ ((uint32_t) FSb[(RK[3] >> 8) & 0xFF]) ^
  14334. ((uint32_t) FSb[(RK[3] >> 16) & 0xFF] << 8) ^
  14335. ((uint32_t) FSb[(RK[3] >> 24) & 0xFF] << 16) ^
  14336. ((uint32_t) FSb[(RK[3]) & 0xFF] << 24);
  14337. RK[5] = RK[1] ^ RK[4];
  14338. RK[6] = RK[2] ^ RK[5];
  14339. RK[7] = RK[3] ^ RK[6];
  14340. }
  14341. break;
  14342. case 12:
  14343. for (i = 0; i < 8; i++, RK += 6) {
  14344. RK[6] = RK[0] ^ RCON[i] ^ ((uint32_t) FSb[(RK[5] >> 8) & 0xFF]) ^
  14345. ((uint32_t) FSb[(RK[5] >> 16) & 0xFF] << 8) ^
  14346. ((uint32_t) FSb[(RK[5] >> 24) & 0xFF] << 16) ^
  14347. ((uint32_t) FSb[(RK[5]) & 0xFF] << 24);
  14348. RK[7] = RK[1] ^ RK[6];
  14349. RK[8] = RK[2] ^ RK[7];
  14350. RK[9] = RK[3] ^ RK[8];
  14351. RK[10] = RK[4] ^ RK[9];
  14352. RK[11] = RK[5] ^ RK[10];
  14353. }
  14354. break;
  14355. case 14:
  14356. for (i = 0; i < 7; i++, RK += 8) {
  14357. RK[8] = RK[0] ^ RCON[i] ^ ((uint32_t) FSb[(RK[7] >> 8) & 0xFF]) ^
  14358. ((uint32_t) FSb[(RK[7] >> 16) & 0xFF] << 8) ^
  14359. ((uint32_t) FSb[(RK[7] >> 24) & 0xFF] << 16) ^
  14360. ((uint32_t) FSb[(RK[7]) & 0xFF] << 24);
  14361. RK[9] = RK[1] ^ RK[8];
  14362. RK[10] = RK[2] ^ RK[9];
  14363. RK[11] = RK[3] ^ RK[10];
  14364. RK[12] = RK[4] ^ ((uint32_t) FSb[(RK[11]) & 0xFF]) ^
  14365. ((uint32_t) FSb[(RK[11] >> 8) & 0xFF] << 8) ^
  14366. ((uint32_t) FSb[(RK[11] >> 16) & 0xFF] << 16) ^
  14367. ((uint32_t) FSb[(RK[11] >> 24) & 0xFF] << 24);
  14368. RK[13] = RK[5] ^ RK[12];
  14369. RK[14] = RK[6] ^ RK[13];
  14370. RK[15] = RK[7] ^ RK[14];
  14371. }
  14372. break;
  14373. default:
  14374. return -1;
  14375. }
  14376. return (0);
  14377. }
  14378. #if AES_DECRYPTION // whether AES decryption is supported
  14379. /******************************************************************************
  14380. *
  14381. * AES_SET_DECRYPTION_KEY
  14382. *
  14383. * This is called by 'aes_setkey' when we're establishing a
  14384. * key for subsequent decryption. We give it a pointer to
  14385. * the encryption context, a pointer to the key, and the key's
  14386. * length in bits. Valid lengths are: 128, 192, or 256 bits.
  14387. *
  14388. ******************************************************************************/
  14389. static int aes_set_decryption_key(aes_context *ctx, const unsigned char *key,
  14390. unsigned int keysize) {
  14391. int i, j;
  14392. aes_context cty; // a calling aes context for set_encryption_key
  14393. uint32_t *RK = ctx->rk; // initialize our RoundKey buffer pointer
  14394. uint32_t *SK;
  14395. int ret;
  14396. cty.rounds = ctx->rounds; // initialize our local aes context
  14397. cty.rk = cty.buf; // round count and key buf pointer
  14398. if ((ret = aes_set_encryption_key(&cty, key, keysize)) != 0) return (ret);
  14399. SK = cty.rk + cty.rounds * 4;
  14400. CPY128 // copy a 128-bit block from *SK to *RK
  14401. for (i = ctx->rounds - 1, SK -= 8; i > 0; i--, SK -= 8) {
  14402. for (j = 0; j < 4; j++, SK++) {
  14403. *RK++ = RT0[FSb[(*SK) & 0xFF]] ^ RT1[FSb[(*SK >> 8) & 0xFF]] ^
  14404. RT2[FSb[(*SK >> 16) & 0xFF]] ^ RT3[FSb[(*SK >> 24) & 0xFF]];
  14405. }
  14406. }
  14407. CPY128 // copy a 128-bit block from *SK to *RK
  14408. memset(&cty, 0, sizeof(aes_context)); // clear local aes context
  14409. return (0);
  14410. }
  14411. #endif /* AES_DECRYPTION */
  14412. /******************************************************************************
  14413. *
  14414. * AES_SETKEY
  14415. *
  14416. * Invoked to establish the key schedule for subsequent encryption/decryption
  14417. *
  14418. ******************************************************************************/
  14419. static int aes_setkey(aes_context *ctx, // AES context provided by our caller
  14420. int mode, // ENCRYPT or DECRYPT flag
  14421. const unsigned char *key, // pointer to the key
  14422. unsigned int keysize) // key length in bytes
  14423. {
  14424. // since table initialization is not thread safe, we could either add
  14425. // system-specific mutexes and init the AES key generation tables on
  14426. // demand, or ask the developer to simply call "gcm_initialize" once during
  14427. // application startup before threading begins. That's what we choose.
  14428. if (!aes_tables_inited) return (-1); // fail the call when not inited.
  14429. ctx->mode = mode; // capture the key type we're creating
  14430. ctx->rk = ctx->buf; // initialize our round key pointer
  14431. switch (keysize) // set the rounds count based upon the keysize
  14432. {
  14433. case 16:
  14434. ctx->rounds = 10;
  14435. break; // 16-byte, 128-bit key
  14436. case 24:
  14437. ctx->rounds = 12;
  14438. break; // 24-byte, 192-bit key
  14439. case 32:
  14440. ctx->rounds = 14;
  14441. break; // 32-byte, 256-bit key
  14442. default:
  14443. return (-1);
  14444. }
  14445. #if AES_DECRYPTION
  14446. if (mode == MG_DECRYPT) // expand our key for encryption or decryption
  14447. return (aes_set_decryption_key(ctx, key, keysize));
  14448. else /* MG_ENCRYPT */
  14449. #endif /* AES_DECRYPTION */
  14450. return (aes_set_encryption_key(ctx, key, keysize));
  14451. }
  14452. /******************************************************************************
  14453. *
  14454. * AES_CIPHER
  14455. *
  14456. * Perform AES encryption and decryption.
  14457. * The AES context will have been setup with the encryption mode
  14458. * and all keying information appropriate for the task.
  14459. *
  14460. ******************************************************************************/
  14461. static int aes_cipher(aes_context *ctx, const unsigned char input[16],
  14462. unsigned char output[16]) {
  14463. int i;
  14464. uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; // general purpose locals
  14465. RK = ctx->rk;
  14466. GET_UINT32_LE(X0, input, 0);
  14467. X0 ^= *RK++; // load our 128-bit
  14468. GET_UINT32_LE(X1, input, 4);
  14469. X1 ^= *RK++; // input buffer in a storage
  14470. GET_UINT32_LE(X2, input, 8);
  14471. X2 ^= *RK++; // memory endian-neutral way
  14472. GET_UINT32_LE(X3, input, 12);
  14473. X3 ^= *RK++;
  14474. #if AES_DECRYPTION // whether AES decryption is supported
  14475. if (ctx->mode == MG_DECRYPT) {
  14476. for (i = (ctx->rounds >> 1) - 1; i > 0; i--) {
  14477. AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
  14478. AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);
  14479. }
  14480. AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
  14481. X0 = *RK++ ^ ((uint32_t) RSb[(Y0) & 0xFF]) ^
  14482. ((uint32_t) RSb[(Y3 >> 8) & 0xFF] << 8) ^
  14483. ((uint32_t) RSb[(Y2 >> 16) & 0xFF] << 16) ^
  14484. ((uint32_t) RSb[(Y1 >> 24) & 0xFF] << 24);
  14485. X1 = *RK++ ^ ((uint32_t) RSb[(Y1) & 0xFF]) ^
  14486. ((uint32_t) RSb[(Y0 >> 8) & 0xFF] << 8) ^
  14487. ((uint32_t) RSb[(Y3 >> 16) & 0xFF] << 16) ^
  14488. ((uint32_t) RSb[(Y2 >> 24) & 0xFF] << 24);
  14489. X2 = *RK++ ^ ((uint32_t) RSb[(Y2) & 0xFF]) ^
  14490. ((uint32_t) RSb[(Y1 >> 8) & 0xFF] << 8) ^
  14491. ((uint32_t) RSb[(Y0 >> 16) & 0xFF] << 16) ^
  14492. ((uint32_t) RSb[(Y3 >> 24) & 0xFF] << 24);
  14493. X3 = *RK++ ^ ((uint32_t) RSb[(Y3) & 0xFF]) ^
  14494. ((uint32_t) RSb[(Y2 >> 8) & 0xFF] << 8) ^
  14495. ((uint32_t) RSb[(Y1 >> 16) & 0xFF] << 16) ^
  14496. ((uint32_t) RSb[(Y0 >> 24) & 0xFF] << 24);
  14497. } else /* MG_ENCRYPT */
  14498. {
  14499. #endif /* AES_DECRYPTION */
  14500. for (i = (ctx->rounds >> 1) - 1; i > 0; i--) {
  14501. AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
  14502. AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);
  14503. }
  14504. AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
  14505. X0 = *RK++ ^ ((uint32_t) FSb[(Y0) & 0xFF]) ^
  14506. ((uint32_t) FSb[(Y1 >> 8) & 0xFF] << 8) ^
  14507. ((uint32_t) FSb[(Y2 >> 16) & 0xFF] << 16) ^
  14508. ((uint32_t) FSb[(Y3 >> 24) & 0xFF] << 24);
  14509. X1 = *RK++ ^ ((uint32_t) FSb[(Y1) & 0xFF]) ^
  14510. ((uint32_t) FSb[(Y2 >> 8) & 0xFF] << 8) ^
  14511. ((uint32_t) FSb[(Y3 >> 16) & 0xFF] << 16) ^
  14512. ((uint32_t) FSb[(Y0 >> 24) & 0xFF] << 24);
  14513. X2 = *RK++ ^ ((uint32_t) FSb[(Y2) & 0xFF]) ^
  14514. ((uint32_t) FSb[(Y3 >> 8) & 0xFF] << 8) ^
  14515. ((uint32_t) FSb[(Y0 >> 16) & 0xFF] << 16) ^
  14516. ((uint32_t) FSb[(Y1 >> 24) & 0xFF] << 24);
  14517. X3 = *RK++ ^ ((uint32_t) FSb[(Y3) & 0xFF]) ^
  14518. ((uint32_t) FSb[(Y0 >> 8) & 0xFF] << 8) ^
  14519. ((uint32_t) FSb[(Y1 >> 16) & 0xFF] << 16) ^
  14520. ((uint32_t) FSb[(Y2 >> 24) & 0xFF] << 24);
  14521. #if AES_DECRYPTION // whether AES decryption is supported
  14522. }
  14523. #endif /* AES_DECRYPTION */
  14524. PUT_UINT32_LE(X0, output, 0);
  14525. PUT_UINT32_LE(X1, output, 4);
  14526. PUT_UINT32_LE(X2, output, 8);
  14527. PUT_UINT32_LE(X3, output, 12);
  14528. return (0);
  14529. }
  14530. /* end of aes.c */
  14531. /******************************************************************************
  14532. *
  14533. * THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
  14534. *
  14535. * This is a simple and straightforward implementation of AES-GCM authenticated
  14536. * encryption. The focus of this work was correctness & accuracy. It is written
  14537. * in straight 'C' without any particular focus upon optimization or speed. It
  14538. * should be endian (memory byte order) neutral since the few places that care
  14539. * are handled explicitly.
  14540. *
  14541. * This implementation of AES-GCM was created by Steven M. Gibson of GRC.com.
  14542. *
  14543. * It is intended for general purpose use, but was written in support of GRC's
  14544. * reference implementation of the SQRL (Secure Quick Reliable Login) client.
  14545. *
  14546. * See: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
  14547. * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/
  14548. * gcm/gcm-revised-spec.pdf
  14549. *
  14550. * NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
  14551. * REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
  14552. *
  14553. *******************************************************************************/
  14554. /******************************************************************************
  14555. * ==== IMPLEMENTATION WARNING ====
  14556. *
  14557. * This code was developed for use within SQRL's fixed environmnent. Thus, it
  14558. * is somewhat less "general purpose" than it would be if it were designed as
  14559. * a general purpose AES-GCM library. Specifically, it bothers with almost NO
  14560. * error checking on parameter limits, buffer bounds, etc. It assumes that it
  14561. * is being invoked by its author or by someone who understands the values it
  14562. * expects to receive. Its behavior will be undefined otherwise.
  14563. *
  14564. * All functions that might fail are defined to return 'ints' to indicate a
  14565. * problem. Most do not do so now. But this allows for error propagation out
  14566. * of internal functions if robust error checking should ever be desired.
  14567. *
  14568. ******************************************************************************/
  14569. /* Calculating the "GHASH"
  14570. *
  14571. * There are many ways of calculating the so-called GHASH in software, each with
  14572. * a traditional size vs performance tradeoff. The GHASH (Galois field hash) is
  14573. * an intriguing construction which takes two 128-bit strings (also the cipher's
  14574. * block size and the fundamental operation size for the system) and hashes them
  14575. * into a third 128-bit result.
  14576. *
  14577. * Many implementation solutions have been worked out that use large precomputed
  14578. * table lookups in place of more time consuming bit fiddling, and this approach
  14579. * can be scaled easily upward or downward as needed to change the time/space
  14580. * tradeoff. It's been studied extensively and there's a solid body of theory
  14581. * and practice. For example, without using any lookup tables an implementation
  14582. * might obtain 119 cycles per byte throughput, whereas using a simple, though
  14583. * large, key-specific 64 kbyte 8-bit lookup table the performance jumps to 13
  14584. * cycles per byte.
  14585. *
  14586. * And Intel's processors have, since 2010, included an instruction which does
  14587. * the entire 128x128->128 bit job in just several 64x64->128 bit pieces.
  14588. *
  14589. * Since SQRL is interactive, and only processing a few 128-bit blocks, I've
  14590. * settled upon a relatively slower but appealing small-table compromise which
  14591. * folds a bunch of not only time consuming but also bit twiddling into a simple
  14592. * 16-entry table which is attributed to Victor Shoup's 1996 work while at
  14593. * Bellcore: "On Fast and Provably Secure MessageAuthentication Based on
  14594. * Universal Hashing." See: http://www.shoup.net/papers/macs.pdf
  14595. * See, also section 4.1 of the "gcm-revised-spec" cited above.
  14596. */
  14597. /*
  14598. * This 16-entry table of pre-computed constants is used by the
  14599. * GHASH multiplier to improve over a strictly table-free but
  14600. * significantly slower 128x128 bit multiple within GF(2^128).
  14601. */
  14602. static const uint64_t last4[16] = {
  14603. 0x0000, 0x1c20, 0x3840, 0x2460, 0x7080, 0x6ca0, 0x48c0, 0x54e0,
  14604. 0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0};
  14605. /*
  14606. * Platform Endianness Neutralizing Load and Store Macro definitions
  14607. * GCM wants platform-neutral Big Endian (BE) byte ordering
  14608. */
  14609. #define GET_UINT32_BE(n, b, i) \
  14610. { \
  14611. (n) = ((uint32_t) (b)[(i)] << 24) | ((uint32_t) (b)[(i) + 1] << 16) | \
  14612. ((uint32_t) (b)[(i) + 2] << 8) | ((uint32_t) (b)[(i) + 3]); \
  14613. }
  14614. #define PUT_UINT32_BE(n, b, i) \
  14615. { \
  14616. (b)[(i)] = (unsigned char) ((n) >> 24); \
  14617. (b)[(i) + 1] = (unsigned char) ((n) >> 16); \
  14618. (b)[(i) + 2] = (unsigned char) ((n) >> 8); \
  14619. (b)[(i) + 3] = (unsigned char) ((n)); \
  14620. }
  14621. /******************************************************************************
  14622. *
  14623. * GCM_INITIALIZE
  14624. *
  14625. * Must be called once to initialize the GCM library.
  14626. *
  14627. * At present, this only calls the AES keygen table generator, which expands
  14628. * the AES keying tables for use. This is NOT A THREAD-SAFE function, so it
  14629. * MUST be called during system initialization before a multi-threading
  14630. * environment is running.
  14631. *
  14632. ******************************************************************************/
  14633. int mg_gcm_initialize(void) {
  14634. aes_init_keygen_tables();
  14635. return (0);
  14636. }
  14637. /******************************************************************************
  14638. *
  14639. * GCM_MULT
  14640. *
  14641. * Performs a GHASH operation on the 128-bit input vector 'x', setting
  14642. * the 128-bit output vector to 'x' times H using our precomputed tables.
  14643. * 'x' and 'output' are seen as elements of GCM's GF(2^128) Galois field.
  14644. *
  14645. ******************************************************************************/
  14646. static void gcm_mult(
  14647. gcm_context *ctx, // pointer to established context
  14648. const unsigned char x[16], // pointer to 128-bit input vector
  14649. unsigned char output[16]) // pointer to 128-bit output vector
  14650. {
  14651. int i;
  14652. unsigned char lo, hi, rem;
  14653. uint64_t zh, zl;
  14654. lo = (unsigned char) (x[15] & 0x0f);
  14655. hi = (unsigned char) (x[15] >> 4);
  14656. zh = ctx->HH[lo];
  14657. zl = ctx->HL[lo];
  14658. for (i = 15; i >= 0; i--) {
  14659. lo = (unsigned char) (x[i] & 0x0f);
  14660. hi = (unsigned char) (x[i] >> 4);
  14661. if (i != 15) {
  14662. rem = (unsigned char) (zl & 0x0f);
  14663. zl = (zh << 60) | (zl >> 4);
  14664. zh = (zh >> 4);
  14665. zh ^= (uint64_t) last4[rem] << 48;
  14666. zh ^= ctx->HH[lo];
  14667. zl ^= ctx->HL[lo];
  14668. }
  14669. rem = (unsigned char) (zl & 0x0f);
  14670. zl = (zh << 60) | (zl >> 4);
  14671. zh = (zh >> 4);
  14672. zh ^= (uint64_t) last4[rem] << 48;
  14673. zh ^= ctx->HH[hi];
  14674. zl ^= ctx->HL[hi];
  14675. }
  14676. PUT_UINT32_BE(zh >> 32, output, 0);
  14677. PUT_UINT32_BE(zh, output, 4);
  14678. PUT_UINT32_BE(zl >> 32, output, 8);
  14679. PUT_UINT32_BE(zl, output, 12);
  14680. }
  14681. /******************************************************************************
  14682. *
  14683. * GCM_SETKEY
  14684. *
  14685. * This is called to set the AES-GCM key. It initializes the AES key
  14686. * and populates the gcm context's pre-calculated HTables.
  14687. *
  14688. ******************************************************************************/
  14689. static int gcm_setkey(
  14690. gcm_context *ctx, // pointer to caller-provided gcm context
  14691. const unsigned char *key, // pointer to the AES encryption key
  14692. const unsigned int keysize) // size in bytes (must be 16, 24, 32 for
  14693. // 128, 192 or 256-bit keys respectively)
  14694. {
  14695. int ret, i, j;
  14696. uint64_t hi, lo;
  14697. uint64_t vl, vh;
  14698. unsigned char h[16];
  14699. memset(ctx, 0, sizeof(gcm_context)); // zero caller-provided GCM context
  14700. memset(h, 0, 16); // initialize the block to encrypt
  14701. // encrypt the null 128-bit block to generate a key-based value
  14702. // which is then used to initialize our GHASH lookup tables
  14703. if ((ret = aes_setkey(&ctx->aes_ctx, MG_ENCRYPT, key, keysize)) != 0)
  14704. return (ret);
  14705. if ((ret = aes_cipher(&ctx->aes_ctx, h, h)) != 0) return (ret);
  14706. GET_UINT32_BE(hi, h, 0); // pack h as two 64-bit ints, big-endian
  14707. GET_UINT32_BE(lo, h, 4);
  14708. vh = (uint64_t) hi << 32 | lo;
  14709. GET_UINT32_BE(hi, h, 8);
  14710. GET_UINT32_BE(lo, h, 12);
  14711. vl = (uint64_t) hi << 32 | lo;
  14712. ctx->HL[8] = vl; // 8 = 1000 corresponds to 1 in GF(2^128)
  14713. ctx->HH[8] = vh;
  14714. ctx->HH[0] = 0; // 0 corresponds to 0 in GF(2^128)
  14715. ctx->HL[0] = 0;
  14716. for (i = 4; i > 0; i >>= 1) {
  14717. uint32_t T = (uint32_t) (vl & 1) * 0xe1000000U;
  14718. vl = (vh << 63) | (vl >> 1);
  14719. vh = (vh >> 1) ^ ((uint64_t) T << 32);
  14720. ctx->HL[i] = vl;
  14721. ctx->HH[i] = vh;
  14722. }
  14723. for (i = 2; i < 16; i <<= 1) {
  14724. uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
  14725. vh = *HiH;
  14726. vl = *HiL;
  14727. for (j = 1; j < i; j++) {
  14728. HiH[j] = vh ^ ctx->HH[j];
  14729. HiL[j] = vl ^ ctx->HL[j];
  14730. }
  14731. }
  14732. return (0);
  14733. }
  14734. /******************************************************************************
  14735. *
  14736. * GCM processing occurs four phases: SETKEY, START, UPDATE and FINISH.
  14737. *
  14738. * SETKEY:
  14739. *
  14740. * START: Sets the Encryption/Decryption mode.
  14741. * Accepts the initialization vector and additional data.
  14742. *
  14743. * UPDATE: Encrypts or decrypts the plaintext or ciphertext.
  14744. *
  14745. * FINISH: Performs a final GHASH to generate the authentication tag.
  14746. *
  14747. ******************************************************************************
  14748. *
  14749. * GCM_START
  14750. *
  14751. * Given a user-provided GCM context, this initializes it, sets the encryption
  14752. * mode, and preprocesses the initialization vector and additional AEAD data.
  14753. *
  14754. ******************************************************************************/
  14755. int gcm_start(
  14756. gcm_context *ctx, // pointer to user-provided GCM context
  14757. int mode, // GCM_ENCRYPT or GCM_DECRYPT
  14758. const unsigned char *iv, // pointer to initialization vector
  14759. size_t iv_len, // IV length in bytes (should == 12)
  14760. const unsigned char *add, // ptr to additional AEAD data (NULL if none)
  14761. size_t add_len) // length of additional AEAD data (bytes)
  14762. {
  14763. int ret; // our error return if the AES encrypt fails
  14764. unsigned char work_buf[16]; // XOR source built from provided IV if len != 16
  14765. const unsigned char *p; // general purpose array pointer
  14766. size_t use_len; // byte count to process, up to 16 bytes
  14767. size_t i; // local loop iterator
  14768. // since the context might be reused under the same key
  14769. // we zero the working buffers for this next new process
  14770. memset(ctx->y, 0x00, sizeof(ctx->y));
  14771. memset(ctx->buf, 0x00, sizeof(ctx->buf));
  14772. ctx->len = 0;
  14773. ctx->add_len = 0;
  14774. ctx->mode = mode; // set the GCM encryption/decryption mode
  14775. ctx->aes_ctx.mode = MG_ENCRYPT; // GCM *always* runs AES in ENCRYPTION mode
  14776. if (iv_len == 12) { // GCM natively uses a 12-byte, 96-bit IV
  14777. memcpy(ctx->y, iv, iv_len); // copy the IV to the top of the 'y' buff
  14778. ctx->y[15] = 1; // start "counting" from 1 (not 0)
  14779. } else // if we don't have a 12-byte IV, we GHASH whatever we've been given
  14780. {
  14781. memset(work_buf, 0x00, 16); // clear the working buffer
  14782. PUT_UINT32_BE(iv_len * 8, work_buf, 12); // place the IV into buffer
  14783. p = iv;
  14784. while (iv_len > 0) {
  14785. use_len = (iv_len < 16) ? iv_len : 16;
  14786. for (i = 0; i < use_len; i++) ctx->y[i] ^= p[i];
  14787. gcm_mult(ctx, ctx->y, ctx->y);
  14788. iv_len -= use_len;
  14789. p += use_len;
  14790. }
  14791. for (i = 0; i < 16; i++) ctx->y[i] ^= work_buf[i];
  14792. gcm_mult(ctx, ctx->y, ctx->y);
  14793. }
  14794. if ((ret = aes_cipher(&ctx->aes_ctx, ctx->y, ctx->base_ectr)) != 0)
  14795. return (ret);
  14796. ctx->add_len = add_len;
  14797. p = add;
  14798. while (add_len > 0) {
  14799. use_len = (add_len < 16) ? add_len : 16;
  14800. for (i = 0; i < use_len; i++) ctx->buf[i] ^= p[i];
  14801. gcm_mult(ctx, ctx->buf, ctx->buf);
  14802. add_len -= use_len;
  14803. p += use_len;
  14804. }
  14805. return (0);
  14806. }
  14807. /******************************************************************************
  14808. *
  14809. * GCM_UPDATE
  14810. *
  14811. * This is called once or more to process bulk plaintext or ciphertext data.
  14812. * We give this some number of bytes of input and it returns the same number
  14813. * of output bytes. If called multiple times (which is fine) all but the final
  14814. * invocation MUST be called with length mod 16 == 0. (Only the final call can
  14815. * have a partial block length of < 128 bits.)
  14816. *
  14817. ******************************************************************************/
  14818. int gcm_update(gcm_context *ctx, // pointer to user-provided GCM context
  14819. size_t length, // length, in bytes, of data to process
  14820. const unsigned char *input, // pointer to source data
  14821. unsigned char *output) // pointer to destination data
  14822. {
  14823. int ret; // our error return if the AES encrypt fails
  14824. unsigned char ectr[16]; // counter-mode cipher output for XORing
  14825. size_t use_len; // byte count to process, up to 16 bytes
  14826. size_t i; // local loop iterator
  14827. ctx->len += length; // bump the GCM context's running length count
  14828. while (length > 0) {
  14829. // clamp the length to process at 16 bytes
  14830. use_len = (length < 16) ? length : 16;
  14831. // increment the context's 128-bit IV||Counter 'y' vector
  14832. for (i = 16; i > 12; i--)
  14833. if (++ctx->y[i - 1] != 0) break;
  14834. // encrypt the context's 'y' vector under the established key
  14835. if ((ret = aes_cipher(&ctx->aes_ctx, ctx->y, ectr)) != 0) return (ret);
  14836. // encrypt or decrypt the input to the output
  14837. if (ctx->mode == MG_ENCRYPT) {
  14838. for (i = 0; i < use_len; i++) {
  14839. // XOR the cipher's ouptut vector (ectr) with our input
  14840. output[i] = (unsigned char) (ectr[i] ^ input[i]);
  14841. // now we mix in our data into the authentication hash.
  14842. // if we're ENcrypting we XOR in the post-XOR (output)
  14843. // results, but if we're DEcrypting we XOR in the input
  14844. // data
  14845. ctx->buf[i] ^= output[i];
  14846. }
  14847. } else {
  14848. for (i = 0; i < use_len; i++) {
  14849. // but if we're DEcrypting we XOR in the input data first,
  14850. // i.e. before saving to ouput data, otherwise if the input
  14851. // and output buffer are the same (inplace decryption) we
  14852. // would not get the correct auth tag
  14853. ctx->buf[i] ^= input[i];
  14854. // XOR the cipher's ouptut vector (ectr) with our input
  14855. output[i] = (unsigned char) (ectr[i] ^ input[i]);
  14856. }
  14857. }
  14858. gcm_mult(ctx, ctx->buf, ctx->buf); // perform a GHASH operation
  14859. length -= use_len; // drop the remaining byte count to process
  14860. input += use_len; // bump our input pointer forward
  14861. output += use_len; // bump our output pointer forward
  14862. }
  14863. return (0);
  14864. }
  14865. /******************************************************************************
  14866. *
  14867. * GCM_FINISH
  14868. *
  14869. * This is called once after all calls to GCM_UPDATE to finalize the GCM.
  14870. * It performs the final GHASH to produce the resulting authentication TAG.
  14871. *
  14872. ******************************************************************************/
  14873. int gcm_finish(gcm_context *ctx, // pointer to user-provided GCM context
  14874. unsigned char *tag, // pointer to buffer which receives the tag
  14875. size_t tag_len) // length, in bytes, of the tag-receiving buf
  14876. {
  14877. unsigned char work_buf[16];
  14878. uint64_t orig_len = ctx->len * 8;
  14879. uint64_t orig_add_len = ctx->add_len * 8;
  14880. size_t i;
  14881. if (tag_len > sizeof(work_buf)) return -1;
  14882. if (tag_len != 0) memcpy(tag, ctx->base_ectr, tag_len);
  14883. if (orig_len || orig_add_len) {
  14884. memset(work_buf, 0x00, 16);
  14885. PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
  14886. PUT_UINT32_BE((orig_add_len), work_buf, 4);
  14887. PUT_UINT32_BE((orig_len >> 32), work_buf, 8);
  14888. PUT_UINT32_BE((orig_len), work_buf, 12);
  14889. for (i = 0; i < 16; i++) ctx->buf[i] ^= work_buf[i];
  14890. gcm_mult(ctx, ctx->buf, ctx->buf);
  14891. for (i = 0; i < tag_len; i++) tag[i] ^= ctx->buf[i];
  14892. }
  14893. return (0);
  14894. }
  14895. /******************************************************************************
  14896. *
  14897. * GCM_CRYPT_AND_TAG
  14898. *
  14899. * This either encrypts or decrypts the user-provided data and, either
  14900. * way, generates an authentication tag of the requested length. It must be
  14901. * called with a GCM context whose key has already been set with GCM_SETKEY.
  14902. *
  14903. * The user would typically call this explicitly to ENCRYPT a buffer of data
  14904. * and optional associated data, and produce its an authentication tag.
  14905. *
  14906. * To reverse the process the user would typically call the companion
  14907. * GCM_AUTH_DECRYPT function to decrypt data and verify a user-provided
  14908. * authentication tag. The GCM_AUTH_DECRYPT function calls this function
  14909. * to perform its decryption and tag generation, which it then compares.
  14910. *
  14911. ******************************************************************************/
  14912. int gcm_crypt_and_tag(
  14913. gcm_context *ctx, // gcm context with key already setup
  14914. int mode, // cipher direction: GCM_ENCRYPT or GCM_DECRYPT
  14915. const unsigned char *iv, // pointer to the 12-byte initialization vector
  14916. size_t iv_len, // byte length if the IV. should always be 12
  14917. const unsigned char *add, // pointer to the non-ciphered additional data
  14918. size_t add_len, // byte length of the additional AEAD data
  14919. const unsigned char *input, // pointer to the cipher data source
  14920. unsigned char *output, // pointer to the cipher data destination
  14921. size_t length, // byte length of the cipher data
  14922. unsigned char *tag, // pointer to the tag to be generated
  14923. size_t tag_len) // byte length of the tag to be generated
  14924. { /*
  14925. assuming that the caller has already invoked gcm_setkey to
  14926. prepare the gcm context with the keying material, we simply
  14927. invoke each of the three GCM sub-functions in turn...
  14928. */
  14929. if (gcm_start(ctx, mode, iv, iv_len, add, add_len) != 0) return -1;
  14930. if (gcm_update(ctx, length, input, output) != 0) return -1;
  14931. return gcm_finish(ctx, tag, tag_len);
  14932. }
  14933. /******************************************************************************
  14934. *
  14935. * GCM_ZERO_CTX
  14936. *
  14937. * The GCM context contains both the GCM context and the AES context.
  14938. * This includes keying and key-related material which is security-
  14939. * sensitive, so it MUST be zeroed after use. This function does that.
  14940. *
  14941. ******************************************************************************/
  14942. void gcm_zero_ctx(gcm_context *ctx) {
  14943. // zero the context originally provided to us
  14944. memset(ctx, 0, sizeof(gcm_context));
  14945. }
  14946. //
  14947. // aes-gcm.c
  14948. // Pods
  14949. //
  14950. // Created by Markus Kosmal on 20/11/14.
  14951. //
  14952. //
  14953. int mg_aes_gcm_encrypt(unsigned char *output, //
  14954. const unsigned char *input, size_t input_length,
  14955. const unsigned char *key, const size_t key_len,
  14956. const unsigned char *iv, const size_t iv_len,
  14957. unsigned char *aead, size_t aead_len, unsigned char *tag,
  14958. const size_t tag_len) {
  14959. int ret = 0; // our return value
  14960. gcm_context ctx; // includes the AES context structure
  14961. gcm_setkey(&ctx, key, (unsigned int) key_len);
  14962. ret = gcm_crypt_and_tag(&ctx, MG_ENCRYPT, iv, iv_len, aead, aead_len, input,
  14963. output, input_length, tag, tag_len);
  14964. gcm_zero_ctx(&ctx);
  14965. return (ret);
  14966. }
  14967. int mg_aes_gcm_decrypt(unsigned char *output, const unsigned char *input,
  14968. size_t input_length, const unsigned char *key,
  14969. const size_t key_len, const unsigned char *iv,
  14970. const size_t iv_len, unsigned char *aead,
  14971. size_t aead_len, const unsigned char *tag,
  14972. const size_t tag_len) {
  14973. int ret = 0; // our return value
  14974. gcm_context ctx; // includes the AES context structure
  14975. unsigned char computed_tag[16];
  14976. if (tag_len > sizeof(computed_tag)) return -1;
  14977. gcm_setkey(&ctx, key, (unsigned int) key_len);
  14978. ret = gcm_crypt_and_tag(&ctx, MG_DECRYPT, iv, iv_len, aead, aead_len, input,
  14979. output, input_length, computed_tag, tag_len);
  14980. gcm_zero_ctx(&ctx);
  14981. if (!mg_memeq(computed_tag, tag, tag_len)) ret = -1;
  14982. return (ret);
  14983. }
  14984. #endif
  14985. // End of aes128 PD
  14986. #ifdef MG_ENABLE_LINES
  14987. #line 1 "src/tls_builtin.c"
  14988. #endif
  14989. #if MG_TLS == MG_TLS_BUILTIN
  14990. #ifndef MG_MAX_TLSOID_DEPTH
  14991. #define MG_MAX_TLSOID_DEPTH 15
  14992. #endif
  14993. // PKCS#8 algorithm OIDs
  14994. static const uint8_t mg_rsa_oid[] = {
  14995. 0x2a, 0x86, 0x48, 0x86, 0xf7,
  14996. 0x0d, 0x01, 0x01, 0x01 // 1.2.840.113549.1.1.1 rsaEncryption
  14997. };
  14998. static const uint8_t mg_ec_public_key_oid[] = {
  14999. 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01 // 1.2.840.10045.2.1 ecPublicKey
  15000. };
  15001. static const uint8_t mg_secp256r1_oid[] = {
  15002. 0x2a, 0x86, 0x48, 0xce,
  15003. 0x3d, 0x03, 0x01, 0x07 // 1.2.840.10045.3.1.7 secp256r1
  15004. };
  15005. /* TLS 1.3 Record Content Type (RFC8446 B.1) */
  15006. #define MG_TLS_CHANGE_CIPHER 20
  15007. #define MG_TLS_ALERT 21
  15008. #define MG_TLS_HANDSHAKE 22
  15009. #define MG_TLS_APP_DATA 23
  15010. #define MG_TLS_HEARTBEAT 24
  15011. /* TLS 1.3 Handshake Message Type (RFC8446 B.3) */
  15012. #define MG_TLS_CLIENT_HELLO 1
  15013. #define MG_TLS_SERVER_HELLO 2
  15014. #define MG_TLS_ENCRYPTED_EXTENSIONS 8
  15015. #define MG_TLS_CERTIFICATE 11
  15016. #define MG_TLS_CERTIFICATE_REQUEST 13
  15017. #define MG_TLS_CERTIFICATE_VERIFY 15
  15018. #define MG_TLS_FINISHED 20
  15019. #define MG_TLS_RSA_USE_CRT 1 // CRT instead of naive RSA
  15020. // handshake is re-entrant, so we need to keep track of its state state names
  15021. // refer to RFC8446#A.1
  15022. enum mg_tls_hs_state {
  15023. // Client state machine:
  15024. MG_TLS_STATE_CLIENT_START, // Send ClientHello
  15025. MG_TLS_STATE_CLIENT_WAIT_SH, // Wait for ServerHello
  15026. MG_TLS_STATE_CLIENT_WAIT_EE, // Wait for EncryptedExtensions
  15027. MG_TLS_STATE_CLIENT_WAIT_CERT, // Wait for Certificate
  15028. MG_TLS_STATE_CLIENT_WAIT_CV, // Wait for CertificateVerify
  15029. MG_TLS_STATE_CLIENT_WAIT_FINISH, // Wait for Finish
  15030. MG_TLS_STATE_CLIENT_CONNECTED, // Done
  15031. // Server state machine:
  15032. MG_TLS_STATE_SERVER_START, // Wait for ClientHello
  15033. MG_TLS_STATE_SERVER_WAIT_CERT, // Wait for Certificate
  15034. MG_TLS_STATE_SERVER_WAIT_CV, // Wait for CertificateVerify
  15035. MG_TLS_STATE_SERVER_NEGOTIATED, // Wait for Finish
  15036. MG_TLS_STATE_SERVER_CONNECTED // Done
  15037. };
  15038. // encryption keys for a TLS connection
  15039. struct tls_enc {
  15040. uint32_t sseq; // server sequence number, used in encryption
  15041. uint32_t cseq; // client sequence number, used in decryption
  15042. // keys for AES encryption or ChaCha20
  15043. uint8_t handshake_secret[32];
  15044. uint8_t server_write_key[32];
  15045. uint8_t server_write_iv[12];
  15046. uint8_t server_finished_key[32];
  15047. uint8_t client_write_key[32];
  15048. uint8_t client_write_iv[12];
  15049. uint8_t client_finished_key[32];
  15050. };
  15051. struct mg_rsa_key {
  15052. struct mg_str n; // modulus
  15053. struct mg_str e; // public exponent
  15054. struct mg_str d; // private exponent
  15055. struct mg_str p; // prime1
  15056. struct mg_str q; // prime2
  15057. struct mg_str dP; // exponent1 (d mod (p-1))
  15058. struct mg_str dQ; // exponent2 (d mod (q-1))
  15059. struct mg_str qInv; // coefficient ((inverse of q) mod p)
  15060. };
  15061. // per-connection TLS data
  15062. struct tls_data {
  15063. enum mg_tls_hs_state state; // keep track of connection handshake progress
  15064. struct mg_iobuf send; // For the receive path, we're reusing c->rtls
  15065. size_t recv_offset; // While c->rtls contains full records, reuse that
  15066. size_t recv_len; // buffer but point at individual decrypted messages
  15067. uint8_t content_type; // Last received record content type
  15068. mg_sha256_ctx sha256; // incremental SHA-256 hash for TLS handshake
  15069. uint8_t random[32]; // client random from ClientHello
  15070. uint8_t session_id[32]; // client session ID between the handshake states
  15071. uint8_t x25519_cli[32]; // client X25519 key between the handshake states
  15072. uint8_t x25519_sec[32]; // x25519 secret between the handshake states
  15073. bool skip_verification; // do not perform checks on server certificate
  15074. bool cert_requested; // client received a CertificateRequest
  15075. bool is_twoway; // server is configured to authenticate clients
  15076. bool is_sntp_pending; // TLS handshake is waiting for wall-clock time
  15077. struct mg_connection *timec; // SNTP connection for wall-clock time
  15078. struct mg_str cert_der; // certificate in DER format
  15079. struct mg_str ca_der; // current CA certificate
  15080. struct mg_str *ca_bundle_der; // bundle of CA certificates
  15081. size_t ca_bundle_len; // number of certificates in bundle
  15082. struct mg_str *chain_der; // certificate chain (intermediate certs)
  15083. size_t chain_len; // number of certificates in chain
  15084. uint8_t ec_key[32]; // EC private key
  15085. struct mg_rsa_key rsa;
  15086. struct mg_str rsa_key_der; // RSA private key in DER format
  15087. char hostname[254]; // matching hostname
  15088. bool is_ec_pubkey; // EC or RSA. TODO(): currently unused
  15089. uint8_t pubkey[512 + 16]; // server EC (64) or RSA (512+exp) public key to
  15090. // verify cert
  15091. size_t pubkeysz; // size of the server public key
  15092. uint8_t sighash[32]; // calculated signature verification hash
  15093. struct tls_enc enc; // actual keys in use at this time
  15094. struct tls_enc app_keys; // storage during two-way auth handshake
  15095. };
  15096. #define TLS_RECHDR_SIZE 5 // 1 byte type, 2 bytes version, 2 bytes length
  15097. #define TLS_MSGHDR_SIZE 4 // 1 byte type, 3 bytes length
  15098. #ifdef MG_TLS_SSLKEYLOGFILE
  15099. #include <stdio.h>
  15100. static void mg_ssl_key_log(const char *label, uint8_t client_random[32],
  15101. uint8_t *secret, size_t secretsz) {
  15102. FILE *f;
  15103. char *keylogfile = getenv("SSLKEYLOGFILE");
  15104. if (keylogfile == NULL) return;
  15105. MG_DEBUG(("Dumping key log into %s", keylogfile));
  15106. f = fopen(keylogfile, "a");
  15107. if (f != NULL) {
  15108. size_t i;
  15109. fprintf(f, "%s ", label);
  15110. for (i = 0; i < 32; i++) {
  15111. fprintf(f, "%02x", client_random[i]);
  15112. }
  15113. fprintf(f, " ");
  15114. for (i = 0; i < secretsz; i++) {
  15115. fprintf(f, "%02x", secret[i]);
  15116. }
  15117. fprintf(f, "\n");
  15118. fclose(f);
  15119. } else {
  15120. MG_ERROR(("Cannot open %s", keylogfile));
  15121. }
  15122. }
  15123. #endif
  15124. // for derived tls keys we need SHA256([0]*32)
  15125. static uint8_t zeros[32] = {0};
  15126. static uint8_t zeros_sha256_digest[32] = {
  15127. 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4,
  15128. 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b,
  15129. 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55};
  15130. // helper to hexdump buffers inline
  15131. static void mg_tls_hexdump(const char *msg, uint8_t *buf, size_t bufsz) {
  15132. MG_VERBOSE(("%s: %M", msg, mg_print_hex, bufsz, buf));
  15133. }
  15134. // helper utilities to parse ASN.1 DER
  15135. struct mg_der_tlv {
  15136. uint8_t type;
  15137. uint32_t len;
  15138. uint8_t *value;
  15139. };
  15140. // parse DER into a TLV record
  15141. static int mg_der_to_tlv(uint8_t *der, size_t dersz, struct mg_der_tlv *tlv) {
  15142. uint32_t n = 0;
  15143. if (dersz < 2) return -1;
  15144. tlv->type = der[0];
  15145. tlv->len = der[1];
  15146. tlv->value = der + 2;
  15147. if (tlv->len > 0x7f) { // long-form length
  15148. uint32_t i;
  15149. n = tlv->len - 0x80;
  15150. if (n == 0 || n > 4 || dersz < (2 + n)) return -1;
  15151. tlv->len = 0;
  15152. for (i = 0; i < n; i++) {
  15153. tlv->len = (tlv->len << 8) | der[2 + i];
  15154. }
  15155. tlv->value += n;
  15156. }
  15157. if (tlv->len > dersz - (size_t) (tlv->value - der)) return -1;
  15158. return (int) n;
  15159. }
  15160. static int mg_der_parse(uint8_t *der, size_t dersz, struct mg_der_tlv *tlv) {
  15161. int n = mg_der_to_tlv(der, dersz, tlv);
  15162. if (n < 0) return -1;
  15163. if (tlv->len >= (uint32_t)((unsigned) -6)) return -1; // avoid overflow
  15164. return 2 + n + (int) tlv->len; // 2: type, len; n = long form len bytes
  15165. }
  15166. static int mg_der_next(struct mg_der_tlv *parent, struct mg_der_tlv *child) {
  15167. int consumed;
  15168. if (parent->len == 0) return 0;
  15169. consumed = mg_der_parse(parent->value, parent->len, child);
  15170. if (consumed < 0) return -1;
  15171. parent->value += consumed;
  15172. parent->len -= (uint32_t) consumed;
  15173. return 1;
  15174. }
  15175. static int der_find_oid(struct mg_der_tlv *tlv, const uint8_t *oid, size_t oid_len, struct mg_der_tlv *found, int depth) {
  15176. struct mg_der_tlv parent, child;
  15177. int r;
  15178. parent = *tlv;
  15179. while ((r = mg_der_next(&parent, &child)) > 0) {
  15180. if (child.type == 0x06 && child.len == oid_len &&
  15181. memcmp(child.value, oid, oid_len) == 0) {
  15182. return mg_der_next(&parent, found);
  15183. } else if (child.type & 0x20) {
  15184. struct mg_der_tlv sub_parent = child;
  15185. if (depth >= MG_MAX_TLSOID_DEPTH) {
  15186. MG_ERROR(("too nested der"));
  15187. return -1;
  15188. }
  15189. if ((r = der_find_oid(&sub_parent, oid, oid_len, found, depth + 1)) > 0)
  15190. return 1;
  15191. if (r < 0) return -1; // exit on error; r = 0 => not found, keep parsing
  15192. }
  15193. }
  15194. if (r < 0) return -1;
  15195. return 0;
  15196. }
  15197. static int mg_der_find_oid(struct mg_der_tlv *tlv, const uint8_t *oid,
  15198. size_t oid_len, struct mg_der_tlv *found) {
  15199. return der_find_oid(tlv, oid, oid_len, found, 0);
  15200. }
  15201. #if 0
  15202. static void mg_der_debug(struct mg_der_tlv *tlv, int depth) {
  15203. MG_DEBUG(("> %.*sd=%d Type: 0x%02X, Length: %u\n", depth * 4, " ", depth,
  15204. tlv->type, tlv->len));
  15205. if (tlv->type & 0x20) { // Constructed: recurse into children
  15206. struct mg_der_tlv child;
  15207. struct mg_der_tlv parent = *tlv;
  15208. while (mg_der_next(&parent, &child) > 0) {
  15209. mg_der_debug(&child, depth + 1);
  15210. }
  15211. }
  15212. }
  15213. #endif
  15214. // Did we receive a full TLS record in the c->rtls buffer?
  15215. static bool mg_tls_got_record(struct mg_connection *c) {
  15216. return c->rtls.len >= (size_t) TLS_RECHDR_SIZE &&
  15217. c->rtls.len >=
  15218. (size_t) (TLS_RECHDR_SIZE + MG_LOAD_BE16(c->rtls.buf + 3));
  15219. }
  15220. // Remove a single TLS record from the recv buffer
  15221. static void mg_tls_drop_record(struct mg_connection *c) {
  15222. struct mg_iobuf *rio = &c->rtls;
  15223. uint16_t n = MG_LOAD_BE16(rio->buf + 3) + TLS_RECHDR_SIZE;
  15224. mg_iobuf_del(rio, 0, n);
  15225. }
  15226. // Remove a single TLS message from decrypted buffer, remove the wrapping
  15227. // record if it was the last message within a record
  15228. static void mg_tls_drop_message(struct mg_connection *c) {
  15229. uint32_t len;
  15230. struct tls_data *tls = (struct tls_data *) c->tls;
  15231. unsigned char *recv_buf = &c->rtls.buf[tls->recv_offset];
  15232. if (tls->recv_len == 0) return;
  15233. len = MG_LOAD_BE24(recv_buf + 1) + TLS_MSGHDR_SIZE;
  15234. if (tls->recv_len < len) {
  15235. mg_error(c, "wrong size");
  15236. return;
  15237. }
  15238. mg_sha256_update(&tls->sha256, recv_buf, len);
  15239. tls->recv_offset += len;
  15240. tls->recv_len -= len;
  15241. if (tls->recv_len == 0) {
  15242. mg_tls_drop_record(c);
  15243. }
  15244. }
  15245. // TLS1.3 secret derivation based on the key label
  15246. static void mg_tls_derive_secret(const char *label, uint8_t *key, size_t keysz,
  15247. uint8_t *data, size_t datasz, uint8_t *hash,
  15248. size_t hashsz) {
  15249. size_t labelsz = strlen(label);
  15250. uint8_t secret[32];
  15251. uint8_t packed[256] = {0, (uint8_t) hashsz, (uint8_t) labelsz};
  15252. // TODO: assert lengths of label, key, data and hash
  15253. if (labelsz > 0) memmove(packed + 3, label, labelsz);
  15254. packed[3 + labelsz] = (uint8_t) datasz;
  15255. if (datasz > 0) memmove(packed + labelsz + 4, data, datasz);
  15256. packed[4 + labelsz + datasz] = 1;
  15257. mg_hmac_sha256(secret, key, keysz, packed, 5 + labelsz + datasz);
  15258. memmove(hash, secret, hashsz);
  15259. }
  15260. // at this point we have x25519 shared secret, we can generate a set of derived
  15261. // handshake encryption keys
  15262. static void mg_tls_generate_handshake_keys(struct mg_connection *c) {
  15263. struct tls_data *tls = (struct tls_data *) c->tls;
  15264. mg_sha256_ctx sha256;
  15265. uint8_t early_secret[32];
  15266. uint8_t pre_extract_secret[32];
  15267. uint8_t hello_hash[32];
  15268. uint8_t server_hs_secret[32];
  15269. uint8_t client_hs_secret[32];
  15270. #if MG_ENABLE_CHACHA20
  15271. const size_t keysz = 32;
  15272. #else
  15273. const size_t keysz = 16;
  15274. #endif
  15275. mg_hmac_sha256(early_secret, NULL, 0, zeros, sizeof(zeros));
  15276. mg_tls_derive_secret("tls13 derived", early_secret, 32, zeros_sha256_digest,
  15277. 32, pre_extract_secret, 32);
  15278. mg_hmac_sha256(tls->enc.handshake_secret, pre_extract_secret,
  15279. sizeof(pre_extract_secret), tls->x25519_sec,
  15280. sizeof(tls->x25519_sec));
  15281. mg_tls_hexdump("hs secret", tls->enc.handshake_secret, 32);
  15282. // mg_sha256_final is not idempotent, need to copy sha256 context to calculate
  15283. // the digest
  15284. memmove(&sha256, &tls->sha256, sizeof(mg_sha256_ctx));
  15285. mg_sha256_final(hello_hash, &sha256);
  15286. mg_tls_hexdump("hello hash", hello_hash, 32);
  15287. // derive keys needed for the rest of the handshake
  15288. mg_tls_derive_secret("tls13 s hs traffic", tls->enc.handshake_secret, 32,
  15289. hello_hash, 32, server_hs_secret, 32);
  15290. mg_tls_derive_secret("tls13 c hs traffic", tls->enc.handshake_secret, 32,
  15291. hello_hash, 32, client_hs_secret, 32);
  15292. mg_tls_derive_secret("tls13 key", server_hs_secret, 32, NULL, 0,
  15293. tls->enc.server_write_key, keysz);
  15294. mg_tls_derive_secret("tls13 iv", server_hs_secret, 32, NULL, 0,
  15295. tls->enc.server_write_iv, 12);
  15296. mg_tls_derive_secret("tls13 finished", server_hs_secret, 32, NULL, 0,
  15297. tls->enc.server_finished_key, 32);
  15298. mg_tls_derive_secret("tls13 key", client_hs_secret, 32, NULL, 0,
  15299. tls->enc.client_write_key, keysz);
  15300. mg_tls_derive_secret("tls13 iv", client_hs_secret, 32, NULL, 0,
  15301. tls->enc.client_write_iv, 12);
  15302. mg_tls_derive_secret("tls13 finished", client_hs_secret, 32, NULL, 0,
  15303. tls->enc.client_finished_key, 32);
  15304. mg_tls_hexdump("s hs traffic", server_hs_secret, 32);
  15305. mg_tls_hexdump("s key", tls->enc.server_write_key, keysz);
  15306. mg_tls_hexdump("s iv", tls->enc.server_write_iv, 12);
  15307. mg_tls_hexdump("s finished", tls->enc.server_finished_key, 32);
  15308. mg_tls_hexdump("c hs traffic", client_hs_secret, 32);
  15309. mg_tls_hexdump("c key", tls->enc.client_write_key, keysz);
  15310. mg_tls_hexdump("c iv", tls->enc.client_write_iv, 12);
  15311. mg_tls_hexdump("c finished", tls->enc.client_finished_key, 32);
  15312. #ifdef MG_TLS_SSLKEYLOGFILE
  15313. mg_ssl_key_log("SERVER_HANDSHAKE_TRAFFIC_SECRET", tls->random,
  15314. server_hs_secret, 32);
  15315. mg_ssl_key_log("CLIENT_HANDSHAKE_TRAFFIC_SECRET", tls->random,
  15316. client_hs_secret, 32);
  15317. #endif
  15318. }
  15319. static void mg_tls_generate_application_keys(struct mg_connection *c) {
  15320. struct tls_data *tls = (struct tls_data *) c->tls;
  15321. uint8_t hash[32];
  15322. uint8_t premaster_secret[32];
  15323. uint8_t master_secret[32];
  15324. uint8_t server_secret[32];
  15325. uint8_t client_secret[32];
  15326. #if MG_ENABLE_CHACHA20
  15327. const size_t keysz = 32;
  15328. #else
  15329. const size_t keysz = 16;
  15330. #endif
  15331. mg_sha256_ctx sha256;
  15332. memmove(&sha256, &tls->sha256, sizeof(mg_sha256_ctx));
  15333. mg_sha256_final(hash, &sha256);
  15334. mg_tls_derive_secret("tls13 derived", tls->enc.handshake_secret, 32,
  15335. zeros_sha256_digest, 32, premaster_secret, 32);
  15336. mg_hmac_sha256(master_secret, premaster_secret, 32, zeros, 32);
  15337. mg_tls_derive_secret("tls13 s ap traffic", master_secret, 32, hash, 32,
  15338. server_secret, 32);
  15339. mg_tls_derive_secret("tls13 key", server_secret, 32, NULL, 0,
  15340. tls->enc.server_write_key, keysz);
  15341. mg_tls_derive_secret("tls13 iv", server_secret, 32, NULL, 0,
  15342. tls->enc.server_write_iv, 12);
  15343. mg_tls_derive_secret("tls13 c ap traffic", master_secret, 32, hash, 32,
  15344. client_secret, 32);
  15345. mg_tls_derive_secret("tls13 key", client_secret, 32, NULL, 0,
  15346. tls->enc.client_write_key, keysz);
  15347. mg_tls_derive_secret("tls13 iv", client_secret, 32, NULL, 0,
  15348. tls->enc.client_write_iv, 12);
  15349. mg_tls_hexdump("s ap traffic", server_secret, 32);
  15350. mg_tls_hexdump("s key", tls->enc.server_write_key, keysz);
  15351. mg_tls_hexdump("s iv", tls->enc.server_write_iv, 12);
  15352. mg_tls_hexdump("s finished", tls->enc.server_finished_key, 32);
  15353. mg_tls_hexdump("c ap traffic", client_secret, 32);
  15354. mg_tls_hexdump("c key", tls->enc.client_write_key, keysz);
  15355. mg_tls_hexdump("c iv", tls->enc.client_write_iv, 12);
  15356. mg_tls_hexdump("c finished", tls->enc.client_finished_key, 32);
  15357. tls->enc.sseq = tls->enc.cseq = 0;
  15358. #ifdef MG_TLS_SSLKEYLOGFILE
  15359. mg_ssl_key_log("SERVER_TRAFFIC_SECRET_0", tls->random, server_secret, 32);
  15360. mg_ssl_key_log("CLIENT_TRAFFIC_SECRET_0", tls->random, client_secret, 32);
  15361. #endif
  15362. }
  15363. // AES GCM encryption of the message + put encoded data into the write buffer
  15364. static bool mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg,
  15365. size_t msgsz, uint8_t msgtype) {
  15366. struct tls_data *tls = (struct tls_data *) c->tls;
  15367. struct mg_iobuf *wio = &tls->send;
  15368. uint8_t *outmsg;
  15369. uint8_t *tag;
  15370. size_t encsz = msgsz + 16 + 1;
  15371. uint8_t hdr[5] = {MG_TLS_APP_DATA, 0x03, 0x03,
  15372. (uint8_t) ((encsz >> 8) & 0xff), (uint8_t) (encsz & 0xff)};
  15373. uint8_t associated_data[5] = {MG_TLS_APP_DATA, 0x03, 0x03,
  15374. (uint8_t) ((encsz >> 8) & 0xff),
  15375. (uint8_t) (encsz & 0xff)};
  15376. uint8_t nonce[12];
  15377. uint32_t seq = c->is_client ? tls->enc.cseq : tls->enc.sseq;
  15378. uint8_t *key =
  15379. c->is_client ? tls->enc.client_write_key : tls->enc.server_write_key;
  15380. uint8_t *iv =
  15381. c->is_client ? tls->enc.client_write_iv : tls->enc.server_write_iv;
  15382. if (msgsz > 16384) {
  15383. MG_ERROR(("msg longer than recordsz"));
  15384. return false;
  15385. }
  15386. #if MG_ENABLE_CHACHA20
  15387. #else
  15388. mg_gcm_initialize();
  15389. #endif
  15390. memmove(nonce, iv, sizeof(nonce));
  15391. nonce[8] ^= (uint8_t) ((seq >> 24) & 255U);
  15392. nonce[9] ^= (uint8_t) ((seq >> 16) & 255U);
  15393. nonce[10] ^= (uint8_t) ((seq >> 8) & 255U);
  15394. nonce[11] ^= (uint8_t) ((seq) & 255U);
  15395. if (mg_iobuf_add(wio, wio->len, hdr, sizeof(hdr)) == 0 ||
  15396. !mg_iobuf_resize(wio, wio->len + encsz))
  15397. return false;
  15398. outmsg = wio->buf + wio->len;
  15399. tag = wio->buf + wio->len + msgsz + 1;
  15400. memmove(outmsg, msg, msgsz);
  15401. outmsg[msgsz] = msgtype;
  15402. #if MG_ENABLE_CHACHA20
  15403. (void) tag; // tag is only used in aes gcm
  15404. {
  15405. size_t n;
  15406. uint8_t *enc = (uint8_t *) mg_calloc(1, msgsz + 256 + 1);
  15407. if (enc == NULL) return false;
  15408. n = mg_chacha20_poly1305_encrypt(enc, key, nonce, associated_data,
  15409. sizeof(associated_data), outmsg,
  15410. msgsz + 1);
  15411. memmove(outmsg, enc, n);
  15412. mg_free(enc);
  15413. }
  15414. #else
  15415. mg_aes_gcm_encrypt(outmsg, outmsg, msgsz + 1, key, 16, nonce, sizeof(nonce),
  15416. associated_data, sizeof(associated_data), tag, 16);
  15417. #endif
  15418. c->is_client ? tls->enc.cseq++ : tls->enc.sseq++;
  15419. wio->len += encsz;
  15420. return true;
  15421. }
  15422. static void verbose_alert(uint8_t *buf) {
  15423. uint8_t level = buf[0], desc = buf[1];
  15424. MG_INFO(("TLS ALERT received: level=%d, desc=%d (%s)", level, desc,
  15425. desc == 0 ? "close_notify"
  15426. : desc == 10 ? "unexpected_message"
  15427. : desc == 20 ? "bad_record_mac"
  15428. : desc == 21 ? "decryption_failed"
  15429. : desc == 40 ? "handshake_failure"
  15430. : desc == 42 ? "bad_certificate"
  15431. : desc == 43 ? "unsupported_certificate"
  15432. : desc == 44 ? "certificate_revoked"
  15433. : desc == 45 ? "certificate_expired"
  15434. : desc == 46 ? "certificate_unknown"
  15435. : desc == 48 ? "unknown_ca"
  15436. : "unknown"));
  15437. }
  15438. // read an encrypted record, decrypt it in place
  15439. static int mg_tls_recv_record(struct mg_connection *c) {
  15440. struct tls_data *tls = (struct tls_data *) c->tls;
  15441. struct mg_iobuf *rio = &c->rtls;
  15442. uint16_t msgsz;
  15443. uint8_t *msg;
  15444. uint8_t nonce[12];
  15445. int r;
  15446. uint32_t seq = c->is_client ? tls->enc.sseq : tls->enc.cseq;
  15447. uint8_t *key =
  15448. c->is_client ? tls->enc.server_write_key : tls->enc.client_write_key;
  15449. uint8_t *iv =
  15450. c->is_client ? tls->enc.server_write_iv : tls->enc.client_write_iv;
  15451. if (tls->recv_len > 0) {
  15452. return 0; /* some data from previous record is still present */
  15453. }
  15454. for (;;) {
  15455. if (!mg_tls_got_record(c)) {
  15456. return MG_IO_WAIT;
  15457. }
  15458. if (rio->buf[0] == MG_TLS_APP_DATA) {
  15459. break;
  15460. } else if (rio->buf[0] == MG_TLS_CHANGE_CIPHER) { // skip CCS
  15461. mg_tls_drop_record(c);
  15462. } else if (rio->buf[0] == MG_TLS_ALERT) { // Skip Alerts
  15463. if (rio->len >= 7) {
  15464. verbose_alert(&rio->buf[5]);
  15465. } else {
  15466. MG_INFO(("TLS ALERT packet received (short)"));
  15467. }
  15468. mg_tls_drop_record(c);
  15469. } else {
  15470. mg_error(c, "unexpected packet");
  15471. return -1;
  15472. }
  15473. }
  15474. msgsz = MG_LOAD_BE16(rio->buf + 3);
  15475. msg = rio->buf + 5;
  15476. if (msgsz < 17) {
  15477. mg_error(c, "wrong size");
  15478. return -1;
  15479. }
  15480. memmove(nonce, iv, sizeof(nonce));
  15481. nonce[8] ^= (uint8_t) ((seq >> 24) & 255U);
  15482. nonce[9] ^= (uint8_t) ((seq >> 16) & 255U);
  15483. nonce[10] ^= (uint8_t) ((seq >> 8) & 255U);
  15484. nonce[11] ^= (uint8_t) ((seq) & 255U);
  15485. #if MG_ENABLE_CHACHA20
  15486. {
  15487. uint8_t associated_data[5] = {MG_TLS_APP_DATA, 0x03, 0x03,
  15488. (uint8_t) ((msgsz >> 8) & 0xff),
  15489. (uint8_t) (msgsz & 0xff)};
  15490. uint8_t *dec = (uint8_t *) mg_calloc(1, msgsz);
  15491. size_t n;
  15492. if (dec == NULL) {
  15493. mg_error(c, "TLS OOM");
  15494. return -1;
  15495. }
  15496. n = mg_chacha20_poly1305_decrypt(dec, key, nonce, associated_data,
  15497. sizeof(associated_data), msg, msgsz);
  15498. if (n == (size_t) -1) {
  15499. mg_free(dec);
  15500. mg_error(c, "decryption error");
  15501. return -1;
  15502. }
  15503. memmove(msg, dec, n);
  15504. mg_free(dec);
  15505. }
  15506. #else
  15507. {
  15508. uint8_t associated_data[5] = {MG_TLS_APP_DATA, 0x03, 0x03,
  15509. (uint8_t) ((msgsz >> 8) & 0xff),
  15510. (uint8_t) (msgsz & 0xff)};
  15511. mg_gcm_initialize();
  15512. if (mg_aes_gcm_decrypt(msg, msg, msgsz - 16, key, 16, nonce, sizeof(nonce),
  15513. associated_data, sizeof(associated_data),
  15514. msg + msgsz - 16, 16) != 0) {
  15515. mg_error(c, "GCM tag verify failed");
  15516. return -1;
  15517. }
  15518. }
  15519. #endif
  15520. r = msgsz - 16 - 1;
  15521. tls->content_type = msg[msgsz - 16 - 1];
  15522. if (tls->content_type == MG_TLS_ALERT) { // Process Alerts
  15523. verbose_alert(msg);
  15524. if (msg[0] == 2) {
  15525. mg_error(c, "TLS Fatal alert");
  15526. return -1;
  15527. } else {
  15528. mg_tls_drop_record(c);
  15529. return MG_IO_WAIT;
  15530. }
  15531. }
  15532. tls->recv_offset = (size_t) msg - (size_t) rio->buf;
  15533. tls->recv_len = (size_t) msgsz - 16 - 1;
  15534. c->is_client ? tls->enc.sseq++ : tls->enc.cseq++;
  15535. return r;
  15536. }
  15537. static void mg_tls_calc_cert_verify_hash(struct mg_connection *c,
  15538. uint8_t hash[32], bool is_client) {
  15539. struct tls_data *tls = (struct tls_data *) c->tls;
  15540. uint8_t sig_content[130];
  15541. mg_sha256_ctx sha256;
  15542. memset(sig_content, 0x20, 64);
  15543. if (is_client) {
  15544. uint8_t client_context[34] = "TLS 1.3, client CertificateVerify";
  15545. memcpy(sig_content + 64, client_context, sizeof(client_context));
  15546. } else {
  15547. uint8_t server_context[34] = "TLS 1.3, server CertificateVerify";
  15548. memcpy(sig_content + 64, server_context, sizeof(server_context));
  15549. }
  15550. memmove(&sha256, &tls->sha256, sizeof(mg_sha256_ctx));
  15551. mg_sha256_final(sig_content + 98, &sha256);
  15552. mg_sha256_init(&sha256);
  15553. mg_sha256_update(&sha256, sig_content, sizeof(sig_content));
  15554. mg_sha256_final(hash, &sha256);
  15555. }
  15556. // read and parse ClientHello record
  15557. static int mg_tls_server_recv_hello(struct mg_connection *c) {
  15558. struct tls_data *tls = (struct tls_data *) c->tls;
  15559. struct mg_iobuf *rio = &c->rtls;
  15560. uint8_t session_id_len;
  15561. uint16_t j;
  15562. uint16_t cipher_suites_len;
  15563. uint16_t ext_len;
  15564. uint8_t *ext;
  15565. uint16_t msgsz;
  15566. if (!mg_tls_got_record(c)) {
  15567. return MG_IO_WAIT;
  15568. }
  15569. if (rio->buf[0] != MG_TLS_HANDSHAKE || rio->buf[5] != MG_TLS_CLIENT_HELLO) {
  15570. mg_error(c, "not a client hello packet");
  15571. return -1;
  15572. }
  15573. if (rio->len < 50) goto fail;
  15574. msgsz = MG_LOAD_BE16(rio->buf + 3);
  15575. if (((uint32_t) msgsz + 4) > rio->len) goto fail;
  15576. mg_sha256_update(&tls->sha256, rio->buf + 5, msgsz);
  15577. // store client random
  15578. memmove(tls->random, rio->buf + 11, sizeof(tls->random));
  15579. // store session_id
  15580. session_id_len = rio->buf[43];
  15581. if (session_id_len == sizeof(tls->session_id)) {
  15582. if (rio->len < (size_t)(46 + session_id_len)) goto fail; // 2: ciphers len
  15583. memmove(tls->session_id, rio->buf + 44, session_id_len);
  15584. } else if (session_id_len != 0) {
  15585. MG_ERROR(("bad session id len"));
  15586. goto fail;
  15587. } // session_id_len is either sizeof(tls->session_id) or 0
  15588. if (((uint32_t) 44 + 2 + session_id_len) > rio->len) goto fail;
  15589. cipher_suites_len = MG_LOAD_BE16(rio->buf + 44 + session_id_len);
  15590. if (((uint32_t) cipher_suites_len + 46 + 2 + 2 + session_id_len) > rio->len)
  15591. goto fail;
  15592. ext_len = MG_LOAD_BE16(rio->buf + 48 + session_id_len + cipher_suites_len);
  15593. ext = rio->buf + 50 + session_id_len + cipher_suites_len;
  15594. if (((unsigned char *) ext + ext_len) > (rio->buf + rio->len)) goto fail;
  15595. for (j = 0; j < ext_len;) {
  15596. uint16_t k;
  15597. uint16_t key_exchange_len;
  15598. uint8_t *key_exchange;
  15599. uint16_t n = MG_LOAD_BE16(ext + j + 2);
  15600. if (((uint32_t) n + j + 4) > ext_len) goto fail;
  15601. if (MG_LOAD_BE16(ext + j) != 0x0033) { // not a key share extension, ignore
  15602. j += (uint16_t) (n + 4);
  15603. continue;
  15604. }
  15605. key_exchange_len = MG_LOAD_BE16(ext + j + 4);
  15606. key_exchange = ext + j + 6;
  15607. if ((key_exchange + key_exchange_len) > ((uint8_t *) rio->buf + rio->len))
  15608. goto fail;
  15609. for (k = 0; k < key_exchange_len;) {
  15610. uint16_t m = MG_LOAD_BE16(key_exchange + k + 2);
  15611. if (((uint32_t) m + k + 4) > key_exchange_len) goto fail;
  15612. if (m == 32 && key_exchange[k] == 0x00 && key_exchange[k + 1] == 0x1d) {
  15613. memmove(tls->x25519_cli, key_exchange + k + 4, m);
  15614. mg_tls_drop_record(c);
  15615. return 0;
  15616. }
  15617. k += (uint16_t) (m + 4);
  15618. }
  15619. j += (uint16_t) (n + 4);
  15620. }
  15621. fail:
  15622. mg_error(c, "bad client hello");
  15623. return -1;
  15624. }
  15625. #define PLACEHOLDER_8B 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'
  15626. #define PLACEHOLDER_16B PLACEHOLDER_8B, PLACEHOLDER_8B
  15627. #define PLACEHOLDER_32B PLACEHOLDER_16B, PLACEHOLDER_16B
  15628. // put ServerHello record into wio buffer
  15629. static bool mg_tls_server_send_hello(struct mg_connection *c) {
  15630. struct tls_data *tls = (struct tls_data *) c->tls;
  15631. struct mg_iobuf *wio = &tls->send;
  15632. // clang-format off
  15633. uint8_t msg_server_hello[122] = {
  15634. // server hello, tls 1.2
  15635. 0x02, 0x00, 0x00, 0x76, 0x03, 0x03,
  15636. // random (32 bytes)
  15637. PLACEHOLDER_32B,
  15638. // session ID length + session ID (32 bytes)
  15639. 0x20, PLACEHOLDER_32B,
  15640. #if MG_ENABLE_CHACHA20
  15641. // TLS_CHACHA20_POLY1305_SHA256 + no compression
  15642. 0x13, 0x03, 0x00,
  15643. #else
  15644. // TLS_AES_128_GCM_SHA256 + no compression
  15645. 0x13, 0x01, 0x00,
  15646. #endif
  15647. // extensions + keyshare
  15648. 0x00, 0x2e, 0x00, 0x33, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20,
  15649. // x25519 keyshare
  15650. PLACEHOLDER_32B,
  15651. // supported versions (tls1.3 == 0x304)
  15652. 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04};
  15653. // clang-format on
  15654. // calculate keyshare
  15655. uint8_t x25519_pub[X25519_BYTES];
  15656. uint8_t x25519_prv[X25519_BYTES];
  15657. if (!mg_random(x25519_prv, sizeof(x25519_prv))) mg_error(c, "RNG");
  15658. if( mg_tls_x25519(x25519_pub, x25519_prv, X25519_BASE_POINT, 1) < 0 || mg_tls_x25519(tls->x25519_sec, x25519_prv, tls->x25519_cli, 1) < 0) {
  15659. mg_error(c, "bad key");
  15660. return false;
  15661. }
  15662. mg_tls_hexdump("s x25519 sec", tls->x25519_sec, sizeof(tls->x25519_sec));
  15663. // fill in the gaps: random + session ID + keyshare
  15664. memmove(msg_server_hello + 6, tls->random, sizeof(tls->random));
  15665. memmove(msg_server_hello + 39, tls->session_id, sizeof(tls->session_id));
  15666. memmove(msg_server_hello + 84, x25519_pub, sizeof(x25519_pub));
  15667. // server hello message
  15668. if (mg_iobuf_add(wio, wio->len, "\x16\x03\x03\x00\x7a", 5) == 0 ||
  15669. mg_iobuf_add(wio, wio->len, msg_server_hello, sizeof(msg_server_hello)) ==
  15670. 0)
  15671. return false;
  15672. mg_sha256_update(&tls->sha256, msg_server_hello, sizeof(msg_server_hello));
  15673. // change cipher message
  15674. if (mg_iobuf_add(wio, wio->len, "\x14\x03\x03\x00\x01\x01", 6) == 0)
  15675. return false;
  15676. return true;
  15677. }
  15678. static bool mg_tls_server_send_ext(struct mg_connection *c) {
  15679. struct tls_data *tls = (struct tls_data *) c->tls;
  15680. // server extensions
  15681. uint8_t ext[6] = {0x08, 0, 0, 2, 0, 0};
  15682. mg_sha256_update(&tls->sha256, ext, sizeof(ext));
  15683. return mg_tls_encrypt(c, ext, sizeof(ext), MG_TLS_HANDSHAKE);
  15684. }
  15685. // signature algorithms we actually support:
  15686. // rsa_pkcs1_sha256, rsa_pss_rsae_sha256 and ecdsa_secp256r1_sha256
  15687. static const uint8_t secp256r1_sig_algs[12] = {
  15688. 0x00, 0x0d, 0x00, 0x08, 0x00, 0x06, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01};
  15689. static bool mg_tls_server_send_cert_request(struct mg_connection *c) {
  15690. struct tls_data *tls = (struct tls_data *) c->tls;
  15691. uint8_t req[13 + sizeof(secp256r1_sig_algs)];
  15692. req[0] = MG_TLS_CERTIFICATE_REQUEST; // handshake header
  15693. MG_STORE_BE24(req + 1, 9 + sizeof(secp256r1_sig_algs));
  15694. req[4] = 0; // context length
  15695. MG_STORE_BE16(req + 5, 6 + sizeof(secp256r1_sig_algs)); // extensions length
  15696. MG_STORE_BE16(req + 7, 13); // "signature algorithms"
  15697. MG_STORE_BE16(req + 9, 2 + sizeof(secp256r1_sig_algs)); // length
  15698. MG_STORE_BE16(
  15699. req + 11,
  15700. sizeof(secp256r1_sig_algs)); // signature hash algorithms length
  15701. memcpy(req + 13, (uint8_t *) secp256r1_sig_algs, sizeof(secp256r1_sig_algs));
  15702. mg_sha256_update(&tls->sha256, req, sizeof(req));
  15703. return mg_tls_encrypt(c, req, sizeof(req), MG_TLS_HANDSHAKE);
  15704. }
  15705. static bool mg_tls_send_cert(struct mg_connection *c, bool is_client) {
  15706. struct tls_data *tls = (struct tls_data *) c->tls;
  15707. int send_ca = !is_client && tls->ca_der.len > 0;
  15708. // DER certificate + CA (server optional)
  15709. size_t i, offset, total_size = tls->cert_der.len + 5;
  15710. uint8_t *cert;
  15711. bool res = false;
  15712. for (i = 1; i < tls->chain_len; i++) {
  15713. total_size += tls->chain_der[i].len + 5;
  15714. }
  15715. if (send_ca) {
  15716. total_size += tls->ca_der.len + 5;
  15717. }
  15718. cert = (uint8_t *) mg_calloc(1, 13 + total_size);
  15719. if (cert == NULL) return res;
  15720. cert[0] = MG_TLS_CERTIFICATE; // handshake header
  15721. if (is_client && tls->cert_der.len == 0) total_size = 0; // empty list
  15722. MG_STORE_BE24(cert + 1, total_size + 4);
  15723. cert[4] = 0; // request context
  15724. MG_STORE_BE24(cert + 5, total_size); // 3 bytes: cert (s) length
  15725. offset = 8;
  15726. if (total_size > 0) { // handle empty list, RFC-8446 4.4.2
  15727. MG_STORE_BE24(cert + offset, tls->cert_der.len); // 3 bytes: 1st cert len
  15728. offset += 3;
  15729. // bytes 11+ are certificate in DER format
  15730. memmove(cert + offset, tls->cert_der.buf, tls->cert_der.len);
  15731. offset += tls->cert_der.len;
  15732. MG_STORE_BE16(cert + offset, 0); // certificate extensions (none)
  15733. offset += 2;
  15734. for (i = 1; i < tls->chain_len; i++) {
  15735. MG_STORE_BE24(cert + offset, tls->chain_der[i].len);
  15736. offset += 3;
  15737. memmove(cert + offset, tls->chain_der[i].buf, tls->chain_der[i].len);
  15738. offset += tls->chain_der[i].len;
  15739. MG_STORE_BE16(cert + offset, 0); // certificate extensions (none)
  15740. offset += 2;
  15741. }
  15742. if (send_ca) {
  15743. MG_STORE_BE24(cert + offset, tls->ca_der.len); // 3 bytes: CA cert length
  15744. offset += 3;
  15745. memmove(cert + offset, tls->ca_der.buf,
  15746. tls->ca_der.len); // CA cert data
  15747. offset += tls->ca_der.len;
  15748. MG_STORE_BE16(cert + offset, 0); // certificate extensions (none)
  15749. offset += 2;
  15750. }
  15751. }
  15752. mg_sha256_update(&tls->sha256, cert, offset);
  15753. res = mg_tls_encrypt(c, cert, offset, MG_TLS_HANDSHAKE);
  15754. mg_free(cert);
  15755. return res;
  15756. }
  15757. // type adapter between uECC hash context and our sha256 implementation
  15758. typedef struct SHA256_HashContext {
  15759. MG_UECC_HashContext uECC;
  15760. mg_sha256_ctx ctx;
  15761. } SHA256_HashContext;
  15762. static void init_SHA256(const MG_UECC_HashContext *base) {
  15763. SHA256_HashContext *c = (SHA256_HashContext *) base;
  15764. mg_sha256_init(&c->ctx);
  15765. }
  15766. static void update_SHA256(const MG_UECC_HashContext *base,
  15767. const uint8_t *message, unsigned message_size) {
  15768. SHA256_HashContext *c = (SHA256_HashContext *) base;
  15769. mg_sha256_update(&c->ctx, message, message_size);
  15770. }
  15771. static void finish_SHA256(const MG_UECC_HashContext *base,
  15772. uint8_t *hash_result) {
  15773. SHA256_HashContext *c = (SHA256_HashContext *) base;
  15774. mg_sha256_final(hash_result, &c->ctx);
  15775. }
  15776. static void mg_tls_mgf1(uint8_t *mask, size_t mask_len, const uint8_t *seed,
  15777. size_t seed_len) {
  15778. uint32_t counter = 0;
  15779. size_t chunk, chunk_len, generated = 0;
  15780. while (generated < mask_len) {
  15781. mg_sha256_ctx ctx;
  15782. uint8_t digest[32];
  15783. uint8_t ctr[4];
  15784. ctr[0] = (uint8_t) (counter >> 24);
  15785. ctr[1] = (uint8_t) (counter >> 16);
  15786. ctr[2] = (uint8_t) (counter >> 8);
  15787. ctr[3] = (uint8_t) counter;
  15788. mg_sha256_init(&ctx);
  15789. mg_sha256_update(&ctx, seed, seed_len);
  15790. mg_sha256_update(&ctx, ctr, sizeof(ctr));
  15791. mg_sha256_final(digest, &ctx);
  15792. chunk_len = mask_len - generated;
  15793. chunk = (chunk_len < sizeof(digest) ? chunk_len : sizeof(digest));
  15794. memmove(mask + generated, digest, chunk);
  15795. generated += chunk;
  15796. counter++;
  15797. }
  15798. }
  15799. static unsigned int mg_tls_rsa_bits(const struct mg_str *n) {
  15800. size_t i = 0;
  15801. unsigned int bits = 0;
  15802. while (i < n->len && n->buf[i] == 0) i++;
  15803. if (i == n->len) return 0;
  15804. bits = (unsigned int) ((n->len - i) * 8);
  15805. {
  15806. uint8_t byte = (uint8_t) n->buf[i];
  15807. while ((byte & 0x80U) == 0) {
  15808. bits--;
  15809. byte = (uint8_t) (byte << 1);
  15810. }
  15811. }
  15812. return bits;
  15813. }
  15814. static bool mg_tls_pss_encode(const uint8_t *hash, size_t hashlen,
  15815. const struct mg_str *n, uint8_t *em) {
  15816. size_t emlen = n->len, saltlen = hashlen, dblen, pslen, i;
  15817. uint8_t salt[64]; // Max salt size for any reasonable hash
  15818. uint8_t m[136]; // 8 + max hash (64) + max salt (64) = 136
  15819. uint8_t H[64]; // Max hash size
  15820. uint8_t DB[512]; // Max for 4096-bit RSA
  15821. uint8_t mask[512]; // Max for 4096-bit RSA
  15822. mg_sha256_ctx ctx;
  15823. // Check bounds
  15824. if (saltlen > sizeof(salt) || (8 + hashlen + saltlen) > sizeof(m) ||
  15825. hashlen > sizeof(H) || emlen > sizeof(DB)) {
  15826. MG_ERROR(("RSA key too large for static buffers"));
  15827. return false;
  15828. }
  15829. if (emlen < hashlen + saltlen + 2) {
  15830. return false;
  15831. }
  15832. if (!mg_random(salt, saltlen)) {
  15833. return false;
  15834. }
  15835. MG_VERBOSE(("PSS salt: %M", mg_print_hex, saltlen, salt));
  15836. // Build m = 8 zero bytes || hash || salt
  15837. memset(m, 0, 8);
  15838. memcpy(m + 8, hash, hashlen);
  15839. memcpy(m + 8 + hashlen, salt, saltlen);
  15840. mg_sha256_init(&ctx);
  15841. mg_sha256_update(&ctx, m, 8 + hashlen + saltlen);
  15842. mg_sha256_final(H, &ctx);
  15843. MG_VERBOSE(("PSS H: %M", mg_print_hex, hashlen, H));
  15844. dblen = emlen - hashlen - 1;
  15845. pslen = emlen - hashlen - saltlen - 2;
  15846. // Build DB = PS || 0x01 || salt
  15847. memset(DB, 0, pslen);
  15848. DB[pslen] = 0x01;
  15849. memcpy(DB + pslen + 1, salt, saltlen);
  15850. // Generate mask and apply to DB
  15851. mg_tls_mgf1(mask, dblen, H, hashlen);
  15852. for (i = 0; i < dblen; i++) DB[i] ^= mask[i];
  15853. {
  15854. // PSS standard: emBits = modulus_bit_length - 1
  15855. unsigned rsa_bits = mg_tls_rsa_bits(n);
  15856. unsigned embits = rsa_bits - 1;
  15857. unsigned unused = (unsigned) (8 * emlen - embits);
  15858. MG_VERBOSE(("RSA modulus bits: %u, emBits: %u, emlen: %zu, unused: %u",
  15859. rsa_bits, embits, emlen, unused));
  15860. if (unused > 0 && unused < 8) {
  15861. uint8_t mask_byte = (uint8_t) (0xff >> unused);
  15862. MG_VERBOSE(("Applying mask 0x%02x to first byte (was 0x%02x)", mask_byte,
  15863. DB[0]));
  15864. DB[0] &= mask_byte;
  15865. MG_VERBOSE(("First byte after mask: 0x%02x", DB[0]));
  15866. }
  15867. }
  15868. // Build final em = maskedDB || H || 0xbc
  15869. memcpy(em, DB, dblen);
  15870. memcpy(em + dblen, H, hashlen);
  15871. em[emlen - 1] = 0xbc;
  15872. return true;
  15873. }
  15874. static bool mg_tls_rsa_sign(struct tls_data *tls, const uint8_t *em,
  15875. size_t emlen, uint8_t *sig) {
  15876. const uint8_t *n = (const uint8_t *) tls->rsa.n.buf;
  15877. size_t nlen = tls->rsa.n.len;
  15878. int crt_result;
  15879. while (nlen > 0 && *n == 0) n++, nlen--;
  15880. if (emlen != nlen) return false;
  15881. #if MG_TLS_RSA_USE_CRT
  15882. // RSA CRT (Chinese Remainder Theorem) optimization:
  15883. // s1 = em^dP mod p
  15884. // s2 = em^dQ mod q
  15885. // h = qInv * (s1 - s2) mod p
  15886. // s = s2 + h * q
  15887. if (tls->rsa.p.len == 0 || tls->rsa.q.len == 0 || tls->rsa.dP.len == 0 ||
  15888. tls->rsa.dQ.len == 0 || tls->rsa.qInv.len == 0) {
  15889. MG_ERROR(("CRT parameters missing, cannot use CRT optimization"));
  15890. return false;
  15891. }
  15892. MG_VERBOSE(("Using RSA-CRT optimization"));
  15893. crt_result = mg_rsa_crt_sign(
  15894. em, emlen, (const uint8_t *) tls->rsa.dP.buf, tls->rsa.dP.len,
  15895. (const uint8_t *) tls->rsa.dQ.buf, tls->rsa.dQ.len,
  15896. (const uint8_t *) tls->rsa.p.buf, tls->rsa.p.len,
  15897. (const uint8_t *) tls->rsa.q.buf, tls->rsa.q.len,
  15898. (const uint8_t *) tls->rsa.qInv.buf, tls->rsa.qInv.len, sig, nlen);
  15899. if (crt_result == 0) {
  15900. uint8_t check[512];
  15901. bool verified;
  15902. if (nlen > sizeof(check) ||
  15903. mg_rsa_mod_pow(n, nlen, (const uint8_t *) tls->rsa.e.buf,
  15904. tls->rsa.e.len, sig, nlen, check, nlen) != 0) {
  15905. MG_ERROR(("CRT signature verification failed"));
  15906. return false;
  15907. }
  15908. verified = memcmp(check, em, emlen) == 0;
  15909. mg_bzero(check, sizeof(check));
  15910. if (!verified) {
  15911. MG_ERROR(("CRT signature verification failed"));
  15912. return false;
  15913. }
  15914. MG_VERBOSE(("CRT signature successful (first 4 bytes): %02x %02x %02x %02x",
  15915. sig[0], sig[1], sig[2], sig[3]));
  15916. MG_VERBOSE(("CRT signature successful (last 4 bytes): %02x %02x %02x %02x",
  15917. sig[nlen - 4], sig[nlen - 3], sig[nlen - 2], sig[nlen - 1]));
  15918. return true;
  15919. } else {
  15920. MG_ERROR(("CRT signing failed"));
  15921. return false;
  15922. }
  15923. #else
  15924. int ret;
  15925. // Standard RSA: s = em^d mod n
  15926. memset(sig, 0, nlen);
  15927. ret = mg_rsa_mod_pow(n, nlen, (const uint8_t *) tls->rsa.d.buf,
  15928. tls->rsa.d.len, em, emlen, sig, nlen);
  15929. if (ret == 0) {
  15930. MG_VERBOSE(("RSA signature first 4 bytes: %02x %02x %02x %02x", sig[0],
  15931. sig[1], sig[2], sig[3]));
  15932. MG_VERBOSE(("RSA signature last 4 bytes: %02x %02x %02x %02x",
  15933. sig[nlen - 4], sig[nlen - 3], sig[nlen - 2], sig[nlen - 1]));
  15934. }
  15935. return ret == 0;
  15936. #endif
  15937. }
  15938. static size_t mg_rsa_trim_len(const uint8_t **p, size_t n) {
  15939. while (n > 0 && **p == 0) (*p)++, n--;
  15940. return n;
  15941. }
  15942. static bool mg_tls_send_cert_verify(struct mg_connection *c, bool is_client) {
  15943. struct tls_data *tls = (struct tls_data *) c->tls;
  15944. uint8_t hash[32] = {0};
  15945. mg_tls_calc_cert_verify_hash(c, (uint8_t *) hash, is_client);
  15946. if (tls->rsa.n.len > 0 && tls->rsa.d.len > 0) {
  15947. // RSA certificate verify packet
  15948. const uint8_t *n = (const uint8_t *) tls->rsa.n.buf;
  15949. size_t nlen = tls->rsa.n.len;
  15950. struct mg_str rn;
  15951. size_t emlen, verifysz;
  15952. uint8_t em[512]; // Max for 4096-bit RSA
  15953. uint8_t verify[520]; // 8 + 512 max
  15954. nlen = mg_rsa_trim_len(&n, nlen);
  15955. rn = mg_str_n((char *) n, nlen);
  15956. emlen = nlen;
  15957. verifysz = 8U + emlen;
  15958. // Check bounds
  15959. if (emlen > sizeof(em) || verifysz > sizeof(verify)) {
  15960. MG_ERROR(("RSA key too large for static buffers"));
  15961. return false;
  15962. }
  15963. if (!mg_tls_pss_encode(hash, sizeof(hash), &rn, em)) {
  15964. MG_ERROR(("Failed PSS encode"));
  15965. return false;
  15966. }
  15967. // Validate PSS encoded message format
  15968. if (em[emlen - 1] != 0xbc) {
  15969. MG_ERROR(("Invalid PSS encoding: last byte is 0x%02x, expected 0xbc",
  15970. em[emlen - 1]));
  15971. return false;
  15972. }
  15973. // Build verify packet header, then sign directly into the packet
  15974. verify[0] = 0x0f;
  15975. MG_STORE_BE24(verify + 1, emlen + 4);
  15976. MG_STORE_BE16(verify + 4, 0x0804);
  15977. MG_STORE_BE16(verify + 6, emlen);
  15978. // Sign directly into the verify buffer (verify + 8 = signature location)
  15979. memset(verify + 8, 0, emlen); // Initialize signature area
  15980. if (!mg_tls_rsa_sign(tls, em, emlen, verify + 8)) {
  15981. MG_ERROR(("Failed RSA sign"));
  15982. return false;
  15983. }
  15984. MG_VERBOSE(
  15985. ("PSS EM first 4: %02x %02x %02x %02x", em[0], em[1], em[2], em[3]));
  15986. MG_VERBOSE(("PSS EM last 4: %02x %02x %02x %02x", em[emlen - 4],
  15987. em[emlen - 3], em[emlen - 2], em[emlen - 1]));
  15988. mg_sha256_update(&tls->sha256, verify, verifysz);
  15989. return mg_tls_encrypt(c, verify, verifysz, MG_TLS_HANDSHAKE);
  15990. } else {
  15991. // EC certificate verify packet
  15992. uint8_t verify[82] = {0x0f, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00};
  15993. uint8_t tmp[2 * 32 + 64] = {0};
  15994. struct SHA256_HashContext ctx = {
  15995. {&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp},
  15996. {{0}, 0, 0, {0}}};
  15997. size_t sigsz, verifysz = 0;
  15998. int neg1, neg2;
  15999. uint8_t sig[64] = {0};
  16000. mg_uecc_sign_deterministic(tls->ec_key, hash, sizeof(hash), &ctx.uECC, sig,
  16001. mg_uecc_secp256r1());
  16002. neg1 = !!(sig[0] & 0x80);
  16003. neg2 = !!(sig[32] & 0x80);
  16004. verify[8] = 0x30; // ASN.1 SEQUENCE
  16005. verify[9] = (uint8_t) (68 + neg1 + neg2);
  16006. verify[10] = 0x02; // ASN.1 INTEGER
  16007. verify[11] = (uint8_t) (32 + neg1);
  16008. memmove(verify + 12 + neg1, sig, 32);
  16009. verify[12 + 32 + neg1] = 0x02; // ASN.1 INTEGER
  16010. verify[13 + 32 + neg1] = (uint8_t) (32 + neg2);
  16011. memmove(verify + 14 + 32 + neg1 + neg2, sig + 32, 32);
  16012. sigsz = (size_t) (70 + neg1 + neg2);
  16013. verifysz = 8U + sigsz;
  16014. verify[3] = (uint8_t) (sigsz + 4);
  16015. verify[7] = (uint8_t) sigsz;
  16016. mg_sha256_update(&tls->sha256, verify, verifysz);
  16017. return mg_tls_encrypt(c, verify, verifysz, MG_TLS_HANDSHAKE);
  16018. }
  16019. }
  16020. static bool mg_tls_server_send_finish(struct mg_connection *c) {
  16021. struct tls_data *tls = (struct tls_data *) c->tls;
  16022. mg_sha256_ctx sha256;
  16023. uint8_t hash[32];
  16024. uint8_t finish[36] = {0x14, 0, 0, 32};
  16025. memmove(&sha256, &tls->sha256, sizeof(mg_sha256_ctx));
  16026. mg_sha256_final(hash, &sha256);
  16027. mg_hmac_sha256(finish + 4, tls->enc.server_finished_key, 32, hash, 32);
  16028. if (!mg_tls_encrypt(c, finish, sizeof(finish), MG_TLS_HANDSHAKE))
  16029. return false;
  16030. mg_sha256_update(&tls->sha256, finish, sizeof(finish));
  16031. return true;
  16032. }
  16033. static int mg_tls_server_recv_finish(struct mg_connection *c) {
  16034. struct tls_data *tls = (struct tls_data *) c->tls;
  16035. unsigned char *recv_buf;
  16036. // we have to backup sha256 value to restore it later, since Finished record
  16037. // is exceptional and is not supposed to be added to the rolling hash
  16038. // calculation.
  16039. mg_sha256_ctx sha256 = tls->sha256;
  16040. if (mg_tls_recv_record(c) < 0) {
  16041. return -1;
  16042. }
  16043. recv_buf = &c->rtls.buf[tls->recv_offset];
  16044. if (recv_buf[0] != MG_TLS_FINISHED) {
  16045. mg_error(c, "expected Finish but got msg 0x%02x", recv_buf[0]);
  16046. return -1;
  16047. }
  16048. mg_tls_drop_message(c);
  16049. // restore hash
  16050. tls->sha256 = sha256;
  16051. return 0;
  16052. }
  16053. static bool mg_tls_client_send_hello(struct mg_connection *c) {
  16054. struct tls_data *tls = (struct tls_data *) c->tls;
  16055. struct mg_iobuf *wio = &tls->send;
  16056. uint8_t x25519_pub[X25519_BYTES];
  16057. // - "signature algorithms we actually support", see above
  16058. // uint8_t secp256r1_sig_algs[]
  16059. // - all popular signature algorithms (if we don't care about verification)
  16060. uint8_t all_sig_algs[34] = {
  16061. 0x00, 0x0d, 0x00, 0x1e, 0x00, 0x1c, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03,
  16062. 0x08, 0x07, 0x08, 0x08, 0x08, 0x09, 0x08, 0x0a, 0x08, 0x0b, 0x08, 0x04,
  16063. 0x08, 0x05, 0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01};
  16064. uint8_t server_name_ext[9] = {0x00, 0x00, 0x00, 0xfe, 0x00,
  16065. 0xfe, 0x00, 0x00, 0xfe};
  16066. // clang-format off
  16067. uint8_t msg_client_hello[145] = {
  16068. // TLS Client Hello header reported as TLS1.2 (5)
  16069. 0x16, 0x03, 0x03, 0x00, 0xfe,
  16070. // client hello, tls 1.2 (6)
  16071. 0x01, 0x00, 0x00, 0x8c, 0x03, 0x03,
  16072. // random (32 bytes)
  16073. PLACEHOLDER_32B,
  16074. // session ID length + session ID (32 bytes)
  16075. 0x20, PLACEHOLDER_32B, 0x00,
  16076. 0x02, // size = 2 bytes
  16077. #if MG_ENABLE_CHACHA20
  16078. // TLS_CHACHA20_POLY1305_SHA256
  16079. 0x13, 0x03,
  16080. #else
  16081. // TLS_AES_128_GCM_SHA256
  16082. 0x13, 0x01,
  16083. #endif
  16084. // no compression
  16085. 0x01, 0x00,
  16086. // extensions + keyshare
  16087. 0x00, 0xfe,
  16088. // x25519 keyshare
  16089. 0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20,
  16090. PLACEHOLDER_32B,
  16091. // supported groups (x25519)
  16092. 0x00, 0x0a, 0x00, 0x04, 0x00, 0x02, 0x00, 0x1d,
  16093. // supported versions (tls1.3 == 0x304)
  16094. 0x00, 0x2b, 0x00, 0x03, 0x02, 0x03, 0x04,
  16095. // session ticket (none)
  16096. 0x00, 0x23, 0x00, 0x00, // 144 bytes till here
  16097. };
  16098. // clang-format on
  16099. const char *hostname = tls->hostname;
  16100. size_t hostnamesz = strlen(tls->hostname);
  16101. size_t hostname_extsz = hostnamesz ? hostnamesz + 9 : 0;
  16102. uint8_t *sig_alg =
  16103. tls->skip_verification ? all_sig_algs : (uint8_t *) secp256r1_sig_algs;
  16104. size_t sig_alg_sz = tls->skip_verification ? sizeof(all_sig_algs)
  16105. : sizeof(secp256r1_sig_algs);
  16106. // patch ClientHello with correct hostname ext length (if any)
  16107. MG_STORE_BE16(msg_client_hello + 3,
  16108. hostname_extsz + 183 - 9 - 34 + sig_alg_sz);
  16109. MG_STORE_BE16(msg_client_hello + 7,
  16110. hostname_extsz + 179 - 9 - 34 + sig_alg_sz);
  16111. MG_STORE_BE16(msg_client_hello + 82,
  16112. hostname_extsz + 104 - 9 - 34 + sig_alg_sz);
  16113. if (hostnamesz > 0) {
  16114. MG_STORE_BE16(server_name_ext + 2, hostnamesz + 5);
  16115. MG_STORE_BE16(server_name_ext + 4, hostnamesz + 3);
  16116. MG_STORE_BE16(server_name_ext + 7, hostnamesz);
  16117. }
  16118. // calculate keyshare
  16119. if (!mg_random(tls->x25519_cli, sizeof(tls->x25519_cli))) mg_error(c, "RNG");
  16120. mg_tls_x25519(x25519_pub, tls->x25519_cli, X25519_BASE_POINT, 1);
  16121. // fill in the gaps: random + session ID + keyshare
  16122. if (!mg_random(tls->session_id, sizeof(tls->session_id))) mg_error(c, "RNG");
  16123. if (!mg_random(tls->random, sizeof(tls->random))) mg_error(c, "RNG");
  16124. memmove(msg_client_hello + 11, tls->random, sizeof(tls->random));
  16125. memmove(msg_client_hello + 44, tls->session_id, sizeof(tls->session_id));
  16126. memmove(msg_client_hello + 94, x25519_pub, sizeof(x25519_pub));
  16127. // client hello message
  16128. if (mg_iobuf_add(wio, wio->len, msg_client_hello, sizeof(msg_client_hello)) ==
  16129. 0)
  16130. return false;
  16131. mg_sha256_update(&tls->sha256, msg_client_hello + 5,
  16132. sizeof(msg_client_hello) - 5);
  16133. if (mg_iobuf_add(wio, wio->len, sig_alg, sig_alg_sz) == 0) return false;
  16134. mg_sha256_update(&tls->sha256, sig_alg, sig_alg_sz);
  16135. if (hostnamesz > 0) {
  16136. if (mg_iobuf_add(wio, wio->len, server_name_ext, sizeof(server_name_ext)) ==
  16137. 0 ||
  16138. mg_iobuf_add(wio, wio->len, hostname, hostnamesz) == 0)
  16139. return false;
  16140. mg_sha256_update(&tls->sha256, server_name_ext, sizeof(server_name_ext));
  16141. mg_sha256_update(&tls->sha256, (uint8_t *) hostname, hostnamesz);
  16142. }
  16143. // change cipher message
  16144. if (mg_iobuf_add(wio, wio->len, (const char *) "\x14\x03\x03\x00\x01\x01",
  16145. 6) == 0)
  16146. return false;
  16147. return true;
  16148. }
  16149. static int mg_tls_client_recv_hello(struct mg_connection *c) {
  16150. struct tls_data *tls = (struct tls_data *) c->tls;
  16151. struct mg_iobuf *rio = &c->rtls;
  16152. uint16_t msgsz;
  16153. uint8_t *ext;
  16154. uint16_t ext_len;
  16155. int j;
  16156. if (!mg_tls_got_record(c)) {
  16157. return MG_IO_WAIT;
  16158. }
  16159. if (rio->buf[0] != MG_TLS_HANDSHAKE || rio->len < 6 || rio->buf[5] != MG_TLS_SERVER_HELLO) {
  16160. if (rio->buf[0] == MG_TLS_ALERT && rio->len >= 7) {
  16161. verbose_alert(&rio->buf[5]);
  16162. mg_error(c, "TLS error alert");
  16163. return -1;
  16164. }
  16165. if (rio->len >= 6) MG_ERROR(("got packet type 0x%02x/0x%02x", rio->buf[0], rio->buf[5]));
  16166. mg_error(c, "not a server hello packet");
  16167. return -1;
  16168. }
  16169. if (rio->len < 5 + 39 + 32 + 3 + 2) goto fail;
  16170. msgsz = MG_LOAD_BE16(rio->buf + 3);
  16171. if (msgsz > rio->len - 5) goto fail;
  16172. mg_sha256_update(&tls->sha256, rio->buf + 5, msgsz);
  16173. ext_len = MG_LOAD_BE16(rio->buf + 5 + 39 + 32 + 3);
  16174. ext = rio->buf + 5 + 39 + 32 + 3 + 2;
  16175. if (ext_len > (rio->len - (5 + 39 + 32 + 3 + 2))) goto fail;
  16176. for (j = 0; j < ext_len;) {
  16177. uint16_t ext_type, ext_len2, group, key_exchange_len;
  16178. uint8_t *key_exchange;
  16179. if ((ext_len - j) < 4) goto fail;
  16180. ext_type = MG_LOAD_BE16(ext + j);
  16181. ext_len2 = MG_LOAD_BE16(ext + j + 2);
  16182. if (ext_len2 > (ext_len - j - 4)) goto fail;
  16183. if (ext_type != 0x0033) { // not a key share extension, ignore
  16184. j += (uint16_t) (ext_len2 + 4);
  16185. continue;
  16186. }
  16187. if (ext_len2 < (2 + 2 + 32)) goto fail;
  16188. group = MG_LOAD_BE16(ext + j + 4);
  16189. if (group != 0x001d) {
  16190. mg_error(c, "bad key exchange group");
  16191. return -1;
  16192. }
  16193. key_exchange_len = MG_LOAD_BE16(ext + j + 6);
  16194. key_exchange = ext + j + 8;
  16195. if (key_exchange_len != 32 || mg_tls_x25519(tls->x25519_sec, tls->x25519_cli, key_exchange, 1) < 0) {
  16196. mg_error(c, "bad key");
  16197. return -1;
  16198. }
  16199. mg_tls_hexdump("c x25519 sec", tls->x25519_sec, 32);
  16200. mg_tls_drop_record(c);
  16201. /* generate handshake keys */
  16202. mg_tls_generate_handshake_keys(c);
  16203. return 0;
  16204. }
  16205. fail:
  16206. mg_error(c, "bad server hello");
  16207. return -1;
  16208. }
  16209. static int mg_tls_client_recv_ext(struct mg_connection *c) {
  16210. struct tls_data *tls = (struct tls_data *) c->tls;
  16211. unsigned char *recv_buf;
  16212. if (mg_tls_recv_record(c) < 0) {
  16213. return -1;
  16214. }
  16215. recv_buf = &c->rtls.buf[tls->recv_offset];
  16216. if (recv_buf[0] != MG_TLS_ENCRYPTED_EXTENSIONS) {
  16217. mg_error(c, "expected server extensions but got msg 0x%02x", recv_buf[0]);
  16218. return -1;
  16219. }
  16220. mg_tls_drop_message(c);
  16221. return 0;
  16222. }
  16223. struct mg_tls_cert {
  16224. bool is_ec_pubkey;
  16225. bool is_ca;
  16226. struct mg_str sn;
  16227. struct mg_str pubkey;
  16228. struct mg_der_tlv issuer;
  16229. struct mg_der_tlv subj;
  16230. struct mg_str sig; // signature
  16231. uint8_t tbshash[48]; // 32B for sha256/secp256, 48B for sha384/secp384
  16232. size_t tbshashsz; // actual TBS hash size
  16233. };
  16234. static void mg_der_debug_cert_name(const char *name, struct mg_der_tlv *tlv) {
  16235. struct mg_der_tlv v;
  16236. struct mg_str cn, c, o, ou;
  16237. if (mg_log_level < MG_LL_VERBOSE) return; // skip recursive computations
  16238. cn = c = o = ou = mg_str("");
  16239. if (mg_der_find_oid(tlv, (uint8_t *) "\x55\x04\x03", 3, &v) > 0)
  16240. cn = mg_str_n((const char *) v.value, v.len);
  16241. if (mg_der_find_oid(tlv, (uint8_t *) "\x55\x04\x06", 3, &v) > 0)
  16242. c = mg_str_n((const char *) v.value, v.len);
  16243. if (mg_der_find_oid(tlv, (uint8_t *) "\x55\x04\x0a", 3, &v) > 0)
  16244. o = mg_str_n((const char *) v.value, v.len);
  16245. if (mg_der_find_oid(tlv, (uint8_t *) "\x55\x04\x0b", 3, &v) > 0)
  16246. ou = mg_str_n((const char *) v.value, v.len);
  16247. MG_VERBOSE(("%s: CN=%.*s, C=%.*s, O=%.*s, OU=%.*s", name, cn.len, cn.buf,
  16248. c.len, c.buf, o.len, o.buf, ou.len, ou.buf));
  16249. }
  16250. static uint64_t asnt2t(uint8_t *v, uint8_t type) {
  16251. unsigned int y, mo, d, h, mi, ss;
  16252. y = 10U * (*v++ - '0'), y += (*v++ - '0');
  16253. if (type == 0x17) { // UTCTime, RFC-5280 4.1.2.5.1 YYMMDDHHMMSSZ
  16254. if (y >= 50) return (uint64_t) 0; // 19YY is in the past
  16255. y += 2000;
  16256. } else { // GeneralizedTime, RFC-5280 4.1.2.5.2 YYYYMMDDHHMMSSZ
  16257. y *= 100U, y += 10U * (*v++ - '0'), y += (*v++ - '0');
  16258. }
  16259. mo = 10U * (*v++ - '0'), mo += (*v++ - '0');
  16260. d = 10U * (*v++ - '0'), d += (*v++ - '0');
  16261. h = 10U * (*v++ - '0'), h += (*v++ - '0');
  16262. mi = 10U * (*v++ - '0'), mi += (*v++ - '0');
  16263. ss = 10U * (*v++ - '0'), ss += (*v++ - '0');
  16264. if (*v != 'Z') return 0; // invalid
  16265. return mg_timegm(y, mo, d, h, mi, ss);
  16266. }
  16267. static int mg_tls_parse_cert_der(void *buf, size_t dersz,
  16268. struct mg_tls_cert *cert) {
  16269. uint8_t *tbs, *der = (uint8_t *) buf;
  16270. size_t tbssz;
  16271. struct mg_der_tlv root, tbs_cert, field, algo; // pubkey, signature;
  16272. struct mg_der_tlv pki, pki_algo, pki_key, pki_curve, raw_sig;
  16273. // Parse outermost SEQUENCE
  16274. if (mg_der_parse(der, dersz, &root) <= 0 || root.type != 0x30) return -1;
  16275. // Parse TBSCertificate SEQUENCE
  16276. tbs = root.value;
  16277. if (mg_der_next(&root, &tbs_cert) <= 0 || tbs_cert.type != 0x30) return -1;
  16278. tbssz = (size_t) (tbs_cert.value + tbs_cert.len - tbs);
  16279. // Parse Version (optional field)
  16280. if (mg_der_next(&tbs_cert, &field) <= 0) return -1;
  16281. if (field.type == 0xa0) { // v3
  16282. if (mg_der_parse(field.value, field.len, &field) <= 0 || field.len != 1 ||
  16283. field.value[0] != 2)
  16284. return -1;
  16285. if (mg_der_next(&tbs_cert, &field) <= 0) return -1;
  16286. }
  16287. // Parse Serial Number
  16288. if (field.type != 2) return -1;
  16289. cert->sn = mg_str_n((char *) field.value, field.len);
  16290. MG_VERBOSE(("cert s/n: %M", mg_print_hex, cert->sn.len, cert->sn.buf));
  16291. // Parse signature algorithm (first occurrence)
  16292. if (mg_der_next(&tbs_cert, &field) <= 0 || field.type != 0x30) return -1;
  16293. if (mg_der_next(&field, &algo) <= 0 || algo.type != 0x06) return -1;
  16294. MG_VERBOSE(("sig algo (oid): %M", mg_print_hex, algo.len, algo.value));
  16295. // Signature algorithm OID mapping
  16296. if (algo.len == 8 &&
  16297. memcmp(algo.value, "\x2A\x86\x48\xCE\x3D\x04\x03\x02", 8) == 0) {
  16298. MG_VERBOSE(("sig algo: ECDSA with SHA256"));
  16299. mg_sha256(cert->tbshash, tbs, tbssz);
  16300. cert->tbshashsz = 32;
  16301. } else if (algo.len == 9 &&
  16302. memcmp(algo.value, "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B", 9) ==
  16303. 0) {
  16304. MG_VERBOSE(("sig algo: RSA with SHA256"));
  16305. mg_sha256(cert->tbshash, tbs, tbssz);
  16306. cert->tbshashsz = 32;
  16307. } else if (algo.len == 8 &&
  16308. memcmp(algo.value, "\x2A\x86\x48\xCE\x3D\x04\x03\x03", 8) == 0) {
  16309. MG_VERBOSE(("sig algo: ECDSA with SHA384"));
  16310. mg_sha384(cert->tbshash, tbs, tbssz);
  16311. cert->tbshashsz = 48;
  16312. } else if (algo.len == 9 &&
  16313. memcmp(algo.value, "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0C", 9) ==
  16314. 0) {
  16315. MG_VERBOSE(("sig algo: RSA with SHA384"));
  16316. mg_sha384(cert->tbshash, tbs, tbssz);
  16317. cert->tbshashsz = 48;
  16318. } else {
  16319. MG_ERROR(
  16320. ("sig algo: unsupported OID: %M", mg_print_hex, algo.len, algo.value));
  16321. return -1;
  16322. }
  16323. MG_VERBOSE(("tbs hash: %M", mg_print_hex, cert->tbshashsz, cert->tbshash));
  16324. // issuer
  16325. if (mg_der_next(&tbs_cert, &field) <= 0 || field.type != 0x30) return -1;
  16326. cert->issuer = field;
  16327. mg_der_debug_cert_name("issuer", &field);
  16328. // validity dates (before/after)
  16329. if (mg_der_next(&tbs_cert, &field) <= 0 || field.type != 0x30) return -1;
  16330. {
  16331. struct mg_der_tlv before, after;
  16332. uint64_t now = mg_now() / 1000U, t;
  16333. if (mg_der_next(&field, &before) <= 0 || ((before.type != 0x17 || before.len != 13) && (before.type != 0x18 || before.len != 15))) return -1;
  16334. if (now < (t = asnt2t(before.value, before.type))) {
  16335. MG_ERROR(("cert is not yet valid: before=%.*s (%lu), now=%lu", before.len, before.value, t, now));
  16336. return -1;
  16337. }
  16338. if (mg_der_next(&field, &after) <= 0 || ((after.type != 0x17 || after.len != 13) && (after.type != 0x18 || after.len != 15))) return -1;
  16339. if (memcmp(after.value, "99991231235959Z", 15) == 0) { // RFC-5280 4.1.2.5
  16340. MG_ERROR(("No well-defined expiration date"));
  16341. return -1;
  16342. }
  16343. if (now > (t = asnt2t(after.value, after.type))) {
  16344. MG_ERROR(("cert is no longer valid: after=%.*s (%lu), now=%lu", after.len, after.value, t, now));
  16345. return -1;
  16346. }
  16347. }
  16348. // subject
  16349. if (mg_der_next(&tbs_cert, &field) <= 0 || field.type != 0x30) return -1;
  16350. cert->subj = field;
  16351. mg_der_debug_cert_name("subject", &field);
  16352. // subject public key info
  16353. if (mg_der_next(&tbs_cert, &field) <= 0 || field.type != 0x30) return -1;
  16354. if (mg_der_next(&field, &pki) <= 0 || pki.type != 0x30) return -1;
  16355. if (mg_der_next(&pki, &pki_algo) <= 0 || pki_algo.type != 0x06) return -1;
  16356. // public key algorithm
  16357. MG_VERBOSE(("pk algo (oid): %M", mg_print_hex, pki_algo.len, pki_algo.value));
  16358. if (pki_algo.len == 8 &&
  16359. memcmp(pki_algo.value, "\x2A\x86\x48\xCE\x3D\x03\x01\x07", 8) == 0) {
  16360. cert->is_ec_pubkey = true;
  16361. MG_VERBOSE(("pk algo: ECDSA secp256r1"));
  16362. } else if (pki_algo.len == 8 &&
  16363. memcmp(pki_algo.value, "\x2A\x86\x48\xCE\x3D\x03\x01\x08", 8) ==
  16364. 0) {
  16365. cert->is_ec_pubkey = true;
  16366. MG_VERBOSE(("pk algo: ECDSA secp384r1"));
  16367. } else if (pki_algo.len == 7 &&
  16368. memcmp(pki_algo.value, "\x2A\x86\x48\xCE\x3D\x02\x01", 7) == 0) {
  16369. cert->is_ec_pubkey = true;
  16370. MG_VERBOSE(("pk algo: EC public key"));
  16371. } else if (pki_algo.len == 9 &&
  16372. memcmp(pki_algo.value, "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01",
  16373. 9) == 0) {
  16374. cert->is_ec_pubkey = false;
  16375. MG_VERBOSE(("pk algo: RSA"));
  16376. } else {
  16377. MG_ERROR(("unsupported pk algo: %M", mg_print_hex, pki_algo.len,
  16378. pki_algo.value));
  16379. return -1;
  16380. }
  16381. // Parse public key
  16382. if (cert->is_ec_pubkey) {
  16383. if (mg_der_next(&pki, &pki_curve) <= 0 || pki_curve.type != 0x06) return -1;
  16384. }
  16385. if (mg_der_next(&field, &pki_key) <= 0 || pki_key.type != 0x03) return -1;
  16386. if (cert->is_ec_pubkey) { // Skip leading 0x00 and 0x04 (=uncompressed)
  16387. if (pki_key.len < 2) return -1;
  16388. cert->pubkey = mg_str_n((char *) pki_key.value + 2, pki_key.len - 2);
  16389. } else { // Skip leading 0x00 byte
  16390. if (pki_key.len < 1) return -1;
  16391. cert->pubkey = mg_str_n((char *) pki_key.value + 1, pki_key.len - 1);
  16392. }
  16393. { // parse optional fields
  16394. int r; // unique ids
  16395. while ((r = mg_der_next(&tbs_cert, &field)) > 0 && field.type == 0xa1);
  16396. if (r > 0 && field.type == 0xa3) { // extensions
  16397. bool ca = false, certsign = true;
  16398. struct mg_der_tlv ext, e, i; // ext[e(i, ...), ...]
  16399. if (mg_der_next(&field, &ext) <= 0 || ext.type != 0x30) return -1;
  16400. while (mg_der_next(&ext, &e) > 0) {
  16401. if (mg_der_next(&e, &i) <= 0 || i.type != 0x06) return -1;
  16402. if (i.len == 3 && memcmp(i.value, (uint8_t *) "\x55\x1d\x13", 3) == 0) {
  16403. struct mg_der_tlv s, v; // basicConstraints
  16404. MG_VERBOSE(("basicConstraints"));
  16405. if (mg_der_next(&e, &i) <= 0 || i.type != 0x01 || i.len != 1 || *i.value != 0xff) return -1;
  16406. if (mg_der_next(&e, &i) <= 0 || i.type != 0x04) return -1;
  16407. if (mg_der_next(&i, &s) <= 0 || s.type != 0x30) return -1;
  16408. if (s.len == 0) break;
  16409. if (mg_der_next(&s, &v) <= 0) return -1;
  16410. if (v.type == 0x01 && v.len == 1 && *v.value == 0xff) ca = true;
  16411. } else if (i.len == 3 && memcmp(i.value, (uint8_t *) "\x55\x1d\x0f", 3) == 0) {
  16412. struct mg_der_tlv b; // keyUsage, enforce when present
  16413. MG_VERBOSE(("keyUsage"));
  16414. if (mg_der_next(&e, &i) <= 0) return -1;
  16415. if (i.type == 0x01) { // SHOULD, defaults to false
  16416. if (i.len != 1) return -1;
  16417. if (mg_der_next(&e, &i) <= 0) return -1;
  16418. }
  16419. if (i.type != 0x04) return -1;
  16420. if (mg_der_next(&i, &b) <= 0 || b.type != 0x03) return -1;
  16421. if (!(b.value[1] & MG_BIT(2))) certsign = false;
  16422. }
  16423. }
  16424. if (ca && certsign) cert->is_ca = true;
  16425. }
  16426. }
  16427. // Parse signature
  16428. if (mg_der_next(&root, &field) <= 0 || field.type != 0x30) return -1;
  16429. if (mg_der_next(&root, &raw_sig) <= 0 || raw_sig.type != 0x03) return -1;
  16430. if (raw_sig.len < 1 || raw_sig.value[0] != 0x00) return -1;
  16431. cert->sig = mg_str_n((char *) raw_sig.value + 1, raw_sig.len - 1);
  16432. MG_VERBOSE(("sig: %M", mg_print_hex, cert->sig.len, cert->sig.buf));
  16433. return 0;
  16434. }
  16435. static int countdots(struct mg_str s) {
  16436. int count = 0;
  16437. size_t len = s.len;
  16438. char *p = s.buf;
  16439. while (len--) {
  16440. if (*(p++) == '.') ++count;
  16441. }
  16442. return count;
  16443. }
  16444. static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz,
  16445. const char *server_name,
  16446. struct mg_addr *server_ip) {
  16447. struct mg_der_tlv root, field, name;
  16448. if (mg_der_parse((uint8_t *) der, dersz, &root) < 0) {
  16449. MG_ERROR(("failed to parse certificate"));
  16450. return -1;
  16451. }
  16452. if (mg_der_find_oid(&root, (uint8_t *) "\x55\x1d\x11", 3, &field) <= 0) {
  16453. MG_ERROR(("failed to extract SAN"));
  16454. return -1;
  16455. }
  16456. if (mg_der_parse(field.value, field.len, &field) < 0) {
  16457. MG_ERROR(("SAN is not a constructed object"));
  16458. return -1;
  16459. }
  16460. while (mg_der_next(&field, &name) > 0) {
  16461. if (name.type == 0x87 && name.len == 4) { // this is an IPv4 address
  16462. MG_VERBOSE(("Found SAN, IP: %M", mg_print_ip4, name.value));
  16463. if (!server_ip->is_ip6 &&
  16464. *((uint32_t *) name.value) == server_ip->addr.ip4)
  16465. return 1; // and matches the one we're connected to
  16466. #if MG_ENABLE_IPV6
  16467. } else if (name.type == 0x87 && name.len == 16) { // is an IPv6 address
  16468. MG_VERBOSE(("Found SAN, IPv6: %M", mg_print_ip6, name.value));
  16469. if (server_ip->is_ip6 && memcmp(name.value, server_ip->addr.ip6, 16) == 0)
  16470. return 1; // and matches the one we're connected to
  16471. #endif
  16472. } else { // this is a text SAN
  16473. struct mg_str sn, tn;
  16474. MG_VERBOSE(("Found SAN, (%u): %.*s", name.type, name.len, name.value));
  16475. sn = mg_str(server_name), tn = mg_str_n((char *) name.value, name.len);
  16476. if (countdots(sn) == countdots(tn) && mg_match(sn, tn, NULL))
  16477. return 1; // and matches the host name
  16478. }
  16479. }
  16480. return -1;
  16481. }
  16482. static int mg_tls_verify_cert_signature(const struct mg_tls_cert *cert,
  16483. const struct mg_tls_cert *issuer) {
  16484. if (issuer->is_ec_pubkey) {
  16485. uint8_t sig[128];
  16486. struct mg_der_tlv seq = {0, 0, 0}, a = {0, 0, 0}, b = {0, 0, 0};
  16487. mg_der_parse((uint8_t *) cert->sig.buf, cert->sig.len, &seq);
  16488. mg_der_next(&seq, &a);
  16489. mg_der_next(&seq, &b);
  16490. if (a.len == 0 || b.len == 0) {
  16491. MG_ERROR(("cert verification error"));
  16492. return 0;
  16493. }
  16494. #if MG_UECC_SUPPORTS_secp256r1
  16495. if (issuer->pubkey.len == 64) {
  16496. const uint32_t N = 32;
  16497. if (a.len > N) a.value += (a.len - N), a.len = N; // padding
  16498. if (b.len > N) b.value += (b.len - N), b.len = N;
  16499. memset(sig, 0, N - a.len); // short encoding
  16500. memmove(sig + (N - a.len), a.value, a.len);
  16501. memset(sig + N, 0, N - b.len);
  16502. memmove(sig + N + (N - b.len), b.value, b.len);
  16503. return mg_uecc_verify((uint8_t *) issuer->pubkey.buf, cert->tbshash,
  16504. (unsigned) cert->tbshashsz, sig,
  16505. mg_uecc_secp256r1());
  16506. } else
  16507. #endif
  16508. #if MG_UECC_SUPPORTS_secp384r1
  16509. if (issuer->pubkey.len == 96) {
  16510. const uint32_t N = 48;
  16511. if (a.len > N) a.value += (a.len - N), a.len = N;
  16512. if (b.len > N) b.value += (b.len - N), b.len = N;
  16513. memmove(sig, a.value, N);
  16514. memmove(sig + N, b.value, N);
  16515. return mg_uecc_verify((uint8_t *) issuer->pubkey.buf, cert->tbshash,
  16516. (unsigned) cert->tbshashsz, sig,
  16517. mg_uecc_secp384r1());
  16518. } else
  16519. #endif
  16520. {
  16521. MG_ERROR(("unsupported public key length: %d", issuer->pubkey.len));
  16522. return 0;
  16523. }
  16524. } else {
  16525. const uint8_t *n;
  16526. size_t nlen;
  16527. uint8_t sig2[512]; // 4096 bits
  16528. struct mg_der_tlv seq, modulus, exponent;
  16529. if (mg_der_parse((uint8_t *) issuer->pubkey.buf, issuer->pubkey.len,
  16530. &seq) <= 0 ||
  16531. mg_der_next(&seq, &modulus) <= 0 || modulus.type != 2 ||
  16532. modulus.len == 0 || mg_der_next(&seq, &exponent) <= 0 ||
  16533. exponent.type != 2 || exponent.len == 0) {
  16534. return -1;
  16535. }
  16536. n = modulus.value, nlen = mg_rsa_trim_len(&n, modulus.len);
  16537. if (nlen > sizeof(sig2) || cert->tbshashsz > nlen ||
  16538. mg_rsa_mod_pow(modulus.value, modulus.len, exponent.value,
  16539. exponent.len, (uint8_t *) cert->sig.buf, cert->sig.len,
  16540. sig2, nlen) != 0) {
  16541. return 0;
  16542. }
  16543. return mg_rsa_pkcs_verify(sig2, nlen, cert->tbshash, cert->tbshashsz);
  16544. }
  16545. }
  16546. static int mg_tls_verify_cert_cn(struct mg_der_tlv *subj, const char *host) {
  16547. struct mg_der_tlv v;
  16548. int matched = 0;
  16549. if (mg_der_find_oid(subj, (uint8_t *) "\x55\x04\x03", 3, &v) > 0) {
  16550. struct mg_str hn, cn;
  16551. MG_VERBOSE(("using CN: %.*s <-> %s", v.len, v.value, host));
  16552. hn = mg_str(host), cn = mg_str_n((char *) v.value, v.len);
  16553. matched = (int) (countdots(hn) == countdots(cn) && mg_match(hn, cn, NULL));
  16554. }
  16555. return matched;
  16556. }
  16557. static int tls_bundle_find(struct tls_data *tls, struct mg_der_tlv *name,
  16558. struct mg_tls_cert *cert) {
  16559. size_t i;
  16560. struct mg_der_tlv v;
  16561. struct mg_str *p = tls->ca_bundle_der, tgt;
  16562. if (!mg_der_find_oid(name, (uint8_t *) "\x55\x04\x03", 3, &v)) return false;
  16563. tgt = mg_str_n((const char *) v.value, v.len);
  16564. for (i = 0; i < tls->ca_bundle_len; i++, p++) {
  16565. struct mg_str subj;
  16566. if (mg_tls_parse_cert_der(p->buf, p->len, cert) < 0 ||
  16567. !mg_der_find_oid(&cert->subj, (uint8_t *) "\x55\x04\x03", 3, &v)) {
  16568. MG_ERROR(("failed to parse certificate #%u in bundle", i + 1));
  16569. continue; // skip this certificate but don't halt the process
  16570. }
  16571. subj = mg_str_n((const char *) v.value, v.len);
  16572. MG_VERBOSE(("#%u: %.*s (%.*s)", i + 1, subj.len, subj.buf, tgt.len, tgt.buf));
  16573. if (mg_strcasecmp(subj, tgt) == 0) return 1;
  16574. }
  16575. return 0;
  16576. }
  16577. static int mg_tls_recv_cert(struct mg_connection *c, bool is_client) {
  16578. struct tls_data *tls = (struct tls_data *) c->tls;
  16579. unsigned char *recv_buf;
  16580. if (mg_tls_recv_record(c) < 0) {
  16581. return -1;
  16582. }
  16583. recv_buf = &c->rtls.buf[tls->recv_offset];
  16584. if (recv_buf[0] == MG_TLS_CERTIFICATE_REQUEST) {
  16585. MG_VERBOSE(("got certificate request"));
  16586. mg_tls_drop_message(c);
  16587. tls->cert_requested = 1;
  16588. return -1;
  16589. }
  16590. if (recv_buf[0] != MG_TLS_CERTIFICATE) {
  16591. mg_error(c, "expected %s certificate but got msg 0x%02x",
  16592. is_client ? "server" : "client", recv_buf[0]);
  16593. return -1;
  16594. }
  16595. if (tls->recv_len < 13) { // 8 + 3 + 2, chain len + cert len + ext len
  16596. mg_error(c, "certificate list too short");
  16597. return -1;
  16598. }
  16599. {
  16600. // Normally, there are 2-3 certs in a chain (when is_client)
  16601. struct mg_tls_cert certs[8];
  16602. int certnum = 0;
  16603. uint32_t full_cert_chain_len = MG_LOAD_BE24(recv_buf + 1);
  16604. uint32_t cert_chain_len = MG_LOAD_BE24(recv_buf + 5);
  16605. uint8_t *p = recv_buf + 8;
  16606. uint8_t *endp = recv_buf + cert_chain_len + 8;
  16607. bool found_ca = false;
  16608. struct mg_tls_cert ca;
  16609. if (cert_chain_len != full_cert_chain_len - 4 || cert_chain_len > (tls->recv_len - 8)) {
  16610. MG_ERROR(("full chain length: %d, chain length: %d, msg length: %d", full_cert_chain_len, cert_chain_len, tls->recv_len));
  16611. mg_error(c, "invalid certificate chain length");
  16612. return -1;
  16613. }
  16614. memset(certs, 0, sizeof(certs));
  16615. memset(&ca, 0, sizeof(ca));
  16616. if (tls->ca_der.len > 0) { // single cert or server
  16617. if (mg_tls_parse_cert_der(tls->ca_der.buf, tls->ca_der.len, &ca) < 0) {
  16618. mg_error(c, "failed to parse CA certificate");
  16619. return -1;
  16620. }
  16621. MG_VERBOSE(("CA serial: %M", mg_print_hex, ca.sn.len, ca.sn.buf));
  16622. }
  16623. while (p < endp) {
  16624. struct mg_tls_cert *ci = &certs[certnum++];
  16625. uint32_t certsz;
  16626. uint16_t certext;
  16627. uint8_t *cert = p + 3;
  16628. if ((endp - p) < 5) { // 3 + 2, cert len + ext len fields
  16629. mg_error(c, "truncated certificate in chain");
  16630. return -1;
  16631. }
  16632. certsz = MG_LOAD_BE24(p);
  16633. p = cert + certsz + 2; // skip cert extensions (size only, not supported)
  16634. if (p > endp) {
  16635. mg_error(c, "invalid certificate length");
  16636. return -1;
  16637. }
  16638. certext = MG_LOAD_BE16(cert + certsz);
  16639. if (certext != 0) {
  16640. mg_error(c, "certificate extensions are not supported");
  16641. return -1;
  16642. }
  16643. if (mg_tls_parse_cert_der(cert, certsz, ci) < 0) {
  16644. mg_error(c, "failed to parse certificate");
  16645. return -1;
  16646. }
  16647. if (ci == certs) {
  16648. // First certificate in the chain is peer cert, check SAN if requested,
  16649. // and store public key for further CertVerify step
  16650. if (tls->hostname[0] != '\0' &&
  16651. mg_tls_verify_cert_san(cert, certsz, tls->hostname, &c->rem) <= 0 &&
  16652. mg_tls_verify_cert_cn(&ci->subj, tls->hostname) <= 0) {
  16653. mg_error(c, "failed to verify hostname");
  16654. return -1;
  16655. }
  16656. if (ci->pubkey.len > sizeof(tls->pubkey)) {
  16657. mg_error(c, "peer public key too large");
  16658. return -1;
  16659. }
  16660. memmove(tls->pubkey, ci->pubkey.buf, ci->pubkey.len);
  16661. tls->pubkeysz = ci->pubkey.len;
  16662. } else {
  16663. if (!ci->is_ca || !mg_tls_verify_cert_signature(ci - 1, ci)) {
  16664. mg_error(c, "failed to verify certificate chain %s", ci->is_ca ? "" : "(not a true CA)");
  16665. return -1;
  16666. }
  16667. }
  16668. if (tls->ca_bundle_len > 0) { // bundle, find subject and compare keys
  16669. int r;
  16670. MG_VERBOSE(("Search current cert in bundle"));
  16671. r = tls_bundle_find(tls, &ci->subj, &ca); // find current cert ci
  16672. if (r < 0) {
  16673. mg_error(c, "failed to parse CA bundle");
  16674. return -1;
  16675. } else if (r > 0 && ca.pubkey.len == ci->pubkey.len &&
  16676. memcmp(ca.pubkey.buf, ci->pubkey.buf, ca.pubkey.len) == 0) {
  16677. found_ca = true;
  16678. MG_VERBOSE(("CA serial: %M", mg_print_hex, ca.sn.len, ca.sn.buf));
  16679. break;
  16680. } // else either r = 0 => subj not found or pubkey not matching
  16681. }
  16682. if (certnum == sizeof(certs) / sizeof(certs[0]) - 1) {
  16683. mg_error(c, "too many certificates in the chain");
  16684. return -1;
  16685. }
  16686. }
  16687. if (!found_ca && certnum > 0 && tls->ca_bundle_len > 0) { // bundle
  16688. int r;
  16689. MG_VERBOSE(("Search bundle for issuer of last cert in chain"));
  16690. r = tls_bundle_find(tls, &certs[certnum - 1].issuer, &ca);
  16691. if (r <= 0) {
  16692. mg_error(c, r < 0 ? "failed to parse CA bundle"
  16693. : "failed to find issuing CA in bundle");
  16694. return -1;
  16695. } else if (!ca.is_ca || // candidate issuer found
  16696. !mg_tls_verify_cert_signature(&certs[certnum - 1], &ca)) {
  16697. mg_error(c, "failed to verify CA");
  16698. return -1;
  16699. } // issuer verified. NOTE(): may fail if two diff CAs share a CN
  16700. MG_VERBOSE(("CA serial: %M", mg_print_hex, ca.sn.len, ca.sn.buf));
  16701. }
  16702. if (!found_ca && tls->ca_der.len > 0) { // single cert or server
  16703. if (certnum < 1 ||
  16704. !mg_tls_verify_cert_signature(&certs[certnum - 1], &ca)) {
  16705. mg_error(c, "failed to verify CA");
  16706. return -1;
  16707. } else if (is_client) {
  16708. MG_VERBOSE(("no CA in chain; verification with builtin CA passed"));
  16709. }
  16710. }
  16711. }
  16712. mg_tls_drop_message(c);
  16713. mg_tls_calc_cert_verify_hash(c, tls->sighash, !is_client);
  16714. return 0;
  16715. }
  16716. static int mg_tls_recv_cert_verify(struct mg_connection *c) {
  16717. struct tls_data *tls = (struct tls_data *) c->tls;
  16718. unsigned char *recv_buf;
  16719. if (mg_tls_recv_record(c) < 0) {
  16720. return -1;
  16721. }
  16722. recv_buf = &c->rtls.buf[tls->recv_offset];
  16723. if (recv_buf[0] != MG_TLS_CERTIFICATE_VERIFY) {
  16724. mg_error(c, "expected %s certificate verify but got msg 0x%02x",
  16725. c->is_client ? "server" : "client", recv_buf[0]);
  16726. return -1;
  16727. }
  16728. if (tls->recv_len < 8) {
  16729. mg_error(c, "server certificate verify is too short: %d bytes",
  16730. tls->recv_len);
  16731. return -1;
  16732. }
  16733. // Ignore CertificateVerify if strict checks are not required
  16734. if (tls->skip_verification) {
  16735. mg_tls_drop_message(c);
  16736. return 0;
  16737. }
  16738. {
  16739. uint16_t sigalg = MG_LOAD_BE16(recv_buf + 4);
  16740. uint16_t siglen = MG_LOAD_BE16(recv_buf + 6);
  16741. uint8_t *sigbuf = recv_buf + 8;
  16742. if (siglen > tls->recv_len - 8) {
  16743. mg_error(c, "invalid certverify signature length: %d, expected %d",
  16744. siglen, tls->recv_len - 8);
  16745. return -1;
  16746. }
  16747. MG_VERBOSE(
  16748. ("certificate verification, algo=%04x, siglen=%d", sigalg, siglen));
  16749. if (sigalg == 0x0804) { // rsa_pss_rsae_sha256
  16750. uint8_t sig2[512]; // 2048 or 4096 bits
  16751. const uint8_t *n;
  16752. size_t nlen;
  16753. struct mg_der_tlv seq, modulus, exponent;
  16754. if (mg_der_parse(tls->pubkey, tls->pubkeysz, &seq) <= 0 ||
  16755. mg_der_next(&seq, &modulus) <= 0 || modulus.type != 2 ||
  16756. modulus.len == 0 || mg_der_next(&seq, &exponent) <= 0 ||
  16757. exponent.type != 2 || exponent.len == 0) {
  16758. mg_error(c, "invalid public key");
  16759. return -1;
  16760. }
  16761. n = modulus.value, nlen = mg_rsa_trim_len(&n, modulus.len);
  16762. if (nlen > sizeof(sig2) ||
  16763. mg_rsa_mod_pow(modulus.value, modulus.len, exponent.value,
  16764. exponent.len, sigbuf, siglen, sig2, nlen) != 0 ||
  16765. !mg_rsa_verify(sig2, nlen, tls->sighash)) {
  16766. mg_error(c, "failed to verify RSA certificate (certverify)");
  16767. return -1;
  16768. }
  16769. MG_VERBOSE(("certificate verification successful (RSA)"));
  16770. } else if (sigalg == 0x0403) { // ecdsa_secp256r1_sha256
  16771. // Extract certificate signature and verify it using pubkey and sighash
  16772. uint8_t sig[64];
  16773. struct mg_der_tlv seq, r, s;
  16774. memset(sig, 0, 64);
  16775. if (mg_der_to_tlv(sigbuf, siglen, &seq) < 0) {
  16776. mg_error(c, "verification message is not an ASN.1 DER sequence");
  16777. return -1;
  16778. }
  16779. if (mg_der_to_tlv(seq.value, seq.len, &r) < 0) {
  16780. mg_error(c, "missing first part of the signature");
  16781. return -1;
  16782. }
  16783. if (mg_der_to_tlv(r.value + r.len, seq.len - r.len, &s) < 0) {
  16784. mg_error(c, "missing second part of the signature");
  16785. return -1;
  16786. }
  16787. // Integers may be padded with zeroes
  16788. if (r.len > 32) r.value = r.value + (r.len - 32), r.len = 32;
  16789. if (s.len > 32) s.value = s.value + (s.len - 32), s.len = 32;
  16790. // r or s may be shorter than 32 bytes, "right-justify" (network order)
  16791. memmove(sig + (32 - r.len), r.value, r.len);
  16792. memmove(sig + 32 + (32 - s.len), s.value, s.len);
  16793. if (mg_uecc_verify(tls->pubkey, tls->sighash, sizeof(tls->sighash), sig,
  16794. mg_uecc_secp256r1()) != 1) {
  16795. mg_error(c, "failed to verify EC certificate (certverify)");
  16796. return -1;
  16797. }
  16798. MG_VERBOSE(("certificate verification successful (EC)"));
  16799. } else {
  16800. // From
  16801. // https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml:
  16802. // 0805 = rsa_pss_rsae_sha384
  16803. // 0806 = rsa_pss_rsae_sha512
  16804. // 0807 = ed25519
  16805. // 0808 = ed448
  16806. // 0809 = rsa_pss_pss_sha256
  16807. // 080A = rsa_pss_pss_sha384
  16808. // 080B = rsa_pss_pss_sha512
  16809. MG_ERROR(("unsupported certverify signature scheme: %x of %d bytes",
  16810. sigalg, siglen));
  16811. return -1;
  16812. }
  16813. }
  16814. mg_tls_drop_message(c);
  16815. return 0;
  16816. }
  16817. static int mg_tls_client_recv_finish(struct mg_connection *c) {
  16818. struct tls_data *tls = (struct tls_data *) c->tls;
  16819. unsigned char *recv_buf;
  16820. if (mg_tls_recv_record(c) < 0) {
  16821. return -1;
  16822. }
  16823. recv_buf = &c->rtls.buf[tls->recv_offset];
  16824. if (recv_buf[0] != MG_TLS_FINISHED) {
  16825. mg_error(c, "expected server finished but got msg 0x%02x", recv_buf[0]);
  16826. return -1;
  16827. }
  16828. mg_tls_drop_message(c);
  16829. return 0;
  16830. }
  16831. static bool mg_tls_client_send_finish(struct mg_connection *c) {
  16832. struct tls_data *tls = (struct tls_data *) c->tls;
  16833. mg_sha256_ctx sha256;
  16834. uint8_t hash[32];
  16835. uint8_t finish[36] = {0x14, 0, 0, 32};
  16836. memmove(&sha256, &tls->sha256, sizeof(mg_sha256_ctx));
  16837. mg_sha256_final(hash, &sha256);
  16838. mg_hmac_sha256(finish + 4, tls->enc.client_finished_key, 32, hash, 32);
  16839. return mg_tls_encrypt(c, finish, sizeof(finish), MG_TLS_HANDSHAKE);
  16840. }
  16841. static bool mg_tls_client_handshake(struct mg_connection *c) {
  16842. struct tls_data *tls = (struct tls_data *) c->tls;
  16843. switch (tls->state) {
  16844. case MG_TLS_STATE_CLIENT_START:
  16845. if (!mg_tls_client_send_hello(c)) return false;
  16846. tls->state = MG_TLS_STATE_CLIENT_WAIT_SH;
  16847. // Fallthrough
  16848. case MG_TLS_STATE_CLIENT_WAIT_SH:
  16849. if (mg_tls_client_recv_hello(c) < 0) break;
  16850. tls->state = MG_TLS_STATE_CLIENT_WAIT_EE;
  16851. // Fallthrough
  16852. case MG_TLS_STATE_CLIENT_WAIT_EE:
  16853. if (mg_tls_client_recv_ext(c) < 0) break;
  16854. tls->state = MG_TLS_STATE_CLIENT_WAIT_CERT;
  16855. // Fallthrough
  16856. case MG_TLS_STATE_CLIENT_WAIT_CERT:
  16857. if (mg_tls_recv_cert(c, true) < 0) break;
  16858. tls->state = MG_TLS_STATE_CLIENT_WAIT_CV;
  16859. // Fallthrough
  16860. case MG_TLS_STATE_CLIENT_WAIT_CV:
  16861. if (mg_tls_recv_cert_verify(c) < 0) break;
  16862. tls->state = MG_TLS_STATE_CLIENT_WAIT_FINISH;
  16863. // Fallthrough
  16864. case MG_TLS_STATE_CLIENT_WAIT_FINISH:
  16865. if (mg_tls_client_recv_finish(c) < 0) break;
  16866. if (tls->cert_requested && tls->cert_der.len > 0) { // two-way auth
  16867. // generate application keys at this point, keep using handshake keys
  16868. struct tls_enc hs_keys = tls->enc;
  16869. mg_tls_generate_application_keys(c);
  16870. tls->app_keys = tls->enc;
  16871. tls->enc = hs_keys;
  16872. if (!mg_tls_send_cert(c, true) || !mg_tls_send_cert_verify(c, true) ||
  16873. !mg_tls_client_send_finish(c))
  16874. return false;
  16875. tls->enc = tls->app_keys;
  16876. } else {
  16877. if (!mg_tls_client_send_finish(c)) return false;
  16878. mg_tls_generate_application_keys(c);
  16879. }
  16880. tls->state = MG_TLS_STATE_CLIENT_CONNECTED;
  16881. c->is_tls_hs = 0;
  16882. mg_call(c, MG_EV_TLS_HS, NULL);
  16883. break;
  16884. default:
  16885. mg_error(c, "unexpected client state: %d", tls->state);
  16886. break;
  16887. }
  16888. return true;
  16889. }
  16890. static bool mg_tls_server_handshake(struct mg_connection *c) {
  16891. struct tls_data *tls = (struct tls_data *) c->tls;
  16892. switch (tls->state) {
  16893. case MG_TLS_STATE_SERVER_START:
  16894. if (mg_tls_server_recv_hello(c) < 0) break;
  16895. if (!mg_tls_server_send_hello(c)) return false;
  16896. mg_tls_generate_handshake_keys(c);
  16897. if (!mg_tls_server_send_ext(c)) return false;
  16898. if (tls->is_twoway && !mg_tls_server_send_cert_request(c)) return false;
  16899. if (!mg_tls_send_cert(c, false) || !mg_tls_send_cert_verify(c, false) ||
  16900. !mg_tls_server_send_finish(c))
  16901. return false;
  16902. if (tls->is_twoway) {
  16903. // generate application keys at this point, keep using handshake keys
  16904. struct tls_enc hs_keys = tls->enc;
  16905. mg_tls_generate_application_keys(c);
  16906. tls->app_keys = tls->enc;
  16907. tls->enc = hs_keys;
  16908. tls->state = MG_TLS_STATE_SERVER_WAIT_CERT;
  16909. break;
  16910. }
  16911. tls->state = MG_TLS_STATE_SERVER_NEGOTIATED;
  16912. // fallthrough
  16913. case MG_TLS_STATE_SERVER_NEGOTIATED:
  16914. if (mg_tls_server_recv_finish(c) < 0) break;
  16915. if (tls->is_twoway) { // use previously generated keys
  16916. tls->enc = tls->app_keys;
  16917. } else { // generate keys now
  16918. mg_tls_generate_application_keys(c);
  16919. }
  16920. tls->state = MG_TLS_STATE_SERVER_CONNECTED;
  16921. c->is_tls_hs = 0;
  16922. break;
  16923. case MG_TLS_STATE_SERVER_WAIT_CERT:
  16924. if (mg_tls_recv_cert(c, false) < 0) break;
  16925. tls->state = MG_TLS_STATE_SERVER_WAIT_CV;
  16926. // Fallthrough
  16927. case MG_TLS_STATE_SERVER_WAIT_CV:
  16928. if (mg_tls_recv_cert_verify(c) < 0) break;
  16929. tls->state = MG_TLS_STATE_SERVER_NEGOTIATED;
  16930. break;
  16931. default:
  16932. mg_error(c, "unexpected server state: %d", tls->state);
  16933. break;
  16934. }
  16935. return true;
  16936. }
  16937. void mg_tls_handshake(struct mg_connection *c) {
  16938. struct tls_data *tls = (struct tls_data *) c->tls;
  16939. long n;
  16940. bool res;
  16941. if (c->is_closing) return; // we don't clear rx buf, so ignore what's left
  16942. if (tls->is_sntp_pending) return;
  16943. if (c->is_client) {
  16944. // will clear is_hs when sending last chunk
  16945. res = mg_tls_client_handshake(c);
  16946. } else {
  16947. res = mg_tls_server_handshake(c);
  16948. }
  16949. if (!res) {
  16950. mg_error(c, "TLS OOM");
  16951. return;
  16952. }
  16953. while (tls->send.len > 0 &&
  16954. (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
  16955. mg_iobuf_del(&tls->send, 0, (size_t) n);
  16956. } // if last chunk fails to be sent, it will be sent with first app data,
  16957. // otherwise, it needs to be flushed
  16958. }
  16959. static int mg_rsa_parse_der_int(const uint8_t **p, const uint8_t *end,
  16960. struct mg_str *out) {
  16961. const uint8_t *start = *p, *value_start, *value_end;
  16962. uint8_t i;
  16963. uint32_t len;
  16964. if (end - start < 2) {
  16965. MG_VERBOSE(("DER INT: not enough bytes (%d < 2)", (int) (end - start)));
  16966. return -1;
  16967. }
  16968. if (start[0] != 0x02) {
  16969. MG_VERBOSE(("DER INT: expected 0x02, got 0x%02x", start[0]));
  16970. return -1;
  16971. }
  16972. len = start[1];
  16973. *p = start + 2;
  16974. if (len > 0x7F) {
  16975. // Long form length
  16976. uint8_t len_bytes = len & 0x7F;
  16977. MG_VERBOSE(("DER INT: long form, %d length bytes", len_bytes));
  16978. if (len_bytes == 0 || len_bytes > 4 || (size_t) (end - *p) < len_bytes) {
  16979. MG_VERBOSE(("DER INT: not enough bytes for length"));
  16980. return -1;
  16981. }
  16982. len = 0;
  16983. for (i = 0; i < len_bytes; i++) {
  16984. len = (len << 8) | (*p)[i];
  16985. }
  16986. *p += len_bytes;
  16987. }
  16988. MG_VERBOSE(("DER INT: length=%u, remaining=%d", len, (int) (end - *p)));
  16989. if ((size_t) (end - *p) < len) {
  16990. MG_VERBOSE(("DER INT: length exceeds remaining bytes"));
  16991. return -1;
  16992. }
  16993. // The encoded length tells us how many bytes to consume from the stream
  16994. value_start = *p;
  16995. value_end = *p + len;
  16996. // Skip leading zero byte if present (for positive numbers)
  16997. // This doesn't change how many bytes we consume, just what we expose
  16998. if (len > 0 && (*p)[0] == 0x00) {
  16999. (*p)++;
  17000. len--;
  17001. }
  17002. out->buf = (char *) *p;
  17003. out->len = len;
  17004. // Advance pointer by the ORIGINAL encoded length, not the adjusted length
  17005. *p = value_end;
  17006. MG_VERBOSE(("DER INT: parsed %u bytes (skipped zero=%d)", len,
  17007. (size_t) (value_end - value_start) != (size_t) len ? 1 : 0));
  17008. return 0;
  17009. }
  17010. // RFC 5915 ECPrivateKey ::= SEQUENCE {
  17011. // version INTEGER { ecPrivkeyVer1(1) },
  17012. // privateKey OCTET STRING,
  17013. // parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
  17014. // publicKey [1] BIT STRING OPTIONAL
  17015. // }
  17016. static int mg_parse_ec_private_key(const uint8_t *der, size_t dersz,
  17017. uint8_t *ec_key) {
  17018. struct mg_der_tlv root, version, private_key_octets;
  17019. if (mg_der_parse((uint8_t *) der, dersz, &root) < 0 || root.type != 0x30) {
  17020. MG_ERROR(("EC private key: invalid SEQUENCE"));
  17021. return -1;
  17022. }
  17023. if (mg_der_next(&root, &version) <= 0 || version.type != 0x02) {
  17024. MG_ERROR(("EC private key: invalid version"));
  17025. return -1;
  17026. }
  17027. if (mg_der_next(&root, &private_key_octets) <= 0 ||
  17028. private_key_octets.type != 0x04) {
  17029. MG_ERROR(("EC private key: invalid privateKey OCTET STRING"));
  17030. return -1;
  17031. }
  17032. if (private_key_octets.len != 32) {
  17033. MG_ERROR(
  17034. ("EC private key: expected 32 bytes, got %u", private_key_octets.len));
  17035. return -1;
  17036. }
  17037. memcpy(ec_key, private_key_octets.value, 32);
  17038. return 0;
  17039. }
  17040. // Parse RSA private key from DER format
  17041. // RSAPrivateKey ::= SEQUENCE {
  17042. // version INTEGER (0),
  17043. // modulus INTEGER, -- n
  17044. // publicExponent INTEGER, -- e
  17045. // privateExponent INTEGER, -- d
  17046. // prime1 INTEGER, -- p
  17047. // prime2 INTEGER, -- q
  17048. // exponent1 INTEGER, -- dP = d mod (p-1)
  17049. // exponent2 INTEGER, -- dQ = d mod (q-1)
  17050. // coefficient INTEGER, -- qInv = (inverse of q) mod p
  17051. // }
  17052. static int mg_rsa_parse_key(const uint8_t *der, size_t dersz,
  17053. struct mg_rsa_key *key) {
  17054. const uint8_t *p = der;
  17055. const uint8_t *end = der + dersz;
  17056. uint32_t seq_len;
  17057. struct mg_str version;
  17058. memset(key, 0, sizeof(*key));
  17059. // Parse outer SEQUENCE
  17060. if (end - p < 2) {
  17061. MG_ERROR(("RSA key too short for SEQUENCE header"));
  17062. return -1;
  17063. }
  17064. if (p[0] != 0x30) {
  17065. MG_ERROR(("RSA key: expected SEQUENCE (0x30), got 0x%02x", p[0]));
  17066. return -1;
  17067. }
  17068. seq_len = p[1];
  17069. p += 2;
  17070. if (seq_len > 0x7F) {
  17071. // Long form length
  17072. uint8_t i, len_bytes = seq_len & 0x7F;
  17073. MG_VERBOSE(("Long form length: %d bytes", len_bytes));
  17074. if (len_bytes == 0 || len_bytes > 4 || (size_t) (end - p) < len_bytes) {
  17075. MG_ERROR(("Not enough bytes for long form length"));
  17076. return -1;
  17077. }
  17078. seq_len = 0;
  17079. for (i = 0; i < len_bytes; i++) {
  17080. seq_len = (seq_len << 8) | p[i];
  17081. }
  17082. p += len_bytes;
  17083. }
  17084. MG_VERBOSE(
  17085. ("SEQUENCE length: %u, total DER size: %u", seq_len, (unsigned) dersz));
  17086. if ((size_t) (end - p) < seq_len) {
  17087. MG_ERROR(("SEQUENCE length exceeds buffer"));
  17088. return -1;
  17089. }
  17090. end = p + seq_len; // Adjust end to sequence boundary
  17091. // Parse version (should be 0)
  17092. MG_VERBOSE(("Before version: offset=%d, bytes: %02x %02x %02x %02x",
  17093. (int) (p - der), p < end ? p[0] : 0xFF,
  17094. p + 1 < end ? p[1] : 0xFF, p + 2 < end ? p[2] : 0xFF,
  17095. p + 3 < end ? p[3] : 0xFF));
  17096. if (mg_rsa_parse_der_int(&p, end, &version) < 0) {
  17097. MG_ERROR(("Failed to parse version"));
  17098. return -1;
  17099. }
  17100. MG_DEBUG(("Version: %d byte(s), value=%d, offset now=%d", (int) version.len,
  17101. version.len > 0 ? (int) (unsigned char) version.buf[0] : -1,
  17102. (int) (p - der)));
  17103. // Parse the 8 components: n, e, d, p, q, dP, dQ, qInv
  17104. MG_VERBOSE(("Before n: offset=%d, bytes: %02x %02x %02x %02x %02x %02x",
  17105. (int) (p - der), p < end ? p[0] : 0xFF,
  17106. p + 1 < end ? p[1] : 0xFF, p + 2 < end ? p[2] : 0xFF,
  17107. p + 3 < end ? p[3] : 0xFF, p + 4 < end ? p[4] : 0xFF,
  17108. p + 5 < end ? p[5] : 0xFF));
  17109. if (mg_rsa_parse_der_int(&p, end, &key->n) < 0) {
  17110. MG_ERROR(("Failed to parse n (modulus)"));
  17111. return -1;
  17112. }
  17113. MG_VERBOSE(("Parsed n: %d bytes, offset now=%d, consumed=%d bytes total",
  17114. (int) key->n.len, (int) (p - der), (int) (p - der)));
  17115. MG_VERBOSE((" First 8 bytes of n: %02x %02x %02x %02x %02x %02x %02x %02x",
  17116. key->n.len > 0 ? (unsigned char) key->n.buf[0] : 0xFF,
  17117. key->n.len > 1 ? (unsigned char) key->n.buf[1] : 0xFF,
  17118. key->n.len > 2 ? (unsigned char) key->n.buf[2] : 0xFF,
  17119. key->n.len > 3 ? (unsigned char) key->n.buf[3] : 0xFF,
  17120. key->n.len > 4 ? (unsigned char) key->n.buf[4] : 0xFF,
  17121. key->n.len > 5 ? (unsigned char) key->n.buf[5] : 0xFF,
  17122. key->n.len > 6 ? (unsigned char) key->n.buf[6] : 0xFF,
  17123. key->n.len > 7 ? (unsigned char) key->n.buf[7] : 0xFF));
  17124. MG_VERBOSE((" Next bytes after n: %02x %02x %02x %02x %02x %02x",
  17125. p < end ? p[0] : 0xFF, p + 1 < end ? p[1] : 0xFF,
  17126. p + 2 < end ? p[2] : 0xFF, p + 3 < end ? p[3] : 0xFF,
  17127. p + 4 < end ? p[4] : 0xFF, p + 5 < end ? p[5] : 0xFF));
  17128. if (mg_rsa_parse_der_int(&p, end, &key->e) < 0) {
  17129. MG_ERROR(("Failed to parse e (public exponent), bytes remaining: %d",
  17130. (int) (end - p)));
  17131. if (end - p >= 4) {
  17132. MG_ERROR((" Next 4 bytes: %02x %02x %02x %02x", p[0], p[1], p[2], p[3]));
  17133. }
  17134. return -1;
  17135. }
  17136. if (mg_rsa_parse_der_int(&p, end, &key->d) < 0) {
  17137. MG_ERROR(("Failed to parse d (private exponent)"));
  17138. return -1;
  17139. }
  17140. if (mg_rsa_parse_der_int(&p, end, &key->p) < 0) {
  17141. MG_ERROR(("Failed to parse p (prime1)"));
  17142. return -1;
  17143. }
  17144. if (mg_rsa_parse_der_int(&p, end, &key->q) < 0) {
  17145. MG_ERROR(("Failed to parse q (prime2)"));
  17146. return -1;
  17147. }
  17148. if (mg_rsa_parse_der_int(&p, end, &key->dP) < 0) {
  17149. MG_ERROR(("Failed to parse dP (exponent1)"));
  17150. return -1;
  17151. }
  17152. if (mg_rsa_parse_der_int(&p, end, &key->dQ) < 0) {
  17153. MG_ERROR(("Failed to parse dQ (exponent2)"));
  17154. return -1;
  17155. }
  17156. if (mg_rsa_parse_der_int(&p, end, &key->qInv) < 0) {
  17157. MG_ERROR(("Failed to parse qInv (coefficient)"));
  17158. return -1;
  17159. }
  17160. MG_VERBOSE(("Successfully parsed RSA key"));
  17161. return 0;
  17162. }
  17163. // PKCS#8 PrivateKeyInfo ::= SEQUENCE {
  17164. // version INTEGER,
  17165. // privateKeyAlgorithm AlgorithmIdentifier,
  17166. // privateKey OCTET STRING,
  17167. // attributes [0] Attributes OPTIONAL
  17168. // }
  17169. // AlgorithmIdentifier ::= SEQUENCE {
  17170. // algorithm OBJECT IDENTIFIER,
  17171. // parameters ANY OPTIONAL
  17172. // }
  17173. static int mg_parse_pkcs8_key(const uint8_t *der, size_t dersz,
  17174. struct mg_rsa_key *rsa, uint8_t *ec_key) {
  17175. struct mg_der_tlv root, version, alg_id, private_key_octets;
  17176. struct mg_der_tlv alg_oid, alg_params;
  17177. if (mg_der_parse((uint8_t *) der, dersz, &root) < 0 || root.type != 0x30) {
  17178. MG_ERROR(("PKCS#8: invalid PrivateKeyInfo SEQUENCE"));
  17179. return -1;
  17180. }
  17181. if (mg_der_next(&root, &version) <= 0 || version.type != 0x02) {
  17182. MG_ERROR(("PKCS#8: invalid version"));
  17183. return -1;
  17184. }
  17185. if (mg_der_next(&root, &alg_id) <= 0 || alg_id.type != 0x30) {
  17186. MG_ERROR(("PKCS#8: invalid AlgorithmIdentifier SEQUENCE"));
  17187. return -1;
  17188. }
  17189. if (mg_der_next(&alg_id, &alg_oid) <= 0 || alg_oid.type != 0x06) {
  17190. MG_ERROR(("PKCS#8: invalid algorithm OID"));
  17191. return -1;
  17192. }
  17193. if (mg_der_next(&root, &private_key_octets) <= 0 ||
  17194. private_key_octets.type != 0x04) {
  17195. MG_ERROR(("PKCS#8: invalid privateKey OCTET STRING"));
  17196. return -1;
  17197. }
  17198. if (alg_oid.len == sizeof(mg_rsa_oid) &&
  17199. memcmp(alg_oid.value, mg_rsa_oid, sizeof(mg_rsa_oid)) == 0) {
  17200. struct mg_rsa_key rsa_key;
  17201. if (rsa == NULL) return -1;
  17202. if (mg_rsa_parse_key(private_key_octets.value, private_key_octets.len,
  17203. &rsa_key) < 0) {
  17204. MG_ERROR(("PKCS#8: failed to parse inner RSA key"));
  17205. return -1;
  17206. }
  17207. *rsa = rsa_key;
  17208. return 0;
  17209. } else if (alg_oid.len == sizeof(mg_ec_public_key_oid) &&
  17210. memcmp(alg_oid.value, mg_ec_public_key_oid,
  17211. sizeof(mg_ec_public_key_oid)) == 0) {
  17212. if (ec_key == NULL) return -1;
  17213. if (mg_der_next(&alg_id, &alg_params) <= 0 || alg_params.type != 0x06) {
  17214. MG_ERROR(("PKCS#8: invalid EC parameters OID"));
  17215. return -1;
  17216. }
  17217. if (alg_params.len != sizeof(mg_secp256r1_oid) ||
  17218. memcmp(alg_params.value, mg_secp256r1_oid, sizeof(mg_secp256r1_oid)) !=
  17219. 0) {
  17220. MG_ERROR(("PKCS#8: unsupported EC curve (only secp256r1 supported)"));
  17221. return -1;
  17222. }
  17223. return mg_parse_ec_private_key(private_key_octets.value,
  17224. private_key_octets.len, ec_key);
  17225. } else {
  17226. MG_ERROR(("PKCS#8: unsupported algorithm"));
  17227. return -1;
  17228. }
  17229. }
  17230. static int mg_parse_pem(const struct mg_str pem, const struct mg_str label,
  17231. struct mg_str *der) {
  17232. size_t n = 0, m = 0;
  17233. char *s;
  17234. const char *c;
  17235. struct mg_str caps[6]; // number of wildcards + 1
  17236. if (!mg_match(pem, mg_str("#-----BEGIN #-----#-----END #-----#"), caps)) {
  17237. *der = mg_strdup(pem);
  17238. return 0;
  17239. }
  17240. if (mg_strcmp(caps[1], label) != 0 || mg_strcmp(caps[3], label) != 0) {
  17241. return -1; // bad label
  17242. }
  17243. if ((s = (char *) mg_calloc(1, caps[2].len)) == NULL) {
  17244. return -1;
  17245. }
  17246. for (c = caps[2].buf; c < caps[2].buf + caps[2].len; c++) {
  17247. if (*c == ' ' || *c == '\n' || *c == '\r' || *c == '\t') {
  17248. continue;
  17249. }
  17250. s[n++] = *c;
  17251. }
  17252. m = mg_base64_decode(s, n, s, n);
  17253. if (m == 0) {
  17254. mg_free(s);
  17255. return -1;
  17256. }
  17257. der->buf = s;
  17258. der->len = m;
  17259. return 0;
  17260. }
  17261. static int mg_parse_pem_certs(const struct mg_str pem, struct mg_str **ders) {
  17262. int count = 0;
  17263. struct mg_str *certs = NULL;
  17264. const char *p = pem.buf;
  17265. const char *end = pem.buf + pem.len;
  17266. const char *begin_marker = "-----BEGIN CERTIFICATE-----";
  17267. const char *end_marker = "-----END CERTIFICATE-----";
  17268. size_t begin_len = strlen(begin_marker);
  17269. size_t end_len = strlen(end_marker);
  17270. while (p < end) {
  17271. const char *s, *begin = NULL, *finish = NULL;
  17272. struct mg_str cert_pem, cert_der, *new_certs;
  17273. int i;
  17274. for (s = p; s <= end - (int) begin_len; s++) {
  17275. if (memcmp(s, begin_marker, begin_len) == 0) {
  17276. begin = s;
  17277. break;
  17278. }
  17279. }
  17280. if (begin == NULL) break;
  17281. for (s = begin + begin_len; s <= end - (int) end_len; s++) {
  17282. if (memcmp(s, end_marker, end_len) == 0) {
  17283. finish = s + end_len;
  17284. break;
  17285. }
  17286. }
  17287. if (finish == NULL) {
  17288. for (i = 0; i < count; i++) mg_free((void *) certs[i].buf);
  17289. mg_free(certs);
  17290. return -1;
  17291. }
  17292. cert_pem = mg_str_n(begin, (size_t) (finish - begin));
  17293. if (mg_parse_pem(cert_pem, mg_str_s("CERTIFICATE"), &cert_der) < 0) {
  17294. for (i = 0; i < count; i++) mg_free((void *) certs[i].buf);
  17295. mg_free(certs);
  17296. return -1;
  17297. }
  17298. new_certs =
  17299. (struct mg_str *) mg_calloc((size_t) count + 1, sizeof(*new_certs));
  17300. if (new_certs == NULL) {
  17301. mg_free((void *) cert_der.buf);
  17302. for (i = 0; i < count; i++) mg_free((void *) certs[i].buf);
  17303. mg_free(certs);
  17304. return -1;
  17305. }
  17306. if (count > 0) {
  17307. memmove(new_certs, certs, (size_t) count * sizeof(struct mg_str));
  17308. mg_free(certs);
  17309. }
  17310. certs = new_certs;
  17311. certs[count++] = cert_der;
  17312. p = finish;
  17313. }
  17314. *ders = certs;
  17315. return count;
  17316. }
  17317. size_t mg_uecc_parse_private_key(struct mg_str key, uint8_t *buf, size_t len) {
  17318. struct mg_str der = mg_str_n(NULL, 0);
  17319. size_t n = 0;
  17320. if (buf == NULL || len < 32) return 0;
  17321. // current mg_parse_ec_private_key() only handles 32-byte keys
  17322. if (mg_parse_pem(key, mg_str_s("EC PRIVATE KEY"), &der) == 0) {
  17323. if (mg_parse_ec_private_key((uint8_t *) der.buf, der.len, buf) == 0) n = 32;
  17324. } else if (mg_parse_pem(key, mg_str_s("PRIVATE KEY"), &der) == 0) {
  17325. if (mg_parse_pkcs8_key((uint8_t *) der.buf, der.len, NULL, buf) == 0) n = 32;
  17326. }
  17327. mg_free((void *) der.buf);
  17328. return n;
  17329. }
  17330. static void sync_time_cancel(struct mg_connection *c) {
  17331. c->fn = NULL;
  17332. c->is_closing = 1;
  17333. }
  17334. static void sync_time_cb(struct mg_connection *c, int ev, void *ev_data) {
  17335. if (ev == MG_EV_SNTP_TIME || (ev == MG_EV_CLOSE)) {
  17336. struct mg_connection *tlsc = (struct mg_connection *) c->fn_data;
  17337. struct tls_data *tls = (struct tls_data *) tlsc->tls;
  17338. sync_time_cancel(c); // c = tls->timec
  17339. tls->timec = NULL;
  17340. tls->is_sntp_pending = false;
  17341. if (ev == MG_EV_SNTP_TIME) mg_tls_handshake(tlsc);
  17342. if (ev == MG_EV_CLOSE) mg_error(tlsc, "time sync failed");
  17343. }
  17344. (void) ev_data;
  17345. }
  17346. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
  17347. struct mg_str key;
  17348. struct tls_data *tls =
  17349. (struct tls_data *) mg_calloc(1, sizeof(struct tls_data));
  17350. if (tls == NULL) {
  17351. mg_error(c, "tls oom");
  17352. return;
  17353. }
  17354. tls->state =
  17355. c->is_client ? MG_TLS_STATE_CLIENT_START : MG_TLS_STATE_SERVER_START;
  17356. tls->skip_verification = opts->skip_verification;
  17357. // tls->send.align = MG_IO_SIZE;
  17358. c->tls = tls;
  17359. c->is_tls = c->is_tls_hs = 1;
  17360. mg_sha256_init(&tls->sha256);
  17361. // save hostname (client extension)
  17362. if (opts->name.len > 0) {
  17363. if (opts->name.len >= sizeof(tls->hostname) - 1) {
  17364. mg_error(c, "hostname too long");
  17365. return;
  17366. }
  17367. strncpy((char *) tls->hostname, opts->name.buf, sizeof(tls->hostname) - 1);
  17368. tls->hostname[opts->name.len] = 0;
  17369. }
  17370. // server CA certificate; parse PEM [bundle] or DER
  17371. if (opts->ca.len > 0) {
  17372. struct mg_str *all_certs = NULL;
  17373. int cert_count = mg_parse_pem_certs(opts->ca, &all_certs);
  17374. if (cert_count > 1 && c->is_client) { // use bundle for clients only
  17375. tls->ca_bundle_len = (size_t) cert_count;
  17376. tls->ca_bundle_der = all_certs;
  17377. MG_VERBOSE(("%d-cert bundle", cert_count));
  17378. } else if (cert_count > 0) {
  17379. tls->ca_der.buf = all_certs[0].buf;
  17380. tls->ca_der.len = all_certs[0].len;
  17381. mg_free(all_certs);
  17382. } else { // parse again for a possible DER (or a truncated begin string)
  17383. if (mg_parse_pem(opts->ca, mg_str_s("CERTIFICATE"), &tls->ca_der) < 0) {
  17384. MG_ERROR(("Failed to load CA certificate"));
  17385. goto xit;
  17386. }
  17387. } // ca_bundle_len != 0 && ca_der.len = 0 => bundle
  17388. if (!c->is_client) tls->is_twoway = true; // server + CA: two-way auth
  17389. }
  17390. if (opts->cert.buf == NULL) {
  17391. MG_VERBOSE(("No certificate provided"));
  17392. goto xit;
  17393. }
  17394. // parse PEM or DER certificate
  17395. {
  17396. struct mg_str *all_certs = NULL;
  17397. int cert_count = mg_parse_pem_certs(opts->cert, &all_certs);
  17398. if (cert_count > 0) {
  17399. tls->cert_der.buf = all_certs[0].buf;
  17400. tls->cert_der.len = all_certs[0].len;
  17401. if (cert_count > 1) {
  17402. tls->chain_len = (size_t) cert_count;
  17403. tls->chain_der = all_certs;
  17404. } else {
  17405. mg_free(all_certs);
  17406. }
  17407. } else { // parse again for a possible DER (or a truncated begin string)
  17408. if (mg_parse_pem(opts->cert, mg_str_s("CERTIFICATE"), &tls->cert_der) <
  17409. 0) {
  17410. MG_ERROR(("Failed to load certificate"));
  17411. return;
  17412. }
  17413. }
  17414. }
  17415. // parse PEM or DER EC key
  17416. if (opts->key.buf == NULL) {
  17417. mg_error(c, "Certificate provided without a private key");
  17418. return;
  17419. }
  17420. if (mg_parse_pem(opts->key, mg_str_s("EC PRIVATE KEY"), &key) == 0) {
  17421. // expect ASN.1 SEQUENCE=[INTEGER=1, BITSTRING of 32 bytes, ...]
  17422. // 30 nn 02 01 01 04 20 [key] ...
  17423. if (key.len < (2 + 5 + 32) || key.buf[0] != 0x30 ||
  17424. (key.buf[1] & 0x80) != 0 ||
  17425. memcmp(key.buf + 2, "\x02\x01\x01\x04\x20", 5) != 0) {
  17426. mg_error(c, "EC private key: invalid ASN.1");
  17427. } else {
  17428. memmove(tls->ec_key, key.buf + 7, 32);
  17429. }
  17430. mg_free((void *) key.buf);
  17431. } else if (mg_parse_pem(opts->key, mg_str_s("RSA PRIVATE KEY"), &key) == 0) {
  17432. struct mg_rsa_key rsa_key;
  17433. // RSA private key found, store it for later use
  17434. tls->rsa_key_der = key;
  17435. // parse and validate the key structure
  17436. // we keep the DER buffer, rsa_key just points into it
  17437. if (mg_rsa_parse_key((const uint8_t *) key.buf, key.len, &rsa_key) < 0) {
  17438. MG_ERROR(("Failed to parse RSA private key structure"));
  17439. mg_free((void *) key.buf);
  17440. tls->rsa_key_der = mg_str_n(NULL, 0);
  17441. mg_error(c, "Invalid RSA private key format");
  17442. return;
  17443. }
  17444. MG_VERBOSE(("RSA key components:"));
  17445. MG_VERBOSE((" n (modulus): %d bytes", (int) rsa_key.n.len));
  17446. MG_VERBOSE((" e (pubexp): %d bytes", (int) rsa_key.e.len));
  17447. MG_VERBOSE((" d (privexp): %d bytes", (int) rsa_key.d.len));
  17448. MG_VERBOSE((" p (prime1): %d bytes", (int) rsa_key.p.len));
  17449. MG_VERBOSE((" q (prime2): %d bytes", (int) rsa_key.q.len));
  17450. MG_VERBOSE((" dP: %d bytes", (int) rsa_key.dP.len));
  17451. MG_VERBOSE((" dQ: %d bytes", (int) rsa_key.dQ.len));
  17452. MG_VERBOSE((" qInv: %d bytes", (int) rsa_key.qInv.len));
  17453. // Copy parsed RSA key components to tls->rsa for signing operations
  17454. tls->rsa = rsa_key;
  17455. } else if (mg_parse_pem(opts->key, mg_str_s("PRIVATE KEY"), &key) == 0) {
  17456. if (mg_parse_pkcs8_key((const uint8_t *) key.buf, key.len, &tls->rsa,
  17457. tls->ec_key) == 0) {
  17458. if (tls->rsa.n.len > 0) {
  17459. tls->rsa_key_der = key;
  17460. MG_INFO(("Parsed PKCS#8 RSA private key: %d bytes", (int) key.len));
  17461. } else {
  17462. mg_free((void *) key.buf);
  17463. MG_INFO(("Parsed PKCS#8 EC private key"));
  17464. }
  17465. } else {
  17466. mg_free((void *) key.buf);
  17467. mg_error(c, "Unsupported PKCS#8 private key format, algorithm, or curve");
  17468. return;
  17469. }
  17470. } else {
  17471. mg_error(
  17472. c, "Expected EC PRIVATE KEY, RSA PRIVATE KEY, or PRIVATE KEY (PKCS#8)");
  17473. return;
  17474. }
  17475. xit:
  17476. if (mg_boot_timestamp_ms == 0 && !tls->skip_verification &&
  17477. (tls->ca_bundle_len > 0 || tls->ca_der.len > 0)) {
  17478. struct mg_connection *timec;
  17479. timec = mg_sntp_connect(c->mgr, NULL, sync_time_cb, c);
  17480. if (timec == NULL) {
  17481. mg_error(c, "time sync failed");
  17482. return;
  17483. }
  17484. tls->is_sntp_pending = true;
  17485. tls->timec = timec;
  17486. }
  17487. }
  17488. void mg_tls_free(struct mg_connection *c) {
  17489. struct tls_data *tls = (struct tls_data *) c->tls;
  17490. size_t i;
  17491. if (tls != NULL) {
  17492. if (tls->timec != NULL) {
  17493. sync_time_cancel(tls->timec);
  17494. tls->timec = NULL;
  17495. }
  17496. mg_iobuf_free(&tls->send);
  17497. if (tls->chain_der != NULL) {
  17498. for (i = 0; i < tls->chain_len; i++) {
  17499. mg_free((void *) tls->chain_der[i].buf);
  17500. }
  17501. mg_free(tls->chain_der);
  17502. } else {
  17503. mg_free((void *) tls->cert_der.buf);
  17504. }
  17505. if (tls->ca_bundle_der != NULL) {
  17506. for (i = 0; i < tls->ca_bundle_len; i++) {
  17507. mg_free((void *) tls->ca_bundle_der[i].buf);
  17508. }
  17509. mg_free(tls->ca_bundle_der);
  17510. }
  17511. mg_free((void *) tls->ca_der.buf);
  17512. mg_free((void *) tls->rsa_key_der.buf);
  17513. }
  17514. mg_free(c->tls);
  17515. c->tls = NULL;
  17516. }
  17517. long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
  17518. struct tls_data *tls = (struct tls_data *) c->tls;
  17519. long n = MG_IO_WAIT;
  17520. bool was_throttled = c->is_tls_throttled; // see #3074
  17521. if (!was_throttled) { // encrypt new data
  17522. if (len > MG_IO_SIZE) len = MG_IO_SIZE;
  17523. if (len > 16384) len = 16384;
  17524. if (!mg_tls_encrypt(c, (const uint8_t *) buf, len, MG_TLS_APP_DATA))
  17525. return 0; // returning 0 means an OOM condition (iobuf couldn't resize),
  17526. // yet this is so far recoverable, let the caller decide
  17527. } // else, resend outstanding encrypted data in tls->send
  17528. while (tls->send.len > 0 &&
  17529. (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
  17530. mg_iobuf_del(&tls->send, 0, (size_t) n);
  17531. } // if last chunk fails to be sent, it needs to be flushed
  17532. c->is_tls_throttled = (tls->send.len > 0 && n == MG_IO_WAIT);
  17533. MG_VERBOSE(("%lu %ld %ld %ld %c %c", c->id, (long) len, (long) tls->send.len,
  17534. n, was_throttled ? 'T' : 't', c->is_tls_throttled ? 'T' : 't'));
  17535. if (n == MG_IO_ERR) return MG_IO_ERR;
  17536. if (was_throttled) return MG_IO_WAIT; // sent throttled data instead
  17537. return (long) len; // return len even when throttled, already encripted that
  17538. }
  17539. long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
  17540. int r = 0;
  17541. struct tls_data *tls = (struct tls_data *) c->tls;
  17542. unsigned char *recv_buf;
  17543. size_t minlen;
  17544. for (;;) {
  17545. r = mg_tls_recv_record(c);
  17546. if (r < 0) return r;
  17547. if (tls->content_type == MG_TLS_APP_DATA) break;
  17548. tls->recv_len = 0;
  17549. mg_tls_drop_record(c);
  17550. }
  17551. if (buf == NULL || len == 0) return 0L;
  17552. recv_buf = &c->rtls.buf[tls->recv_offset];
  17553. minlen = len < tls->recv_len ? len : tls->recv_len;
  17554. memmove(buf, recv_buf, minlen);
  17555. tls->recv_offset += minlen;
  17556. tls->recv_len -= minlen;
  17557. if (tls->recv_len == 0) mg_tls_drop_record(c);
  17558. return (long) minlen;
  17559. }
  17560. size_t mg_tls_pending(struct mg_connection *c) {
  17561. struct tls_data *tls = (struct tls_data *) c->tls;
  17562. return tls != NULL ? tls->recv_len : 0;
  17563. }
  17564. void mg_tls_flush(struct mg_connection *c) {
  17565. struct tls_data *tls = (struct tls_data *) c->tls;
  17566. long n;
  17567. while (tls->send.len > 0 &&
  17568. (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
  17569. mg_iobuf_del(&tls->send, 0, (size_t) n);
  17570. }
  17571. }
  17572. void mg_tls_ctx_init(struct mg_mgr *mgr) {
  17573. (void) mgr;
  17574. }
  17575. void mg_tls_ctx_free(struct mg_mgr *mgr) {
  17576. (void) mgr;
  17577. }
  17578. #endif
  17579. #ifdef MG_ENABLE_LINES
  17580. #line 1 "src/tls_chacha20.c"
  17581. #endif
  17582. // portable8439 v1.0.1
  17583. // Source: https://github.com/DavyLandman/portable8439
  17584. // Licensed under CC0-1.0
  17585. // Contains poly1305-donna e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781 (Public
  17586. // Domain)
  17587. #if MG_TLS == MG_TLS_BUILTIN && MG_ENABLE_CHACHA20
  17588. // ******* BEGIN: chacha-portable/chacha-portable.h ********
  17589. #if !defined(__cplusplus) && !defined(_MSC_VER) && \
  17590. (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
  17591. #error "C99 or newer required"
  17592. #endif
  17593. #define CHACHA20_KEY_SIZE (32)
  17594. #define CHACHA20_NONCE_SIZE (12)
  17595. #if defined(_MSC_VER) || defined(__cplusplus)
  17596. // add restrict support
  17597. #if ((defined(_MSC_VER) && _MSC_VER >= 1900) && !defined(__cplusplus)) || \
  17598. defined(__clang__) || defined(__GNUC__)
  17599. #define restrict __restrict
  17600. #else
  17601. #define restrict
  17602. #endif
  17603. #endif
  17604. // xor data with a ChaCha20 keystream as per RFC8439
  17605. static PORTABLE_8439_DECL void chacha20_xor_stream(
  17606. uint8_t *restrict dest, const uint8_t *restrict source, size_t length,
  17607. const uint8_t key[CHACHA20_KEY_SIZE],
  17608. const uint8_t nonce[CHACHA20_NONCE_SIZE], uint32_t counter);
  17609. static PORTABLE_8439_DECL void rfc8439_keygen(
  17610. uint8_t poly_key[32], const uint8_t key[CHACHA20_KEY_SIZE],
  17611. const uint8_t nonce[CHACHA20_NONCE_SIZE]);
  17612. // ******* END: chacha-portable/chacha-portable.h ********
  17613. // ******* BEGIN: poly1305-donna/poly1305-donna.h ********
  17614. #include <stddef.h>
  17615. typedef struct poly1305_context {
  17616. size_t aligner;
  17617. unsigned char opaque[136];
  17618. } poly1305_context;
  17619. static PORTABLE_8439_DECL void poly1305_init(poly1305_context *ctx,
  17620. const unsigned char key[32]);
  17621. static PORTABLE_8439_DECL void poly1305_update(poly1305_context *ctx,
  17622. const unsigned char *m,
  17623. size_t bytes);
  17624. static PORTABLE_8439_DECL void poly1305_finish(poly1305_context *ctx,
  17625. unsigned char mac[16]);
  17626. // ******* END: poly1305-donna/poly1305-donna.h ********
  17627. // ******* BEGIN: chacha-portable.c ********
  17628. #include <assert.h>
  17629. #include <string.h>
  17630. // this is a fresh implementation of chacha20, based on the description in
  17631. // rfc8349 it's such a nice compact algorithm that it is easy to do. In
  17632. // relationship to other c implementation this implementation:
  17633. // - pure c99
  17634. // - big & little endian support
  17635. // - safe for architectures that don't support unaligned reads
  17636. //
  17637. // Next to this, we try to be fast as possible without resorting inline
  17638. // assembly.
  17639. // based on https://sourceforge.net/p/predef/wiki/Endianness/
  17640. #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
  17641. __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  17642. #define __HAVE_LITTLE_ENDIAN 1
  17643. #elif defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \
  17644. defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \
  17645. defined(__MIPSEL) || defined(__MIPSEL__) || defined(__XTENSA_EL__) || \
  17646. defined(__AVR__)
  17647. #define __HAVE_LITTLE_ENDIAN 1
  17648. #endif
  17649. // DO NOT test for LITTLE_ENDIAN, as it is defined as 1234 when including
  17650. // sys/types.h in GCC
  17651. #ifndef TEST_SLOW_PATH
  17652. #if defined(__HAVE_LITTLE_ENDIAN)
  17653. #define FAST_PATH
  17654. #endif
  17655. #endif
  17656. #define CHACHA20_STATE_WORDS (16)
  17657. #define CHACHA20_BLOCK_SIZE (CHACHA20_STATE_WORDS * sizeof(uint32_t))
  17658. #ifdef FAST_PATH
  17659. #define store_32_le(target, source) memcpy(&(target), source, sizeof(uint32_t))
  17660. #else
  17661. #define store_32_le(target, source) \
  17662. target = (uint32_t) (source)[0] | ((uint32_t) (source)[1]) << 8 | \
  17663. ((uint32_t) (source)[2]) << 16 | ((uint32_t) (source)[3]) << 24
  17664. #endif
  17665. static void initialize_state(uint32_t state[CHACHA20_STATE_WORDS],
  17666. const uint8_t key[CHACHA20_KEY_SIZE],
  17667. const uint8_t nonce[CHACHA20_NONCE_SIZE],
  17668. uint32_t counter) {
  17669. #if 0
  17670. #ifdef static_assert
  17671. static_assert(sizeof(uint32_t) == 4,
  17672. "We don't support systems that do not conform to standard of "
  17673. "uint32_t being exact 32bit wide");
  17674. #endif
  17675. #endif
  17676. state[0] = 0x61707865;
  17677. state[1] = 0x3320646e;
  17678. state[2] = 0x79622d32;
  17679. state[3] = 0x6b206574;
  17680. store_32_le(state[4], key);
  17681. store_32_le(state[5], key + 4);
  17682. store_32_le(state[6], key + 8);
  17683. store_32_le(state[7], key + 12);
  17684. store_32_le(state[8], key + 16);
  17685. store_32_le(state[9], key + 20);
  17686. store_32_le(state[10], key + 24);
  17687. store_32_le(state[11], key + 28);
  17688. state[12] = counter;
  17689. store_32_le(state[13], nonce);
  17690. store_32_le(state[14], nonce + 4);
  17691. store_32_le(state[15], nonce + 8);
  17692. }
  17693. #define increment_counter(state) (state)[12]++
  17694. // source: http://blog.regehr.org/archives/1063
  17695. #define rotl32a(x, n) ((x) << (n)) | ((x) >> (32 - (n)))
  17696. #define Qround(a, b, c, d) \
  17697. a += b; \
  17698. d ^= a; \
  17699. d = rotl32a(d, 16); \
  17700. c += d; \
  17701. b ^= c; \
  17702. b = rotl32a(b, 12); \
  17703. a += b; \
  17704. d ^= a; \
  17705. d = rotl32a(d, 8); \
  17706. c += d; \
  17707. b ^= c; \
  17708. b = rotl32a(b, 7);
  17709. #define TIMES16(x) \
  17710. x(0) x(1) x(2) x(3) x(4) x(5) x(6) x(7) x(8) x(9) x(10) x(11) x(12) x(13) \
  17711. x(14) x(15)
  17712. static void core_block(const uint32_t *restrict start,
  17713. uint32_t *restrict output) {
  17714. int i;
  17715. // instead of working on the output array,
  17716. // we let the compiler allocate 16 local variables on the stack
  17717. #define __LV(i) uint32_t __t##i = start[i];
  17718. TIMES16(__LV)
  17719. #define __Q(a, b, c, d) Qround(__t##a, __t##b, __t##c, __t##d)
  17720. for (i = 0; i < 10; i++) {
  17721. __Q(0, 4, 8, 12);
  17722. __Q(1, 5, 9, 13);
  17723. __Q(2, 6, 10, 14);
  17724. __Q(3, 7, 11, 15);
  17725. __Q(0, 5, 10, 15);
  17726. __Q(1, 6, 11, 12);
  17727. __Q(2, 7, 8, 13);
  17728. __Q(3, 4, 9, 14);
  17729. }
  17730. #define __FIN(i) output[i] = start[i] + __t##i;
  17731. TIMES16(__FIN)
  17732. }
  17733. #define U8(x) ((uint8_t) ((x) & 0xFF))
  17734. #ifdef FAST_PATH
  17735. #define xor32_le(dst, src, pad) \
  17736. uint32_t __value; \
  17737. memcpy(&__value, src, sizeof(uint32_t)); \
  17738. __value ^= *(pad); \
  17739. memcpy(dst, &__value, sizeof(uint32_t));
  17740. #else
  17741. #define xor32_le(dst, src, pad) \
  17742. (dst)[0] = (src)[0] ^ U8(*(pad)); \
  17743. (dst)[1] = (src)[1] ^ U8(*(pad) >> 8); \
  17744. (dst)[2] = (src)[2] ^ U8(*(pad) >> 16); \
  17745. (dst)[3] = (src)[3] ^ U8(*(pad) >> 24);
  17746. #endif
  17747. #define index8_32(a, ix) ((a) + ((ix) * sizeof(uint32_t)))
  17748. #define xor32_blocks(dest, source, pad, words) \
  17749. for (i = 0; i < words; i++) { \
  17750. xor32_le(index8_32(dest, i), index8_32(source, i), (pad) + i) \
  17751. }
  17752. static void xor_block(uint8_t *restrict dest, const uint8_t *restrict source,
  17753. const uint32_t *restrict pad, unsigned int chunk_size) {
  17754. unsigned int i, full_blocks = chunk_size / (unsigned int) sizeof(uint32_t);
  17755. // have to be carefull, we are going back from uint32 to uint8, so endianness
  17756. // matters again
  17757. xor32_blocks(dest, source, pad, full_blocks)
  17758. dest += full_blocks * sizeof(uint32_t);
  17759. source += full_blocks * sizeof(uint32_t);
  17760. pad += full_blocks;
  17761. switch (chunk_size % sizeof(uint32_t)) {
  17762. case 1:
  17763. dest[0] = source[0] ^ U8(*pad);
  17764. break;
  17765. case 2:
  17766. dest[0] = source[0] ^ U8(*pad);
  17767. dest[1] = source[1] ^ U8(*pad >> 8);
  17768. break;
  17769. case 3:
  17770. dest[0] = source[0] ^ U8(*pad);
  17771. dest[1] = source[1] ^ U8(*pad >> 8);
  17772. dest[2] = source[2] ^ U8(*pad >> 16);
  17773. break;
  17774. }
  17775. }
  17776. static void chacha20_xor_stream(uint8_t *restrict dest,
  17777. const uint8_t *restrict source, size_t length,
  17778. const uint8_t key[CHACHA20_KEY_SIZE],
  17779. const uint8_t nonce[CHACHA20_NONCE_SIZE],
  17780. uint32_t counter) {
  17781. uint32_t state[CHACHA20_STATE_WORDS];
  17782. uint32_t pad[CHACHA20_STATE_WORDS];
  17783. size_t i, b, last_block, full_blocks = length / CHACHA20_BLOCK_SIZE;
  17784. initialize_state(state, key, nonce, counter);
  17785. for (b = 0; b < full_blocks; b++) {
  17786. core_block(state, pad);
  17787. increment_counter(state);
  17788. xor32_blocks(dest, source, pad, CHACHA20_STATE_WORDS) dest +=
  17789. CHACHA20_BLOCK_SIZE;
  17790. source += CHACHA20_BLOCK_SIZE;
  17791. }
  17792. last_block = length % CHACHA20_BLOCK_SIZE;
  17793. if (last_block > 0) {
  17794. core_block(state, pad);
  17795. xor_block(dest, source, pad, (unsigned int) last_block);
  17796. }
  17797. }
  17798. #ifdef FAST_PATH
  17799. #define serialize(poly_key, result) memcpy(poly_key, result, 32)
  17800. #else
  17801. #define store32_le(target, source) \
  17802. (target)[0] = U8(*(source)); \
  17803. (target)[1] = U8(*(source) >> 8); \
  17804. (target)[2] = U8(*(source) >> 16); \
  17805. (target)[3] = U8(*(source) >> 24);
  17806. #define serialize(poly_key, result) \
  17807. for (i = 0; i < 32 / sizeof(uint32_t); i++) { \
  17808. store32_le(index8_32(poly_key, i), result + i); \
  17809. }
  17810. #endif
  17811. static void rfc8439_keygen(uint8_t poly_key[32],
  17812. const uint8_t key[CHACHA20_KEY_SIZE],
  17813. const uint8_t nonce[CHACHA20_NONCE_SIZE]) {
  17814. uint32_t state[CHACHA20_STATE_WORDS];
  17815. uint32_t result[CHACHA20_STATE_WORDS];
  17816. size_t i;
  17817. initialize_state(state, key, nonce, 0);
  17818. core_block(state, result);
  17819. serialize(poly_key, result);
  17820. (void) i;
  17821. }
  17822. // ******* END: chacha-portable.c ********
  17823. // ******* BEGIN: poly1305-donna.c ********
  17824. /* auto detect between 32bit / 64bit */
  17825. #if /* uint128 available on 64bit system*/ \
  17826. (defined(__SIZEOF_INT128__) && \
  17827. defined(__LP64__)) /* MSVC 64bit compiler */ \
  17828. || (defined(_MSC_VER) && defined(_M_X64)) /* gcc >= 4.4 64bit */ \
  17829. || (defined(__GNUC__) && defined(__LP64__) && \
  17830. ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4))))
  17831. #define __GUESS64
  17832. #else
  17833. #define __GUESS32
  17834. #endif
  17835. #if defined(POLY1305_8BIT)
  17836. /*
  17837. poly1305 implementation using 8 bit * 8 bit = 16 bit multiplication and
  17838. 32 bit addition
  17839. based on the public domain reference version in supercop by djb
  17840. static */
  17841. #if defined(_MSC_VER) && _MSC_VER < 1700
  17842. #define POLY1305_NOINLINE
  17843. #elif defined(_MSC_VER)
  17844. #define POLY1305_NOINLINE __declspec(noinline)
  17845. #elif defined(__GNUC__)
  17846. #define POLY1305_NOINLINE __attribute__((noinline))
  17847. #else
  17848. #define POLY1305_NOINLINE
  17849. #endif
  17850. #define poly1305_block_size 16
  17851. /* 17 + sizeof(size_t) + 51*sizeof(unsigned char) */
  17852. typedef struct poly1305_state_internal_t {
  17853. unsigned char buffer[poly1305_block_size];
  17854. size_t leftover;
  17855. unsigned char h[17];
  17856. unsigned char r[17];
  17857. unsigned char pad[17];
  17858. unsigned char final;
  17859. } poly1305_state_internal_t;
  17860. static void poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
  17861. poly1305_state_internal_t *st = (poly1305_state_internal_t *) ctx;
  17862. size_t i;
  17863. st->leftover = 0;
  17864. /* h = 0 */
  17865. for (i = 0; i < 17; i++) st->h[i] = 0;
  17866. /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
  17867. st->r[0] = key[0] & 0xff;
  17868. st->r[1] = key[1] & 0xff;
  17869. st->r[2] = key[2] & 0xff;
  17870. st->r[3] = key[3] & 0x0f;
  17871. st->r[4] = key[4] & 0xfc;
  17872. st->r[5] = key[5] & 0xff;
  17873. st->r[6] = key[6] & 0xff;
  17874. st->r[7] = key[7] & 0x0f;
  17875. st->r[8] = key[8] & 0xfc;
  17876. st->r[9] = key[9] & 0xff;
  17877. st->r[10] = key[10] & 0xff;
  17878. st->r[11] = key[11] & 0x0f;
  17879. st->r[12] = key[12] & 0xfc;
  17880. st->r[13] = key[13] & 0xff;
  17881. st->r[14] = key[14] & 0xff;
  17882. st->r[15] = key[15] & 0x0f;
  17883. st->r[16] = 0;
  17884. /* save pad for later */
  17885. for (i = 0; i < 16; i++) st->pad[i] = key[i + 16];
  17886. st->pad[16] = 0;
  17887. st->final = 0;
  17888. }
  17889. static void poly1305_add(unsigned char h[17], const unsigned char c[17]) {
  17890. unsigned short u;
  17891. unsigned int i;
  17892. for (u = 0, i = 0; i < 17; i++) {
  17893. u += (unsigned short) h[i] + (unsigned short) c[i];
  17894. h[i] = (unsigned char) u & 0xff;
  17895. u >>= 8;
  17896. }
  17897. }
  17898. static void poly1305_squeeze(unsigned char h[17], unsigned long hr[17]) {
  17899. unsigned long u;
  17900. unsigned int i;
  17901. u = 0;
  17902. for (i = 0; i < 16; i++) {
  17903. u += hr[i];
  17904. h[i] = (unsigned char) u & 0xff;
  17905. u >>= 8;
  17906. }
  17907. u += hr[16];
  17908. h[16] = (unsigned char) u & 0x03;
  17909. u >>= 2;
  17910. u += (u << 2); /* u *= 5; */
  17911. for (i = 0; i < 16; i++) {
  17912. u += h[i];
  17913. h[i] = (unsigned char) u & 0xff;
  17914. u >>= 8;
  17915. }
  17916. h[16] += (unsigned char) u;
  17917. }
  17918. static void poly1305_freeze(unsigned char h[17]) {
  17919. const unsigned char minusp[17] = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
  17920. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  17921. 0x00, 0x00, 0x00, 0x00, 0xfc};
  17922. unsigned char horig[17], negative;
  17923. unsigned int i;
  17924. /* compute h + -p */
  17925. for (i = 0; i < 17; i++) horig[i] = h[i];
  17926. poly1305_add(h, minusp);
  17927. /* select h if h < p, or h + -p if h >= p */
  17928. negative = -(h[16] >> 7);
  17929. for (i = 0; i < 17; i++) h[i] ^= negative & (horig[i] ^ h[i]);
  17930. }
  17931. static void poly1305_blocks(poly1305_state_internal_t *st,
  17932. const unsigned char *m, size_t bytes) {
  17933. const unsigned char hibit = st->final ^ 1; /* 1 << 128 */
  17934. while (bytes >= poly1305_block_size) {
  17935. unsigned long hr[17], u;
  17936. unsigned char c[17];
  17937. unsigned int i, j;
  17938. /* h += m */
  17939. for (i = 0; i < 16; i++) c[i] = m[i];
  17940. c[16] = hibit;
  17941. poly1305_add(st->h, c);
  17942. /* h *= r */
  17943. for (i = 0; i < 17; i++) {
  17944. u = 0;
  17945. for (j = 0; j <= i; j++) {
  17946. u += (unsigned short) st->h[j] * st->r[i - j];
  17947. }
  17948. for (j = i + 1; j < 17; j++) {
  17949. unsigned long v = (unsigned short) st->h[j] * st->r[i + 17 - j];
  17950. v = ((v << 8) + (v << 6)); /* v *= (5 << 6); */
  17951. u += v;
  17952. }
  17953. hr[i] = u;
  17954. }
  17955. /* (partial) h %= p */
  17956. poly1305_squeeze(st->h, hr);
  17957. m += poly1305_block_size;
  17958. bytes -= poly1305_block_size;
  17959. }
  17960. }
  17961. static POLY1305_NOINLINE void poly1305_finish(poly1305_context *ctx,
  17962. unsigned char mac[16]) {
  17963. poly1305_state_internal_t *st = (poly1305_state_internal_t *) ctx;
  17964. size_t i;
  17965. /* process the remaining block */
  17966. if (st->leftover) {
  17967. size_t i = st->leftover;
  17968. st->buffer[i++] = 1;
  17969. for (; i < poly1305_block_size; i++) st->buffer[i] = 0;
  17970. st->final = 1;
  17971. poly1305_blocks(st, st->buffer, poly1305_block_size);
  17972. }
  17973. /* fully reduce h */
  17974. poly1305_freeze(st->h);
  17975. /* h = (h + pad) % (1 << 128) */
  17976. poly1305_add(st->h, st->pad);
  17977. for (i = 0; i < 16; i++) mac[i] = st->h[i];
  17978. /* zero out the state */
  17979. for (i = 0; i < 17; i++) st->h[i] = 0;
  17980. for (i = 0; i < 17; i++) st->r[i] = 0;
  17981. for (i = 0; i < 17; i++) st->pad[i] = 0;
  17982. }
  17983. #elif defined(POLY1305_16BIT)
  17984. /*
  17985. poly1305 implementation using 16 bit * 16 bit = 32 bit multiplication
  17986. and 32 bit addition static */
  17987. #if defined(_MSC_VER) && _MSC_VER < 1700
  17988. #define POLY1305_NOINLINE
  17989. #elif defined(_MSC_VER)
  17990. #define POLY1305_NOINLINE __declspec(noinline)
  17991. #elif defined(__GNUC__)
  17992. #define POLY1305_NOINLINE __attribute__((noinline))
  17993. #else
  17994. #define POLY1305_NOINLINE
  17995. #endif
  17996. #define poly1305_block_size 16
  17997. /* 17 + sizeof(size_t) + 18*sizeof(unsigned short) */
  17998. typedef struct poly1305_state_internal_t {
  17999. unsigned char buffer[poly1305_block_size];
  18000. size_t leftover;
  18001. unsigned short r[10];
  18002. unsigned short h[10];
  18003. unsigned short pad[8];
  18004. unsigned char final;
  18005. } poly1305_state_internal_t;
  18006. /* interpret two 8 bit unsigned integers as a 16 bit unsigned integer in little
  18007. * endian */
  18008. static unsigned short U8TO16(const unsigned char *p) {
  18009. return (((unsigned short) (p[0] & 0xff)) |
  18010. ((unsigned short) (p[1] & 0xff) << 8));
  18011. }
  18012. /* store a 16 bit unsigned integer as two 8 bit unsigned integers in little
  18013. * endian */
  18014. static void U16TO8(unsigned char *p, unsigned short v) {
  18015. p[0] = (v) & 0xff;
  18016. p[1] = (v >> 8) & 0xff;
  18017. }
  18018. static void poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
  18019. poly1305_state_internal_t *st = (poly1305_state_internal_t *) ctx;
  18020. unsigned short t0, t1, t2, t3, t4, t5, t6, t7;
  18021. size_t i;
  18022. /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
  18023. t0 = U8TO16(&key[0]);
  18024. st->r[0] = (t0) & 0x1fff;
  18025. t1 = U8TO16(&key[2]);
  18026. st->r[1] = ((t0 >> 13) | (t1 << 3)) & 0x1fff;
  18027. t2 = U8TO16(&key[4]);
  18028. st->r[2] = ((t1 >> 10) | (t2 << 6)) & 0x1f03;
  18029. t3 = U8TO16(&key[6]);
  18030. st->r[3] = ((t2 >> 7) | (t3 << 9)) & 0x1fff;
  18031. t4 = U8TO16(&key[8]);
  18032. st->r[4] = ((t3 >> 4) | (t4 << 12)) & 0x00ff;
  18033. st->r[5] = ((t4 >> 1)) & 0x1ffe;
  18034. t5 = U8TO16(&key[10]);
  18035. st->r[6] = ((t4 >> 14) | (t5 << 2)) & 0x1fff;
  18036. t6 = U8TO16(&key[12]);
  18037. st->r[7] = ((t5 >> 11) | (t6 << 5)) & 0x1f81;
  18038. t7 = U8TO16(&key[14]);
  18039. st->r[8] = ((t6 >> 8) | (t7 << 8)) & 0x1fff;
  18040. st->r[9] = ((t7 >> 5)) & 0x007f;
  18041. /* h = 0 */
  18042. for (i = 0; i < 10; i++) st->h[i] = 0;
  18043. /* save pad for later */
  18044. for (i = 0; i < 8; i++) st->pad[i] = U8TO16(&key[16 + (2 * i)]);
  18045. st->leftover = 0;
  18046. st->final = 0;
  18047. }
  18048. static void poly1305_blocks(poly1305_state_internal_t *st,
  18049. const unsigned char *m, size_t bytes) {
  18050. const unsigned short hibit = (st->final) ? 0 : (1 << 11); /* 1 << 128 */
  18051. unsigned short t0, t1, t2, t3, t4, t5, t6, t7;
  18052. unsigned long d[10];
  18053. unsigned long c;
  18054. while (bytes >= poly1305_block_size) {
  18055. size_t i, j;
  18056. /* h += m[i] */
  18057. t0 = U8TO16(&m[0]);
  18058. st->h[0] += (t0) & 0x1fff;
  18059. t1 = U8TO16(&m[2]);
  18060. st->h[1] += ((t0 >> 13) | (t1 << 3)) & 0x1fff;
  18061. t2 = U8TO16(&m[4]);
  18062. st->h[2] += ((t1 >> 10) | (t2 << 6)) & 0x1fff;
  18063. t3 = U8TO16(&m[6]);
  18064. st->h[3] += ((t2 >> 7) | (t3 << 9)) & 0x1fff;
  18065. t4 = U8TO16(&m[8]);
  18066. st->h[4] += ((t3 >> 4) | (t4 << 12)) & 0x1fff;
  18067. st->h[5] += ((t4 >> 1)) & 0x1fff;
  18068. t5 = U8TO16(&m[10]);
  18069. st->h[6] += ((t4 >> 14) | (t5 << 2)) & 0x1fff;
  18070. t6 = U8TO16(&m[12]);
  18071. st->h[7] += ((t5 >> 11) | (t6 << 5)) & 0x1fff;
  18072. t7 = U8TO16(&m[14]);
  18073. st->h[8] += ((t6 >> 8) | (t7 << 8)) & 0x1fff;
  18074. st->h[9] += ((t7 >> 5)) | hibit;
  18075. /* h *= r, (partial) h %= p */
  18076. for (i = 0, c = 0; i < 10; i++) {
  18077. d[i] = c;
  18078. for (j = 0; j < 10; j++) {
  18079. d[i] += (unsigned long) st->h[j] *
  18080. ((j <= i) ? st->r[i - j] : (5 * st->r[i + 10 - j]));
  18081. /* Sum(h[i] * r[i] * 5) will overflow slightly above 6 products with an
  18082. * unclamped r, so carry at 5 */
  18083. if (j == 4) {
  18084. c = (d[i] >> 13);
  18085. d[i] &= 0x1fff;
  18086. }
  18087. }
  18088. c += (d[i] >> 13);
  18089. d[i] &= 0x1fff;
  18090. }
  18091. c = ((c << 2) + c); /* c *= 5 */
  18092. c += d[0];
  18093. d[0] = ((unsigned short) c & 0x1fff);
  18094. c = (c >> 13);
  18095. d[1] += c;
  18096. for (i = 0; i < 10; i++) st->h[i] = (unsigned short) d[i];
  18097. m += poly1305_block_size;
  18098. bytes -= poly1305_block_size;
  18099. }
  18100. }
  18101. static POLY1305_NOINLINE void poly1305_finish(poly1305_context *ctx,
  18102. unsigned char mac[16]) {
  18103. poly1305_state_internal_t *st = (poly1305_state_internal_t *) ctx;
  18104. unsigned short c;
  18105. unsigned short g[10];
  18106. unsigned short mask;
  18107. unsigned long f;
  18108. size_t i;
  18109. /* process the remaining block */
  18110. if (st->leftover) {
  18111. size_t i = st->leftover;
  18112. st->buffer[i++] = 1;
  18113. for (; i < poly1305_block_size; i++) st->buffer[i] = 0;
  18114. st->final = 1;
  18115. poly1305_blocks(st, st->buffer, poly1305_block_size);
  18116. }
  18117. /* fully carry h */
  18118. c = st->h[1] >> 13;
  18119. st->h[1] &= 0x1fff;
  18120. for (i = 2; i < 10; i++) {
  18121. st->h[i] += c;
  18122. c = st->h[i] >> 13;
  18123. st->h[i] &= 0x1fff;
  18124. }
  18125. st->h[0] += (c * 5);
  18126. c = st->h[0] >> 13;
  18127. st->h[0] &= 0x1fff;
  18128. st->h[1] += c;
  18129. c = st->h[1] >> 13;
  18130. st->h[1] &= 0x1fff;
  18131. st->h[2] += c;
  18132. /* compute h + -p */
  18133. g[0] = st->h[0] + 5;
  18134. c = g[0] >> 13;
  18135. g[0] &= 0x1fff;
  18136. for (i = 1; i < 10; i++) {
  18137. g[i] = st->h[i] + c;
  18138. c = g[i] >> 13;
  18139. g[i] &= 0x1fff;
  18140. }
  18141. /* select h if h < p, or h + -p if h >= p */
  18142. mask = (c ^ 1) - 1;
  18143. for (i = 0; i < 10; i++) g[i] &= mask;
  18144. mask = ~mask;
  18145. for (i = 0; i < 10; i++) st->h[i] = (st->h[i] & mask) | g[i];
  18146. /* h = h % (2^128) */
  18147. st->h[0] = ((st->h[0]) | (st->h[1] << 13)) & 0xffff;
  18148. st->h[1] = ((st->h[1] >> 3) | (st->h[2] << 10)) & 0xffff;
  18149. st->h[2] = ((st->h[2] >> 6) | (st->h[3] << 7)) & 0xffff;
  18150. st->h[3] = ((st->h[3] >> 9) | (st->h[4] << 4)) & 0xffff;
  18151. st->h[4] = ((st->h[4] >> 12) | (st->h[5] << 1) | (st->h[6] << 14)) & 0xffff;
  18152. st->h[5] = ((st->h[6] >> 2) | (st->h[7] << 11)) & 0xffff;
  18153. st->h[6] = ((st->h[7] >> 5) | (st->h[8] << 8)) & 0xffff;
  18154. st->h[7] = ((st->h[8] >> 8) | (st->h[9] << 5)) & 0xffff;
  18155. /* mac = (h + pad) % (2^128) */
  18156. f = (unsigned long) st->h[0] + st->pad[0];
  18157. st->h[0] = (unsigned short) f;
  18158. for (i = 1; i < 8; i++) {
  18159. f = (unsigned long) st->h[i] + st->pad[i] + (f >> 16);
  18160. st->h[i] = (unsigned short) f;
  18161. }
  18162. for (i = 0; i < 8; i++) U16TO8(mac + (i * 2), st->h[i]);
  18163. /* zero out the state */
  18164. for (i = 0; i < 10; i++) st->h[i] = 0;
  18165. for (i = 0; i < 10; i++) st->r[i] = 0;
  18166. for (i = 0; i < 8; i++) st->pad[i] = 0;
  18167. }
  18168. #elif defined(POLY1305_32BIT) || \
  18169. (!defined(POLY1305_64BIT) && defined(__GUESS32))
  18170. /*
  18171. poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication
  18172. and 64 bit addition static */
  18173. #if defined(_MSC_VER) && _MSC_VER < 1700
  18174. #define POLY1305_NOINLINE
  18175. #elif defined(_MSC_VER)
  18176. #define POLY1305_NOINLINE __declspec(noinline)
  18177. #elif defined(__GNUC__)
  18178. #define POLY1305_NOINLINE __attribute__((noinline))
  18179. #else
  18180. #define POLY1305_NOINLINE
  18181. #endif
  18182. #define poly1305_block_size 16
  18183. /* 17 + sizeof(size_t) + 14*sizeof(unsigned long) */
  18184. typedef struct poly1305_state_internal_t {
  18185. unsigned long r[5];
  18186. unsigned long h[5];
  18187. unsigned long pad[4];
  18188. size_t leftover;
  18189. unsigned char buffer[poly1305_block_size];
  18190. unsigned char final;
  18191. } poly1305_state_internal_t;
  18192. /* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little
  18193. * endian */
  18194. static unsigned long U8TO32(const unsigned char *p) {
  18195. return (((unsigned long) (p[0] & 0xff)) |
  18196. ((unsigned long) (p[1] & 0xff) << 8) |
  18197. ((unsigned long) (p[2] & 0xff) << 16) |
  18198. ((unsigned long) (p[3] & 0xff) << 24));
  18199. }
  18200. /* store a 32 bit unsigned integer as four 8 bit unsigned integers in little
  18201. * endian */
  18202. static void U32TO8(unsigned char *p, unsigned long v) {
  18203. p[0] = (unsigned char) ((v) & 0xff);
  18204. p[1] = (unsigned char) ((v >> 8) & 0xff);
  18205. p[2] = (unsigned char) ((v >> 16) & 0xff);
  18206. p[3] = (unsigned char) ((v >> 24) & 0xff);
  18207. }
  18208. static void poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
  18209. poly1305_state_internal_t *st = (poly1305_state_internal_t *) ctx;
  18210. /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
  18211. st->r[0] = (U8TO32(&key[0])) & 0x3ffffff;
  18212. st->r[1] = (U8TO32(&key[3]) >> 2) & 0x3ffff03;
  18213. st->r[2] = (U8TO32(&key[6]) >> 4) & 0x3ffc0ff;
  18214. st->r[3] = (U8TO32(&key[9]) >> 6) & 0x3f03fff;
  18215. st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff;
  18216. /* h = 0 */
  18217. st->h[0] = 0;
  18218. st->h[1] = 0;
  18219. st->h[2] = 0;
  18220. st->h[3] = 0;
  18221. st->h[4] = 0;
  18222. /* save pad for later */
  18223. st->pad[0] = U8TO32(&key[16]);
  18224. st->pad[1] = U8TO32(&key[20]);
  18225. st->pad[2] = U8TO32(&key[24]);
  18226. st->pad[3] = U8TO32(&key[28]);
  18227. st->leftover = 0;
  18228. st->final = 0;
  18229. }
  18230. static void poly1305_blocks(poly1305_state_internal_t *st,
  18231. const unsigned char *m, size_t bytes) {
  18232. const unsigned long hibit = (st->final) ? 0 : (1UL << 24); /* 1 << 128 */
  18233. unsigned long r0, r1, r2, r3, r4;
  18234. unsigned long s1, s2, s3, s4;
  18235. unsigned long h0, h1, h2, h3, h4;
  18236. uint64_t d0, d1, d2, d3, d4;
  18237. unsigned long c;
  18238. r0 = st->r[0];
  18239. r1 = st->r[1];
  18240. r2 = st->r[2];
  18241. r3 = st->r[3];
  18242. r4 = st->r[4];
  18243. s1 = r1 * 5;
  18244. s2 = r2 * 5;
  18245. s3 = r3 * 5;
  18246. s4 = r4 * 5;
  18247. h0 = st->h[0];
  18248. h1 = st->h[1];
  18249. h2 = st->h[2];
  18250. h3 = st->h[3];
  18251. h4 = st->h[4];
  18252. while (bytes >= poly1305_block_size) {
  18253. /* h += m[i] */
  18254. h0 += (U8TO32(m + 0)) & 0x3ffffff;
  18255. h1 += (U8TO32(m + 3) >> 2) & 0x3ffffff;
  18256. h2 += (U8TO32(m + 6) >> 4) & 0x3ffffff;
  18257. h3 += (U8TO32(m + 9) >> 6) & 0x3ffffff;
  18258. h4 += (U8TO32(m + 12) >> 8) | hibit;
  18259. /* h *= r */
  18260. d0 = ((uint64_t) h0 * r0) + ((uint64_t) h1 * s4) + ((uint64_t) h2 * s3) +
  18261. ((uint64_t) h3 * s2) + ((uint64_t) h4 * s1);
  18262. d1 = ((uint64_t) h0 * r1) + ((uint64_t) h1 * r0) + ((uint64_t) h2 * s4) +
  18263. ((uint64_t) h3 * s3) + ((uint64_t) h4 * s2);
  18264. d2 = ((uint64_t) h0 * r2) + ((uint64_t) h1 * r1) + ((uint64_t) h2 * r0) +
  18265. ((uint64_t) h3 * s4) + ((uint64_t) h4 * s3);
  18266. d3 = ((uint64_t) h0 * r3) + ((uint64_t) h1 * r2) + ((uint64_t) h2 * r1) +
  18267. ((uint64_t) h3 * r0) + ((uint64_t) h4 * s4);
  18268. d4 = ((uint64_t) h0 * r4) + ((uint64_t) h1 * r3) + ((uint64_t) h2 * r2) +
  18269. ((uint64_t) h3 * r1) + ((uint64_t) h4 * r0);
  18270. /* (partial) h %= p */
  18271. c = (unsigned long) (d0 >> 26);
  18272. h0 = (unsigned long) d0 & 0x3ffffff;
  18273. d1 += c;
  18274. c = (unsigned long) (d1 >> 26);
  18275. h1 = (unsigned long) d1 & 0x3ffffff;
  18276. d2 += c;
  18277. c = (unsigned long) (d2 >> 26);
  18278. h2 = (unsigned long) d2 & 0x3ffffff;
  18279. d3 += c;
  18280. c = (unsigned long) (d3 >> 26);
  18281. h3 = (unsigned long) d3 & 0x3ffffff;
  18282. d4 += c;
  18283. c = (unsigned long) (d4 >> 26);
  18284. h4 = (unsigned long) d4 & 0x3ffffff;
  18285. h0 += c * 5;
  18286. c = (h0 >> 26);
  18287. h0 = h0 & 0x3ffffff;
  18288. h1 += c;
  18289. m += poly1305_block_size;
  18290. bytes -= poly1305_block_size;
  18291. }
  18292. st->h[0] = h0;
  18293. st->h[1] = h1;
  18294. st->h[2] = h2;
  18295. st->h[3] = h3;
  18296. st->h[4] = h4;
  18297. }
  18298. static POLY1305_NOINLINE void poly1305_finish(poly1305_context *ctx,
  18299. unsigned char mac[16]) {
  18300. poly1305_state_internal_t *st = (poly1305_state_internal_t *) ctx;
  18301. unsigned long h0, h1, h2, h3, h4, c;
  18302. unsigned long g0, g1, g2, g3, g4;
  18303. uint64_t f;
  18304. unsigned long mask;
  18305. /* process the remaining block */
  18306. if (st->leftover) {
  18307. size_t i = st->leftover;
  18308. st->buffer[i++] = 1;
  18309. for (; i < poly1305_block_size; i++) st->buffer[i] = 0;
  18310. st->final = 1;
  18311. poly1305_blocks(st, st->buffer, poly1305_block_size);
  18312. }
  18313. /* fully carry h */
  18314. h0 = st->h[0];
  18315. h1 = st->h[1];
  18316. h2 = st->h[2];
  18317. h3 = st->h[3];
  18318. h4 = st->h[4];
  18319. c = h1 >> 26;
  18320. h1 = h1 & 0x3ffffff;
  18321. h2 += c;
  18322. c = h2 >> 26;
  18323. h2 = h2 & 0x3ffffff;
  18324. h3 += c;
  18325. c = h3 >> 26;
  18326. h3 = h3 & 0x3ffffff;
  18327. h4 += c;
  18328. c = h4 >> 26;
  18329. h4 = h4 & 0x3ffffff;
  18330. h0 += c * 5;
  18331. c = h0 >> 26;
  18332. h0 = h0 & 0x3ffffff;
  18333. h1 += c;
  18334. /* compute h + -p */
  18335. g0 = h0 + 5;
  18336. c = g0 >> 26;
  18337. g0 &= 0x3ffffff;
  18338. g1 = h1 + c;
  18339. c = g1 >> 26;
  18340. g1 &= 0x3ffffff;
  18341. g2 = h2 + c;
  18342. c = g2 >> 26;
  18343. g2 &= 0x3ffffff;
  18344. g3 = h3 + c;
  18345. c = g3 >> 26;
  18346. g3 &= 0x3ffffff;
  18347. g4 = h4 + c - (1UL << 26);
  18348. /* select h if h < p, or h + -p if h >= p */
  18349. mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1;
  18350. g0 &= mask;
  18351. g1 &= mask;
  18352. g2 &= mask;
  18353. g3 &= mask;
  18354. g4 &= mask;
  18355. mask = ~mask;
  18356. h0 = (h0 & mask) | g0;
  18357. h1 = (h1 & mask) | g1;
  18358. h2 = (h2 & mask) | g2;
  18359. h3 = (h3 & mask) | g3;
  18360. h4 = (h4 & mask) | g4;
  18361. /* h = h % (2^128) */
  18362. h0 = ((h0) | (h1 << 26)) & 0xffffffff;
  18363. h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
  18364. h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
  18365. h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
  18366. /* mac = (h + pad) % (2^128) */
  18367. f = (uint64_t) h0 + st->pad[0];
  18368. h0 = (unsigned long) f;
  18369. f = (uint64_t) h1 + st->pad[1] + (f >> 32);
  18370. h1 = (unsigned long) f;
  18371. f = (uint64_t) h2 + st->pad[2] + (f >> 32);
  18372. h2 = (unsigned long) f;
  18373. f = (uint64_t) h3 + st->pad[3] + (f >> 32);
  18374. h3 = (unsigned long) f;
  18375. U32TO8(mac + 0, h0);
  18376. U32TO8(mac + 4, h1);
  18377. U32TO8(mac + 8, h2);
  18378. U32TO8(mac + 12, h3);
  18379. /* zero out the state */
  18380. st->h[0] = 0;
  18381. st->h[1] = 0;
  18382. st->h[2] = 0;
  18383. st->h[3] = 0;
  18384. st->h[4] = 0;
  18385. st->r[0] = 0;
  18386. st->r[1] = 0;
  18387. st->r[2] = 0;
  18388. st->r[3] = 0;
  18389. st->r[4] = 0;
  18390. st->pad[0] = 0;
  18391. st->pad[1] = 0;
  18392. st->pad[2] = 0;
  18393. st->pad[3] = 0;
  18394. }
  18395. #else
  18396. /*
  18397. poly1305 implementation using 64 bit * 64 bit = 128 bit multiplication
  18398. and 128 bit addition static */
  18399. #if defined(_MSC_VER)
  18400. typedef struct uint128_t {
  18401. uint64_t lo;
  18402. uint64_t hi;
  18403. } uint128_t;
  18404. #define MUL128(out, x, y) out.lo = _umul128((x), (y), &out.hi)
  18405. #define ADD(out, in) \
  18406. { \
  18407. uint64_t t = out.lo; \
  18408. out.lo += in.lo; \
  18409. out.hi += (out.lo < t) + in.hi; \
  18410. }
  18411. #define ADDLO(out, in) \
  18412. { \
  18413. uint64_t t = out.lo; \
  18414. out.lo += in; \
  18415. out.hi += (out.lo < t); \
  18416. }
  18417. #define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift)))
  18418. #define LO(in) (in.lo)
  18419. #if defined(_MSC_VER) && _MSC_VER < 1700
  18420. #define POLY1305_NOINLINE
  18421. #else
  18422. #define POLY1305_NOINLINE __declspec(noinline)
  18423. #endif
  18424. #elif defined(__GNUC__)
  18425. #if defined(__SIZEOF_INT128__)
  18426. // Get rid of GCC warning "ISO C does not support '__int128' types"
  18427. #pragma GCC diagnostic push
  18428. #pragma GCC diagnostic ignored "-Wpedantic"
  18429. typedef unsigned __int128 uint128_t;
  18430. #pragma GCC diagnostic pop
  18431. #else
  18432. typedef unsigned uint128_t __attribute__((mode(TI)));
  18433. #endif
  18434. #define MUL128(out, x, y) out = ((uint128_t) x * y)
  18435. #define ADD(out, in) out += in
  18436. #define ADDLO(out, in) out += in
  18437. #define SHR(in, shift) (uint64_t) (in >> (shift))
  18438. #define LO(in) (uint64_t) (in)
  18439. #define POLY1305_NOINLINE __attribute__((noinline))
  18440. #endif
  18441. #define poly1305_block_size 16
  18442. /* 17 + sizeof(size_t) + 8*sizeof(uint64_t) */
  18443. typedef struct poly1305_state_internal_t {
  18444. uint64_t r[3];
  18445. uint64_t h[3];
  18446. uint64_t pad[2];
  18447. size_t leftover;
  18448. unsigned char buffer[poly1305_block_size];
  18449. unsigned char final;
  18450. } poly1305_state_internal_t;
  18451. /* interpret eight 8 bit unsigned integers as a 64 bit unsigned integer in
  18452. * little endian */
  18453. static uint64_t U8TO64(const unsigned char *p) {
  18454. return (((uint64_t) (p[0] & 0xff)) | ((uint64_t) (p[1] & 0xff) << 8) |
  18455. ((uint64_t) (p[2] & 0xff) << 16) | ((uint64_t) (p[3] & 0xff) << 24) |
  18456. ((uint64_t) (p[4] & 0xff) << 32) | ((uint64_t) (p[5] & 0xff) << 40) |
  18457. ((uint64_t) (p[6] & 0xff) << 48) | ((uint64_t) (p[7] & 0xff) << 56));
  18458. }
  18459. /* store a 64 bit unsigned integer as eight 8 bit unsigned integers in little
  18460. * endian */
  18461. static void U64TO8(unsigned char *p, uint64_t v) {
  18462. p[0] = (unsigned char) ((v) & 0xff);
  18463. p[1] = (unsigned char) ((v >> 8) & 0xff);
  18464. p[2] = (unsigned char) ((v >> 16) & 0xff);
  18465. p[3] = (unsigned char) ((v >> 24) & 0xff);
  18466. p[4] = (unsigned char) ((v >> 32) & 0xff);
  18467. p[5] = (unsigned char) ((v >> 40) & 0xff);
  18468. p[6] = (unsigned char) ((v >> 48) & 0xff);
  18469. p[7] = (unsigned char) ((v >> 56) & 0xff);
  18470. }
  18471. static void poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
  18472. poly1305_state_internal_t *st = (poly1305_state_internal_t *) ctx;
  18473. uint64_t t0, t1;
  18474. /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
  18475. t0 = U8TO64(&key[0]);
  18476. t1 = U8TO64(&key[8]);
  18477. st->r[0] = (t0) & 0xffc0fffffff;
  18478. st->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff;
  18479. st->r[2] = ((t1 >> 24)) & 0x00ffffffc0f;
  18480. /* h = 0 */
  18481. st->h[0] = 0;
  18482. st->h[1] = 0;
  18483. st->h[2] = 0;
  18484. /* save pad for later */
  18485. st->pad[0] = U8TO64(&key[16]);
  18486. st->pad[1] = U8TO64(&key[24]);
  18487. st->leftover = 0;
  18488. st->final = 0;
  18489. }
  18490. static void poly1305_blocks(poly1305_state_internal_t *st,
  18491. const unsigned char *m, size_t bytes) {
  18492. const uint64_t hibit = (st->final) ? 0 : ((uint64_t) 1 << 40); /* 1 << 128 */
  18493. uint64_t r0, r1, r2;
  18494. uint64_t s1, s2;
  18495. uint64_t h0, h1, h2;
  18496. uint64_t c;
  18497. uint128_t d0, d1, d2, d;
  18498. r0 = st->r[0];
  18499. r1 = st->r[1];
  18500. r2 = st->r[2];
  18501. h0 = st->h[0];
  18502. h1 = st->h[1];
  18503. h2 = st->h[2];
  18504. s1 = r1 * (5 << 2);
  18505. s2 = r2 * (5 << 2);
  18506. while (bytes >= poly1305_block_size) {
  18507. uint64_t t0, t1;
  18508. /* h += m[i] */
  18509. t0 = U8TO64(&m[0]);
  18510. t1 = U8TO64(&m[8]);
  18511. h0 += ((t0) & 0xfffffffffff);
  18512. h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff);
  18513. h2 += (((t1 >> 24)) & 0x3ffffffffff) | hibit;
  18514. /* h *= r */
  18515. MUL128(d0, h0, r0);
  18516. MUL128(d, h1, s2);
  18517. ADD(d0, d);
  18518. MUL128(d, h2, s1);
  18519. ADD(d0, d);
  18520. MUL128(d1, h0, r1);
  18521. MUL128(d, h1, r0);
  18522. ADD(d1, d);
  18523. MUL128(d, h2, s2);
  18524. ADD(d1, d);
  18525. MUL128(d2, h0, r2);
  18526. MUL128(d, h1, r1);
  18527. ADD(d2, d);
  18528. MUL128(d, h2, r0);
  18529. ADD(d2, d);
  18530. /* (partial) h %= p */
  18531. c = SHR(d0, 44);
  18532. h0 = LO(d0) & 0xfffffffffff;
  18533. ADDLO(d1, c);
  18534. c = SHR(d1, 44);
  18535. h1 = LO(d1) & 0xfffffffffff;
  18536. ADDLO(d2, c);
  18537. c = SHR(d2, 42);
  18538. h2 = LO(d2) & 0x3ffffffffff;
  18539. h0 += c * 5;
  18540. c = (h0 >> 44);
  18541. h0 = h0 & 0xfffffffffff;
  18542. h1 += c;
  18543. m += poly1305_block_size;
  18544. bytes -= poly1305_block_size;
  18545. }
  18546. st->h[0] = h0;
  18547. st->h[1] = h1;
  18548. st->h[2] = h2;
  18549. }
  18550. static POLY1305_NOINLINE void poly1305_finish(poly1305_context *ctx,
  18551. unsigned char mac[16]) {
  18552. poly1305_state_internal_t *st = (poly1305_state_internal_t *) ctx;
  18553. uint64_t h0, h1, h2, c;
  18554. uint64_t g0, g1, g2;
  18555. uint64_t t0, t1;
  18556. /* process the remaining block */
  18557. if (st->leftover) {
  18558. size_t i = st->leftover;
  18559. st->buffer[i] = 1;
  18560. for (i = i + 1; i < poly1305_block_size; i++) st->buffer[i] = 0;
  18561. st->final = 1;
  18562. poly1305_blocks(st, st->buffer, poly1305_block_size);
  18563. }
  18564. /* fully carry h */
  18565. h0 = st->h[0];
  18566. h1 = st->h[1];
  18567. h2 = st->h[2];
  18568. c = (h1 >> 44);
  18569. h1 &= 0xfffffffffff;
  18570. h2 += c;
  18571. c = (h2 >> 42);
  18572. h2 &= 0x3ffffffffff;
  18573. h0 += c * 5;
  18574. c = (h0 >> 44);
  18575. h0 &= 0xfffffffffff;
  18576. h1 += c;
  18577. c = (h1 >> 44);
  18578. h1 &= 0xfffffffffff;
  18579. h2 += c;
  18580. c = (h2 >> 42);
  18581. h2 &= 0x3ffffffffff;
  18582. h0 += c * 5;
  18583. c = (h0 >> 44);
  18584. h0 &= 0xfffffffffff;
  18585. h1 += c;
  18586. /* compute h + -p */
  18587. g0 = h0 + 5;
  18588. c = (g0 >> 44);
  18589. g0 &= 0xfffffffffff;
  18590. g1 = h1 + c;
  18591. c = (g1 >> 44);
  18592. g1 &= 0xfffffffffff;
  18593. g2 = h2 + c - ((uint64_t) 1 << 42);
  18594. /* select h if h < p, or h + -p if h >= p */
  18595. c = (g2 >> ((sizeof(uint64_t) * 8) - 1)) - 1;
  18596. g0 &= c;
  18597. g1 &= c;
  18598. g2 &= c;
  18599. c = ~c;
  18600. h0 = (h0 & c) | g0;
  18601. h1 = (h1 & c) | g1;
  18602. h2 = (h2 & c) | g2;
  18603. /* h = (h + pad) */
  18604. t0 = st->pad[0];
  18605. t1 = st->pad[1];
  18606. h0 += ((t0) & 0xfffffffffff);
  18607. c = (h0 >> 44);
  18608. h0 &= 0xfffffffffff;
  18609. h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c;
  18610. c = (h1 >> 44);
  18611. h1 &= 0xfffffffffff;
  18612. h2 += (((t1 >> 24)) & 0x3ffffffffff) + c;
  18613. h2 &= 0x3ffffffffff;
  18614. /* mac = h % (2^128) */
  18615. h0 = ((h0) | (h1 << 44));
  18616. h1 = ((h1 >> 20) | (h2 << 24));
  18617. U64TO8(&mac[0], h0);
  18618. U64TO8(&mac[8], h1);
  18619. /* zero out the state */
  18620. st->h[0] = 0;
  18621. st->h[1] = 0;
  18622. st->h[2] = 0;
  18623. st->r[0] = 0;
  18624. st->r[1] = 0;
  18625. st->r[2] = 0;
  18626. st->pad[0] = 0;
  18627. st->pad[1] = 0;
  18628. }
  18629. #endif
  18630. static void poly1305_update(poly1305_context *ctx, const unsigned char *m,
  18631. size_t bytes) {
  18632. poly1305_state_internal_t *st = (poly1305_state_internal_t *) ctx;
  18633. size_t i;
  18634. /* handle leftover */
  18635. if (st->leftover) {
  18636. size_t want = (poly1305_block_size - st->leftover);
  18637. if (want > bytes) want = bytes;
  18638. for (i = 0; i < want; i++) st->buffer[st->leftover + i] = m[i];
  18639. bytes -= want;
  18640. m += want;
  18641. st->leftover += want;
  18642. if (st->leftover < poly1305_block_size) return;
  18643. poly1305_blocks(st, st->buffer, poly1305_block_size);
  18644. st->leftover = 0;
  18645. }
  18646. /* process full blocks */
  18647. if (bytes >= poly1305_block_size) {
  18648. size_t want = (bytes & (size_t) ~(poly1305_block_size - 1));
  18649. poly1305_blocks(st, m, want);
  18650. m += want;
  18651. bytes -= want;
  18652. }
  18653. /* store leftover */
  18654. if (bytes) {
  18655. for (i = 0; i < bytes; i++) st->buffer[st->leftover + i] = m[i];
  18656. st->leftover += bytes;
  18657. }
  18658. }
  18659. // ******* END: poly1305-donna.c ********
  18660. // ******* BEGIN: portable8439.c ********
  18661. #define __CHACHA20_BLOCK_SIZE (64)
  18662. #define __POLY1305_KEY_SIZE (32)
  18663. static PORTABLE_8439_DECL uint8_t __ZEROES[16] = {0};
  18664. static PORTABLE_8439_DECL void pad_if_needed(poly1305_context *ctx,
  18665. size_t size) {
  18666. size_t padding = size % 16;
  18667. if (padding != 0) {
  18668. poly1305_update(ctx, __ZEROES, 16 - padding);
  18669. }
  18670. }
  18671. #define __u8(v) ((uint8_t) ((v) & 0xFF))
  18672. // TODO: make this depending on the unaligned/native read size possible
  18673. static PORTABLE_8439_DECL void write_64bit_int(poly1305_context *ctx,
  18674. uint64_t value) {
  18675. uint8_t result[8];
  18676. result[0] = __u8(value);
  18677. result[1] = __u8(value >> 8);
  18678. result[2] = __u8(value >> 16);
  18679. result[3] = __u8(value >> 24);
  18680. result[4] = __u8(value >> 32);
  18681. result[5] = __u8(value >> 40);
  18682. result[6] = __u8(value >> 48);
  18683. result[7] = __u8(value >> 56);
  18684. poly1305_update(ctx, result, 8);
  18685. }
  18686. static PORTABLE_8439_DECL void poly1305_calculate_mac(
  18687. uint8_t *mac, const uint8_t *cipher_text, size_t cipher_text_size,
  18688. const uint8_t key[RFC_8439_KEY_SIZE],
  18689. const uint8_t nonce[RFC_8439_NONCE_SIZE], const uint8_t *ad,
  18690. size_t ad_size) {
  18691. // init poly key (section 2.6)
  18692. uint8_t poly_key[__POLY1305_KEY_SIZE] = {0};
  18693. poly1305_context poly_ctx;
  18694. rfc8439_keygen(poly_key, key, nonce);
  18695. // start poly1305 mac
  18696. poly1305_init(&poly_ctx, poly_key);
  18697. if (ad != NULL && ad_size > 0) {
  18698. // write AD if present
  18699. poly1305_update(&poly_ctx, ad, ad_size);
  18700. pad_if_needed(&poly_ctx, ad_size);
  18701. }
  18702. // now write the cipher text
  18703. poly1305_update(&poly_ctx, cipher_text, cipher_text_size);
  18704. pad_if_needed(&poly_ctx, cipher_text_size);
  18705. // write sizes
  18706. write_64bit_int(&poly_ctx, ad_size);
  18707. write_64bit_int(&poly_ctx, cipher_text_size);
  18708. // calculate MAC
  18709. poly1305_finish(&poly_ctx, mac);
  18710. }
  18711. #define MG_PM(p) ((size_t) (p))
  18712. // pointers overlap if the smaller either ahead of the end,
  18713. // or its end is before the start of the other
  18714. //
  18715. // s_size should be smaller or equal to b_size
  18716. #define MG_OVERLAPPING(s, s_size, b, b_size) \
  18717. (MG_PM(s) < MG_PM((b) + (b_size))) && (MG_PM(b) < MG_PM((s) + (s_size)))
  18718. PORTABLE_8439_DECL size_t mg_chacha20_poly1305_encrypt(
  18719. uint8_t *restrict cipher_text, const uint8_t key[RFC_8439_KEY_SIZE],
  18720. const uint8_t nonce[RFC_8439_NONCE_SIZE], const uint8_t *restrict ad,
  18721. size_t ad_size, const uint8_t *restrict plain_text,
  18722. size_t plain_text_size) {
  18723. size_t new_size = plain_text_size + RFC_8439_TAG_SIZE;
  18724. if (MG_OVERLAPPING(plain_text, plain_text_size, cipher_text, new_size)) {
  18725. return (size_t) -1;
  18726. }
  18727. chacha20_xor_stream(cipher_text, plain_text, plain_text_size, key, nonce, 1);
  18728. poly1305_calculate_mac(cipher_text + plain_text_size, cipher_text,
  18729. plain_text_size, key, nonce, ad, ad_size);
  18730. return new_size;
  18731. }
  18732. PORTABLE_8439_DECL size_t mg_chacha20_poly1305_decrypt(
  18733. uint8_t *restrict plain_text, const uint8_t key[RFC_8439_KEY_SIZE],
  18734. const uint8_t nonce[RFC_8439_NONCE_SIZE], const uint8_t *restrict ad,
  18735. size_t ad_size, const uint8_t *restrict cipher_text,
  18736. size_t cipher_text_size) {
  18737. // first we calculate the mac and see if it lines up, only then do we decrypt
  18738. size_t actual_size = cipher_text_size - RFC_8439_TAG_SIZE;
  18739. uint8_t computed_mac[RFC_8439_TAG_SIZE];
  18740. if (MG_OVERLAPPING(plain_text, actual_size, cipher_text, cipher_text_size)) {
  18741. return (size_t) -1;
  18742. }
  18743. poly1305_calculate_mac(computed_mac, cipher_text, actual_size, key, nonce, ad,
  18744. ad_size);
  18745. if (!mg_memeq(computed_mac, cipher_text + actual_size, RFC_8439_TAG_SIZE))
  18746. return (size_t) -1;
  18747. chacha20_xor_stream(plain_text, cipher_text, actual_size, key, nonce, 1);
  18748. return actual_size;
  18749. }
  18750. // ******* END: portable8439.c ********
  18751. #endif // MG_TLS == MG_TLS_BUILTIN
  18752. #ifdef MG_ENABLE_LINES
  18753. #line 1 "src/tls_dummy.c"
  18754. #endif
  18755. #if MG_TLS == MG_TLS_NONE
  18756. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
  18757. (void) opts;
  18758. mg_error(c, "TLS is not enabled");
  18759. }
  18760. void mg_tls_handshake(struct mg_connection *c) {
  18761. (void) c;
  18762. }
  18763. void mg_tls_free(struct mg_connection *c) {
  18764. (void) c;
  18765. }
  18766. long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
  18767. return c == NULL || buf == NULL || len == 0 ? 0 : -1;
  18768. }
  18769. long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
  18770. return c == NULL || buf == NULL || len == 0 ? 0 : -1;
  18771. }
  18772. size_t mg_tls_pending(struct mg_connection *c) {
  18773. (void) c;
  18774. return 0;
  18775. }
  18776. void mg_tls_flush(struct mg_connection *c) {
  18777. (void) c;
  18778. }
  18779. void mg_tls_ctx_init(struct mg_mgr *mgr) {
  18780. (void) mgr;
  18781. }
  18782. void mg_tls_ctx_free(struct mg_mgr *mgr) {
  18783. (void) mgr;
  18784. }
  18785. #endif
  18786. #ifdef MG_ENABLE_LINES
  18787. #line 1 "src/tls_mbed.c"
  18788. #endif
  18789. #if MG_TLS == MG_TLS_MBED
  18790. #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \
  18791. MBEDTLS_VERSION_NUMBER < 0x04000000
  18792. #define MG_MBEDTLS_RNG_GET , mg_mbed_rng, NULL
  18793. #else
  18794. #define MG_MBEDTLS_RNG_GET
  18795. #endif
  18796. static int mg_tls_err(struct mg_connection *c, int rc) {
  18797. char s[80];
  18798. mbedtls_strerror(rc, s, sizeof(s));
  18799. MG_ERROR(("%lu %s", ((struct mg_connection *) c)->id, s));
  18800. return rc;
  18801. }
  18802. #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x04000000
  18803. #else
  18804. static int mg_mbed_rng(void *ctx, unsigned char *buf, size_t len) {
  18805. (void) ctx;
  18806. return mg_random(buf, len) ? 0 : -1;
  18807. }
  18808. #endif
  18809. static bool mg_load_cert(struct mg_str str, mbedtls_x509_crt *p) {
  18810. int rc;
  18811. if (str.buf == NULL || str.buf[0] == '\0' || str.buf[0] == '*') return true;
  18812. if (!MG_IS_DER(str.buf)) str.len++; // PEM, include trailing NUL
  18813. if ((rc = mbedtls_x509_crt_parse(p, (uint8_t *) str.buf, str.len)) != 0) {
  18814. MG_ERROR(("cert err %#x", -rc));
  18815. return false;
  18816. }
  18817. return true;
  18818. }
  18819. static bool mg_load_key(struct mg_str str, mbedtls_pk_context *p) {
  18820. int rc;
  18821. if (str.buf == NULL || str.buf[0] == '\0' || str.buf[0] == '*') return true;
  18822. if (!MG_IS_DER(str.buf)) str.len++; // PEM, include trailing NUL
  18823. if ((rc = mbedtls_pk_parse_key(p, (uint8_t *) str.buf, str.len, NULL,
  18824. 0 MG_MBEDTLS_RNG_GET)) != 0) {
  18825. MG_ERROR(("key err %#x", -rc));
  18826. return false;
  18827. }
  18828. return true;
  18829. }
  18830. void mg_tls_free(struct mg_connection *c) {
  18831. struct mg_tls *tls = (struct mg_tls *) c->tls;
  18832. if (tls != NULL) {
  18833. mbedtls_ssl_free(&tls->ssl);
  18834. mbedtls_pk_free(&tls->pk);
  18835. mbedtls_x509_crt_free(&tls->ca);
  18836. mbedtls_x509_crt_free(&tls->cert);
  18837. mbedtls_ssl_config_free(&tls->conf);
  18838. #ifdef MBEDTLS_SSL_SESSION_TICKETS
  18839. mbedtls_ssl_ticket_free(&tls->ticket);
  18840. #endif
  18841. // PSA has global data. Do not call mbedtls_psa_crypto_free() here,
  18842. // it will free all global resources. Call it when actually freeing all
  18843. // application resources (main() exits)
  18844. mg_free(tls);
  18845. c->tls = NULL;
  18846. }
  18847. }
  18848. static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) {
  18849. long n = mg_io_send((struct mg_connection *) ctx, buf, len);
  18850. MG_VERBOSE(("%lu n=%ld e=%d", ((struct mg_connection *) ctx)->id, n, errno));
  18851. if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_WRITE;
  18852. // if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
  18853. if (n == MG_IO_ERR) return MBEDTLS_ERR_NET_SEND_FAILED;
  18854. return (int) n;
  18855. }
  18856. static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) {
  18857. long n = mg_io_recv((struct mg_connection *) ctx, buf, len);
  18858. MG_VERBOSE(("%lu n=%ld", ((struct mg_connection *) ctx)->id, n));
  18859. if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_READ;
  18860. // if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
  18861. if (n == MG_IO_ERR) return MBEDTLS_ERR_NET_RECV_FAILED;
  18862. return (int) n;
  18863. }
  18864. void mg_tls_handshake(struct mg_connection *c) {
  18865. struct mg_tls *tls = (struct mg_tls *) c->tls;
  18866. int rc = mbedtls_ssl_handshake(&tls->ssl);
  18867. if (rc == 0) { // Success
  18868. if (tls->check_name && (mbedtls_ssl_get_verify_result(&tls->ssl) &
  18869. MBEDTLS_X509_BADCERT_CN_MISMATCH)) {
  18870. mg_error(c, "failed to verify hostname");
  18871. return;
  18872. } // ignore MBEDTLS_X509_BADCERT_NOT_TRUSTED, no CA cert given
  18873. MG_DEBUG(("%lu success", c->id));
  18874. c->is_tls_hs = 0;
  18875. mg_call(c, MG_EV_TLS_HS, NULL);
  18876. } else if (rc == MBEDTLS_ERR_SSL_WANT_READ ||
  18877. rc == MBEDTLS_ERR_SSL_WANT_WRITE) { // Still pending
  18878. MG_VERBOSE(("%lu pending, %d%d %d (-%#x)", c->id, c->is_connecting,
  18879. c->is_tls_hs, rc, -rc));
  18880. } else {
  18881. mg_error(c, "TLS handshake: -%#x", -mg_tls_err(c, rc)); // Error
  18882. }
  18883. }
  18884. static void debug_cb(void *c, int lev, const char *s, int n, const char *s2) {
  18885. n = (int) strlen(s2) - 1;
  18886. MG_INFO(("%lu %d %.*s", ((struct mg_connection *) c)->id, lev, n, s2));
  18887. (void) s;
  18888. }
  18889. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
  18890. struct mg_tls *tls = (struct mg_tls *) mg_calloc(1, sizeof(*tls));
  18891. int rc = 0;
  18892. bool check_name = false;
  18893. c->tls = tls;
  18894. if (c->tls == NULL) {
  18895. mg_error(c, "TLS OOM");
  18896. goto fail;
  18897. }
  18898. if (c->is_listening) goto fail;
  18899. MG_DEBUG(("%lu Setting TLS", c->id));
  18900. MG_PROF_ADD(c, "mbedtls_init_start");
  18901. mbedtls_ssl_init(&tls->ssl);
  18902. mbedtls_ssl_config_init(&tls->conf);
  18903. mbedtls_x509_crt_init(&tls->ca);
  18904. mbedtls_x509_crt_init(&tls->cert);
  18905. mbedtls_pk_init(&tls->pk);
  18906. mbedtls_ssl_conf_dbg(&tls->conf, debug_cb, c);
  18907. #if defined(MG_MBEDTLS_DEBUG_LEVEL)
  18908. mbedtls_debug_set_threshold(MG_MBEDTLS_DEBUG_LEVEL);
  18909. #endif
  18910. if ((rc = mbedtls_ssl_config_defaults(
  18911. &tls->conf,
  18912. c->is_client ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
  18913. MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
  18914. mg_error(c, "tls defaults %#x", -mg_tls_err(c, rc));
  18915. goto fail;
  18916. }
  18917. #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x04000000
  18918. MG_INFO(("PSA is in control of random number generation"));
  18919. #else
  18920. mbedtls_ssl_conf_rng(&tls->conf, mg_mbed_rng, c);
  18921. #endif
  18922. if (c->is_client && opts->name.buf != NULL && opts->name.len > 0 &&
  18923. opts->name.buf[0] != '\0') {
  18924. char *host = mg_mprintf("%.*s", opts->name.len, opts->name.buf);
  18925. mbedtls_ssl_set_hostname(&tls->ssl, host);
  18926. #if !defined(MBEDTLS_VERSION_NUMBER) || MBEDTLS_VERSION_NUMBER < 0x03030000 || \
  18927. MBEDTLS_VERSION_NUMBER >= 0x04000000
  18928. // NOTE: MBEDTLS_SSL_VERIFY_OPTIONAL is not supported for TLS1.3 on client
  18929. // side See https://github.com/Mbed-TLS/mbedtls/issues/7075
  18930. check_name = true;
  18931. #endif
  18932. MG_DEBUG(("%lu hostname verification: %s", c->id, host));
  18933. mg_free(host);
  18934. } else {
  18935. MG_DEBUG(("%lu skipping hostname verification", c->id));
  18936. mbedtls_ssl_set_hostname(&tls->ssl, NULL);
  18937. }
  18938. if (opts->ca.len == 0 || mg_strcmp(opts->ca, mg_str("*")) == 0) {
  18939. mbedtls_ssl_conf_authmode(&tls->conf, check_name // see set comment above
  18940. ? MBEDTLS_SSL_VERIFY_OPTIONAL
  18941. : MBEDTLS_SSL_VERIFY_NONE);
  18942. tls->check_name = check_name; // host name set but no CA cert given
  18943. } else {
  18944. if (mg_load_cert(opts->ca, &tls->ca) == false) goto fail;
  18945. mbedtls_ssl_conf_ca_chain(&tls->conf, &tls->ca, NULL);
  18946. mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
  18947. }
  18948. if (!mg_load_cert(opts->cert, &tls->cert)) goto fail;
  18949. if (!mg_load_key(opts->key, &tls->pk)) goto fail;
  18950. if (tls->cert.version &&
  18951. (rc = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->cert, &tls->pk)) != 0) {
  18952. mg_error(c, "own cert %#x", -mg_tls_err(c, rc));
  18953. goto fail;
  18954. }
  18955. #ifdef MBEDTLS_SSL_SESSION_TICKETS
  18956. if (!c->is_client && c->mgr->tls_ctx != NULL) {
  18957. mbedtls_ssl_conf_session_tickets_cb(
  18958. &tls->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse,
  18959. &((struct mg_tls_ctx *) c->mgr->tls_ctx)->tickets);
  18960. }
  18961. #endif
  18962. if ((rc = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) {
  18963. mg_error(c, "setup err %#x", -mg_tls_err(c, rc));
  18964. goto fail;
  18965. }
  18966. c->is_tls = 1;
  18967. c->is_tls_hs = 1;
  18968. mbedtls_ssl_set_bio(&tls->ssl, c, mg_net_send, mg_net_recv, 0);
  18969. MG_PROF_ADD(c, "mbedtls_init_end");
  18970. return;
  18971. fail:
  18972. mg_tls_free(c);
  18973. }
  18974. size_t mg_tls_pending(struct mg_connection *c) {
  18975. struct mg_tls *tls = (struct mg_tls *) c->tls;
  18976. return tls == NULL ? 0 : mbedtls_ssl_get_bytes_avail(&tls->ssl);
  18977. }
  18978. long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
  18979. struct mg_tls *tls = (struct mg_tls *) c->tls;
  18980. long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
  18981. if (!c->is_tls_hs && (buf == NULL || len == 0) && n == 0) return 0; // MIP
  18982. if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE)
  18983. return MG_IO_WAIT;
  18984. #if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
  18985. if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) {
  18986. return MG_IO_WAIT;
  18987. }
  18988. #endif
  18989. if (n <= 0) return MG_IO_ERR;
  18990. return n;
  18991. }
  18992. long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
  18993. struct mg_tls *tls = (struct mg_tls *) c->tls;
  18994. long n;
  18995. bool was_throttled = c->is_tls_throttled; // see #3074
  18996. n = was_throttled ? mbedtls_ssl_write(&tls->ssl, tls->throttled_buf,
  18997. tls->throttled_len) /* flush old data */
  18998. : mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf,
  18999. len); // encrypt current data
  19000. #if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
  19001. if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
  19002. return MG_IO_WAIT;
  19003. #endif
  19004. c->is_tls_throttled =
  19005. (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE);
  19006. if (was_throttled && c->is_tls_throttled) return MG_IO_WAIT; // no changes
  19007. if (c->is_tls_throttled) {
  19008. tls->throttled_buf =
  19009. (unsigned char *) buf; // MbedTLS code actually ignores
  19010. tls->throttled_len = len; // these, but let's play API rules
  19011. return MG_IO_WAIT;
  19012. }
  19013. if (n <= 0) return MG_IO_ERR;
  19014. return n;
  19015. }
  19016. void mg_tls_flush(struct mg_connection *c) {
  19017. struct mg_tls *tls = (struct mg_tls *) c->tls;
  19018. if (c->is_tls_throttled && c->is_draining) {
  19019. long n =
  19020. mbedtls_ssl_write(&tls->ssl, tls->throttled_buf, tls->throttled_len);
  19021. #if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
  19022. if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) return;
  19023. #endif
  19024. c->is_tls_throttled =
  19025. (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE);
  19026. }
  19027. }
  19028. void mg_tls_ctx_init(struct mg_mgr *mgr) {
  19029. #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \
  19030. defined(MBEDTLS_PSA_CRYPTO_C)
  19031. psa_crypto_init(); // Initializes global PSA resources, no-op if already done
  19032. #endif
  19033. #ifdef MBEDTLS_SSL_SESSION_TICKETS
  19034. {
  19035. struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mg_calloc(1, sizeof(*ctx));
  19036. if (ctx == NULL) {
  19037. MG_ERROR(("TLS context init OOM"));
  19038. } else {
  19039. int rc;
  19040. mbedtls_ssl_ticket_init(&ctx->tickets);
  19041. #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x04000000
  19042. rc = mbedtls_ssl_ticket_setup(&ctx->tickets, PSA_ALG_GCM,
  19043. PSA_KEY_TYPE_AES, 128, 86400);
  19044. #else
  19045. rc = mbedtls_ssl_ticket_setup(&ctx->tickets, mg_mbed_rng, NULL,
  19046. MBEDTLS_CIPHER_AES_128_GCM, 86400);
  19047. #endif
  19048. if (rc != 0) {
  19049. MG_ERROR((" mbedtls_ssl_ticket_setup %#x", -rc));
  19050. mbedtls_ssl_ticket_free(&ctx->tickets);
  19051. mg_free(ctx);
  19052. } else {
  19053. mgr->tls_ctx = ctx;
  19054. }
  19055. }
  19056. }
  19057. #else
  19058. (void) mgr;
  19059. #endif
  19060. }
  19061. void mg_tls_ctx_free(struct mg_mgr *mgr) {
  19062. struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mgr->tls_ctx;
  19063. if (ctx != NULL) {
  19064. #ifdef MBEDTLS_SSL_SESSION_TICKETS
  19065. mbedtls_ssl_ticket_free(&ctx->tickets);
  19066. #endif
  19067. mg_free(ctx);
  19068. mgr->tls_ctx = NULL;
  19069. }
  19070. }
  19071. #endif
  19072. #ifdef MG_ENABLE_LINES
  19073. #line 1 "src/tls_openssl.c"
  19074. #endif
  19075. #if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL
  19076. static int tls_err_cb(const char *s, size_t len, void *c) {
  19077. int n = (int) len - 1;
  19078. MG_ERROR(("%lu %.*s", ((struct mg_connection *) c)->id, n, s));
  19079. return 0; // undocumented
  19080. }
  19081. static int mg_tls_err(struct mg_connection *c, struct mg_tls *tls, int res) {
  19082. int err = SSL_get_error(tls->ssl, res);
  19083. // We've just fetched the last error from the queue.
  19084. // Now we need to clear the error queue. If we do not, then the following
  19085. // can happen (actually reported):
  19086. // - A new connection is accept()-ed with cert error (e.g. self-signed cert)
  19087. // - Since all accept()-ed connections share listener's context,
  19088. // - *ALL* SSL accepted connection report read error on the next poll cycle.
  19089. // Thus a single errored connection can close all the rest, unrelated ones.
  19090. // Clearing the error keeps the shared SSL_CTX in an OK state.
  19091. if (err != 0) ERR_print_errors_cb(tls_err_cb, c);
  19092. ERR_clear_error();
  19093. if (err == SSL_ERROR_WANT_READ) return 0;
  19094. if (err == SSL_ERROR_WANT_WRITE) return 0;
  19095. return err;
  19096. }
  19097. #if MG_TLS != MG_TLS_WOLFSSL
  19098. static STACK_OF(X509_INFO) * load_ca_certs(struct mg_str ca) {
  19099. BIO *bio = BIO_new_mem_buf(ca.buf, (int) ca.len);
  19100. STACK_OF(X509_INFO) *certs =
  19101. bio ? PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL) : NULL;
  19102. if (bio) BIO_free(bio);
  19103. return certs;
  19104. }
  19105. static bool add_ca_certs(SSL_CTX *ctx, STACK_OF(X509_INFO) * certs) {
  19106. int i;
  19107. X509_STORE *cert_store = SSL_CTX_get_cert_store(ctx);
  19108. if (cert_store == NULL) return false;
  19109. for (i = 0; i < sk_X509_INFO_num(certs); i++) {
  19110. X509_INFO *cert_info = sk_X509_INFO_value(certs, i);
  19111. if (cert_info->x509 && !X509_STORE_add_cert(cert_store, cert_info->x509))
  19112. return false;
  19113. }
  19114. return true;
  19115. }
  19116. #endif
  19117. static EVP_PKEY *load_key(struct mg_str s) {
  19118. BIO *bio = BIO_new_mem_buf(s.buf, (int) (long) s.len);
  19119. EVP_PKEY *key = bio ? PEM_read_bio_PrivateKey(bio, NULL, 0, NULL) : NULL;
  19120. if (bio) BIO_free(bio);
  19121. return key;
  19122. }
  19123. static int load_cert(SSL *ssl, struct mg_str s) {
  19124. BIO *bio = BIO_new_mem_buf(s.buf, (int) (long) s.len);
  19125. X509 *cert = NULL;
  19126. int rc = 0;
  19127. if (bio == NULL) return 0;
  19128. if (MG_IS_DER(s.buf)) {
  19129. cert = d2i_X509_bio(bio, NULL);
  19130. rc = cert == NULL ? 0 : SSL_use_certificate(ssl, cert);
  19131. } else {
  19132. cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
  19133. rc = cert == NULL ? 0 : SSL_use_certificate(ssl, cert);
  19134. #if MG_TLS != MG_TLS_WOLFSSL
  19135. X509_free(cert);
  19136. while (rc == 1) {
  19137. cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
  19138. if (cert == NULL) {
  19139. ERR_clear_error(); // PEM_read_bio_X509 sets an error on EOF
  19140. break;
  19141. }
  19142. rc = (int) SSL_add1_chain_cert(ssl, cert);
  19143. X509_free(cert);
  19144. }
  19145. cert = NULL;
  19146. #endif
  19147. }
  19148. X509_free(cert);
  19149. if (bio) BIO_free(bio);
  19150. return rc;
  19151. }
  19152. static long mg_bio_ctrl(BIO *b, int cmd, long larg, void *pargs) {
  19153. long ret = 0;
  19154. if (cmd == BIO_CTRL_PUSH) ret = 1;
  19155. if (cmd == BIO_CTRL_POP) ret = 1;
  19156. if (cmd == BIO_CTRL_FLUSH) ret = 1;
  19157. #if MG_TLS == MG_TLS_OPENSSL
  19158. if (cmd == BIO_C_SET_NBIO) ret = 1;
  19159. #endif
  19160. // MG_DEBUG(("%d -> %ld", cmd, ret));
  19161. (void) b, (void) cmd, (void) larg, (void) pargs;
  19162. return ret;
  19163. }
  19164. static int mg_bio_read(BIO *bio, char *buf, int len) {
  19165. struct mg_connection *c = (struct mg_connection *) BIO_get_data(bio);
  19166. long res = mg_io_recv(c, buf, (size_t) len);
  19167. // MG_DEBUG(("%p %d %ld", buf, len, res));
  19168. len = res > 0 ? (int) res : -1;
  19169. if (res == MG_IO_WAIT) BIO_set_retry_read(bio);
  19170. return len;
  19171. }
  19172. static int mg_bio_write(BIO *bio, const char *buf, int len) {
  19173. struct mg_connection *c = (struct mg_connection *) BIO_get_data(bio);
  19174. long res = mg_io_send(c, buf, (size_t) len);
  19175. // MG_DEBUG(("%p %d %ld", buf, len, res));
  19176. len = res > 0 ? (int) res : -1;
  19177. if (res == MG_IO_WAIT) BIO_set_retry_write(bio);
  19178. return len;
  19179. }
  19180. #ifdef MG_TLS_SSLKEYLOGFILE
  19181. static void ssl_keylog_cb(const SSL *ssl, const char *line) {
  19182. FILE *f;
  19183. char *keylogfile = getenv("SSLKEYLOGFILE");
  19184. if (keylogfile == NULL) return;
  19185. f = fopen(keylogfile, "a");
  19186. if (f != NULL) {
  19187. fprintf(f, "%s\n", line);
  19188. fflush(f);
  19189. fclose(f);
  19190. } else {
  19191. MG_ERROR(("Cannot open %s", keylogfile));
  19192. }
  19193. (void) ssl;
  19194. }
  19195. #endif
  19196. void mg_tls_free(struct mg_connection *c) {
  19197. struct mg_tls *tls = (struct mg_tls *) c->tls;
  19198. if (tls == NULL) return;
  19199. SSL_free(tls->ssl);
  19200. SSL_CTX_free(tls->ctx);
  19201. BIO_meth_free(tls->bm);
  19202. mg_free(tls->name);
  19203. mg_free(tls);
  19204. c->tls = NULL;
  19205. }
  19206. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
  19207. struct mg_tls *tls = (struct mg_tls *) mg_calloc(1, sizeof(*tls));
  19208. const char *id = "mongoose";
  19209. bool check_name = false;
  19210. static unsigned char s_initialised = 0;
  19211. BIO *bio = NULL;
  19212. int rc;
  19213. c->tls = tls;
  19214. if (tls == NULL) {
  19215. mg_error(c, "TLS OOM");
  19216. goto fail;
  19217. }
  19218. if (!s_initialised) {
  19219. SSL_library_init();
  19220. s_initialised++;
  19221. }
  19222. MG_DEBUG(("%lu Setting TLS", c->id));
  19223. tls->ctx = c->is_client ? SSL_CTX_new(TLS_client_method())
  19224. : SSL_CTX_new(TLS_server_method());
  19225. if (tls->ctx == NULL) {
  19226. mg_error(c, "SSL_CTX_new");
  19227. goto fail;
  19228. }
  19229. #ifdef MG_TLS_SSLKEYLOGFILE
  19230. SSL_CTX_set_keylog_callback(tls->ctx, ssl_keylog_cb);
  19231. #endif
  19232. if ((tls->ssl = SSL_new(tls->ctx)) == NULL) {
  19233. mg_error(c, "SSL_new");
  19234. goto fail;
  19235. }
  19236. SSL_set_session_id_context(tls->ssl, (const uint8_t *) id,
  19237. (unsigned) strlen(id));
  19238. // Disable deprecated protocols
  19239. SSL_set_options(tls->ssl, SSL_OP_NO_SSLv2);
  19240. SSL_set_options(tls->ssl, SSL_OP_NO_SSLv3);
  19241. SSL_set_options(tls->ssl, SSL_OP_NO_TLSv1);
  19242. SSL_set_options(tls->ssl, SSL_OP_NO_TLSv1_1);
  19243. #ifdef MG_ENABLE_OPENSSL_NO_COMPRESSION
  19244. SSL_set_options(tls->ssl, SSL_OP_NO_COMPRESSION);
  19245. #endif
  19246. #ifdef MG_ENABLE_OPENSSL_CIPHER_SERVER_PREFERENCE
  19247. SSL_set_options(tls->ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
  19248. #endif
  19249. if (c->is_client && opts->name.buf != NULL && opts->name.len > 0 && opts->name.buf[0] != '\0') {
  19250. tls->name = mg_mprintf("%.*s", (int) opts->name.len, opts->name.buf);
  19251. if (tls->name == NULL) {
  19252. mg_error(c, "TLS OOM");
  19253. goto fail;
  19254. }
  19255. check_name = true;
  19256. }
  19257. #if MG_TLS == MG_TLS_WOLFSSL && !defined(OPENSSL_COMPATIBLE_DEFAULTS)
  19258. if (opts->ca.len == 0 || mg_strcmp(opts->ca, mg_str("*")) == 0) {
  19259. // Older versions require that either the CA is loaded or SSL_VERIFY_NONE
  19260. // explicitly set
  19261. SSL_set_verify(tls->ssl, SSL_VERIFY_NONE, NULL);
  19262. }
  19263. #endif
  19264. if (opts->ca.buf != NULL && opts->ca.len > 0 && opts->ca.buf[0] != '\0') {
  19265. SSL_set_verify(tls->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
  19266. NULL);
  19267. #if MG_TLS == MG_TLS_WOLFSSL
  19268. extern int wolfSSL_CTX_load_verify_buffer(SSL_CTX *, const unsigned char *,
  19269. long, int);
  19270. rc = wolfSSL_CTX_load_verify_buffer(tls->ctx,
  19271. (const unsigned char *) opts->ca.buf,
  19272. (long) opts->ca.len, SSL_FILETYPE_PEM);
  19273. if (rc != 1) {
  19274. mg_error(c, "CA err");
  19275. goto fail;
  19276. }
  19277. #else
  19278. STACK_OF(X509_INFO) *certs = load_ca_certs(opts->ca);
  19279. rc = add_ca_certs(tls->ctx, certs);
  19280. sk_X509_INFO_pop_free(certs, X509_INFO_free);
  19281. if (!rc) {
  19282. mg_error(c, "CA err");
  19283. goto fail;
  19284. }
  19285. #endif
  19286. } else {
  19287. tls->check_name = check_name; // host name set but no CA cert given
  19288. }
  19289. if (opts->cert.buf != NULL && opts->cert.buf[0] != '\0') {
  19290. rc = load_cert(tls->ssl, opts->cert);
  19291. if (rc != 1) {
  19292. mg_error(c, "CERT err %d", mg_tls_err(c, tls, rc));
  19293. goto fail;
  19294. }
  19295. }
  19296. if (opts->key.buf != NULL && opts->key.buf[0] != '\0') {
  19297. EVP_PKEY *key = load_key(opts->key);
  19298. rc = key == NULL ? 0 : SSL_use_PrivateKey(tls->ssl, key);
  19299. EVP_PKEY_free(key);
  19300. if (key == NULL || rc != 1) {
  19301. mg_error(c, "KEY err %d", mg_tls_err(c, tls, rc));
  19302. goto fail;
  19303. }
  19304. }
  19305. SSL_set_mode(tls->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  19306. #if MG_TLS == MG_TLS_OPENSSL && OPENSSL_VERSION_NUMBER > 0x10002000L
  19307. (void) SSL_set_ecdh_auto(tls->ssl, 1);
  19308. #endif
  19309. #if OPENSSL_VERSION_NUMBER >= 0x10100000L
  19310. if (tls->name != NULL) {
  19311. #if MG_TLS != MG_TLS_WOLFSSL || LIBWOLFSSL_VERSION_HEX >= 0x05005002
  19312. SSL_set1_host(tls->ssl, tls->name);
  19313. #else
  19314. X509_VERIFY_PARAM_set1_host(SSL_get0_param(tls->ssl), tls->name, 0);
  19315. #endif
  19316. SSL_set_tlsext_host_name(tls->ssl, tls->name);
  19317. }
  19318. #endif
  19319. #if MG_TLS == MG_TLS_WOLFSSL
  19320. tls->bm = BIO_meth_new(0, "bio_mg");
  19321. #else
  19322. tls->bm = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "bio_mg");
  19323. #endif
  19324. BIO_meth_set_write(tls->bm, mg_bio_write);
  19325. BIO_meth_set_read(tls->bm, mg_bio_read);
  19326. BIO_meth_set_ctrl(tls->bm, mg_bio_ctrl);
  19327. bio = BIO_new(tls->bm);
  19328. BIO_set_data(bio, c);
  19329. SSL_set_bio(tls->ssl, bio, bio);
  19330. c->is_tls = 1;
  19331. c->is_tls_hs = 1;
  19332. MG_DEBUG(("%lu SSL %s OK", c->id, c->is_accepted ? "accept" : "client"));
  19333. return;
  19334. fail:
  19335. mg_tls_free(c);
  19336. }
  19337. void mg_tls_handshake(struct mg_connection *c) {
  19338. struct mg_tls *tls = (struct mg_tls *) c->tls;
  19339. int rc = c->is_client ? SSL_connect(tls->ssl) : SSL_accept(tls->ssl);
  19340. if (rc == 1) {
  19341. if (tls->check_name) { // host name set but no CA cert given
  19342. X509 *cert = SSL_get_peer_certificate(tls->ssl);
  19343. bool ok =
  19344. cert != NULL && X509_check_host(cert, tls->name, 0, 0, NULL) == 1;
  19345. X509_free(cert);
  19346. if (!ok) {
  19347. mg_error(c, "failed to verify hostname");
  19348. return;
  19349. }
  19350. }
  19351. MG_DEBUG(("%lu success", c->id));
  19352. c->is_tls_hs = 0;
  19353. mg_call(c, MG_EV_TLS_HS, NULL);
  19354. } else {
  19355. int code = mg_tls_err(c, tls, rc);
  19356. if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code);
  19357. }
  19358. }
  19359. size_t mg_tls_pending(struct mg_connection *c) {
  19360. struct mg_tls *tls = (struct mg_tls *) c->tls;
  19361. return tls == NULL ? 0 : (size_t) SSL_pending(tls->ssl);
  19362. }
  19363. long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
  19364. struct mg_tls *tls = (struct mg_tls *) c->tls;
  19365. int n;
  19366. #if MG_TLS == MG_TLS_WOLFSSL
  19367. uint8_t dummy; // WolfSSL requires destination != NULL
  19368. if (buf == NULL && len == 0) buf = &dummy;
  19369. #endif
  19370. n = SSL_read(tls->ssl, buf, (int) len);
  19371. if (!c->is_tls_hs && (buf == NULL || len == 0) && n == 0) return 0; // MIP
  19372. if (n < 0 && mg_tls_err(c, tls, n) == 0) return MG_IO_WAIT;
  19373. if (n <= 0) return MG_IO_ERR;
  19374. return n;
  19375. }
  19376. long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
  19377. struct mg_tls *tls = (struct mg_tls *) c->tls;
  19378. int n = SSL_write(tls->ssl, buf, (int) len);
  19379. if (n < 0 && mg_tls_err(c, tls, n) == 0) return MG_IO_WAIT;
  19380. if (n <= 0) return MG_IO_ERR;
  19381. return n;
  19382. }
  19383. void mg_tls_flush(struct mg_connection *c) {
  19384. (void) c;
  19385. }
  19386. void mg_tls_ctx_init(struct mg_mgr *mgr) {
  19387. (void) mgr;
  19388. }
  19389. void mg_tls_ctx_free(struct mg_mgr *mgr) {
  19390. (void) mgr;
  19391. }
  19392. #endif
  19393. #ifdef MG_ENABLE_LINES
  19394. #line 1 "src/tls_rsa.c"
  19395. #endif
  19396. #if MG_TLS == MG_TLS_BUILTIN
  19397. /*
  19398. * The RSA bigint backend below is derived from BearSSL's i31 RSA code.
  19399. *
  19400. * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
  19401. *
  19402. * Permission is hereby granted, free of charge, to any person obtaining
  19403. * a copy of this software and associated documentation files (the
  19404. * "Software"), to deal in the Software without restriction, including
  19405. * without limitation the rights to use, copy, modify, merge, publish,
  19406. * distribute, sublicense, and/or sell copies of the Software, and to
  19407. * permit persons to whom the Software is furnished to do so, subject to
  19408. * the following conditions:
  19409. *
  19410. * The above copyright notice and this permission notice shall be
  19411. * included in all copies or substantial portions of the Software.
  19412. *
  19413. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19414. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19415. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19416. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19417. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  19418. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19419. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19420. * SOFTWARE.
  19421. */
  19422. #define BR_MAX_RSA_SIZE 4096
  19423. #define BR_MAX_RSA_FACTOR ((BR_MAX_RSA_SIZE + 64) >> 1)
  19424. #define BR_I31_WORDS(bits) (2 + (((bits) + 30) / 31))
  19425. #define BR_RSA_WORDS BR_I31_WORDS(BR_MAX_RSA_SIZE)
  19426. #define BR_RSA_FACTOR_WORDS BR_I31_WORDS(BR_MAX_RSA_FACTOR)
  19427. #define BR_64 1
  19428. #define MUL31(x, y) ((uint64_t) (x) * (uint64_t) (y))
  19429. #define MUL31_lo(x, y) (((uint32_t) (x) * (uint32_t) (y)) & 0x7fffffffU)
  19430. #define CCOPY br_ccopy
  19431. static uint32_t NOT(uint32_t ctl) { return ctl ^ 1; }
  19432. static uint32_t MUX(uint32_t ctl, uint32_t x, uint32_t y) {
  19433. return y ^ (-ctl & (x ^ y));
  19434. }
  19435. static uint32_t EQ(uint32_t x, uint32_t y) {
  19436. uint32_t q = x ^ y;
  19437. return NOT((q | -q) >> 31);
  19438. }
  19439. static uint32_t NEQ(uint32_t x, uint32_t y) {
  19440. uint32_t q = x ^ y;
  19441. return (q | -q) >> 31;
  19442. }
  19443. static uint32_t GT(uint32_t x, uint32_t y) {
  19444. uint32_t z = y - x;
  19445. return (z ^ ((x ^ y) & (x ^ z))) >> 31;
  19446. }
  19447. #define GE(x, y) NOT(GT(y, x))
  19448. #define LT(x, y) GT(y, x)
  19449. static uint32_t BIT_LENGTH(uint32_t x) {
  19450. uint32_t k, c;
  19451. k = NEQ(x, 0);
  19452. c = GT(x, 0xffff); x = MUX(c, x >> 16, x); k += c << 4;
  19453. c = GT(x, 0x00ff); x = MUX(c, x >> 8, x); k += c << 3;
  19454. c = GT(x, 0x000f); x = MUX(c, x >> 4, x); k += c << 2;
  19455. c = GT(x, 0x0003); x = MUX(c, x >> 2, x); k += c << 1;
  19456. k += GT(x, 0x0001);
  19457. return k;
  19458. }
  19459. static void br_enc32be(void *dst, uint32_t x) {
  19460. unsigned char *buf = (unsigned char *) dst;
  19461. buf[0] = (unsigned char) (x >> 24);
  19462. buf[1] = (unsigned char) (x >> 16);
  19463. buf[2] = (unsigned char) (x >> 8);
  19464. buf[3] = (unsigned char) x;
  19465. }
  19466. static void br_ccopy(uint32_t ctl, void *dst, const void *src, size_t len) {
  19467. unsigned char *d = (unsigned char *) dst;
  19468. const unsigned char *s = (const unsigned char *) src;
  19469. while (len-- > 0) {
  19470. uint32_t x = *s++, y = *d;
  19471. *d++ = (unsigned char) MUX(ctl, x, y);
  19472. }
  19473. }
  19474. static uint32_t br_i31_add(uint32_t *, const uint32_t *, uint32_t);
  19475. static uint32_t br_i31_sub(uint32_t *, const uint32_t *, uint32_t);
  19476. static uint32_t br_i31_bit_length(uint32_t *, size_t);
  19477. static void br_i31_decode(uint32_t *, const void *, size_t);
  19478. static void br_i31_encode(void *, size_t, const uint32_t *);
  19479. static uint32_t br_i31_ninv31(uint32_t);
  19480. static uint32_t br_divrem(uint32_t, uint32_t, uint32_t, uint32_t *);
  19481. static void br_i31_muladd_small(uint32_t *, uint32_t, const uint32_t *);
  19482. static void br_i31_reduce(uint32_t *, const uint32_t *, const uint32_t *);
  19483. static void br_i31_rshift(uint32_t *, int);
  19484. static void br_i31_decode_reduce(uint32_t *, const void *, size_t, const uint32_t *);
  19485. static void br_i31_mulacc(uint32_t *, const uint32_t *, const uint32_t *);
  19486. static void br_i31_montymul(uint32_t *, const uint32_t *, const uint32_t *, const uint32_t *, uint32_t);
  19487. static void br_i31_to_monty(uint32_t *, const uint32_t *);
  19488. static void br_i31_modpow(uint32_t *, const unsigned char *, size_t, const uint32_t *, uint32_t, uint32_t *, uint32_t *);
  19489. static void br_i31_zero(uint32_t *x, uint32_t bit_len) {
  19490. *x++ = bit_len;
  19491. memset(x, 0, ((bit_len + 31) >> 5) * sizeof *x);
  19492. }
  19493. static uint32_t br_rem(uint32_t hi, uint32_t lo, uint32_t d) {
  19494. uint32_t r;
  19495. br_divrem(hi, lo, d, &r);
  19496. return r;
  19497. }
  19498. static uint32_t br_div(uint32_t hi, uint32_t lo, uint32_t d) {
  19499. uint32_t r;
  19500. return br_divrem(hi, lo, d, &r);
  19501. }
  19502. static uint32_t
  19503. br_i31_add(uint32_t *a, const uint32_t *b, uint32_t ctl)
  19504. {
  19505. uint32_t cc;
  19506. size_t u, m;
  19507. cc = 0;
  19508. m = (a[0] + 63) >> 5;
  19509. for (u = 1; u < m; u ++) {
  19510. uint32_t aw, bw, naw;
  19511. aw = a[u];
  19512. bw = b[u];
  19513. naw = aw + bw + cc;
  19514. cc = naw >> 31;
  19515. a[u] = MUX(ctl, naw & (uint32_t)0x7FFFFFFF, aw);
  19516. }
  19517. return cc;
  19518. }
  19519. static uint32_t
  19520. br_i31_sub(uint32_t *a, const uint32_t *b, uint32_t ctl)
  19521. {
  19522. uint32_t cc;
  19523. size_t u, m;
  19524. cc = 0;
  19525. m = (a[0] + 63) >> 5;
  19526. for (u = 1; u < m; u ++) {
  19527. uint32_t aw, bw, naw;
  19528. aw = a[u];
  19529. bw = b[u];
  19530. naw = aw - bw - cc;
  19531. cc = naw >> 31;
  19532. a[u] = MUX(ctl, naw & 0x7FFFFFFF, aw);
  19533. }
  19534. return cc;
  19535. }
  19536. static uint32_t
  19537. br_i31_bit_length(uint32_t *x, size_t xlen)
  19538. {
  19539. uint32_t tw, twk;
  19540. tw = 0;
  19541. twk = 0;
  19542. while (xlen -- > 0) {
  19543. uint32_t w, c;
  19544. c = EQ(tw, 0);
  19545. w = x[xlen];
  19546. tw = MUX(c, w, tw);
  19547. twk = MUX(c, (uint32_t)xlen, twk);
  19548. }
  19549. return (twk << 5) + BIT_LENGTH(tw);
  19550. }
  19551. static void
  19552. br_i31_decode(uint32_t *x, const void *src, size_t len)
  19553. {
  19554. const unsigned char *buf;
  19555. size_t u, v;
  19556. uint32_t acc;
  19557. int acc_len;
  19558. buf = (const unsigned char *) src;
  19559. u = len;
  19560. v = 1;
  19561. acc = 0;
  19562. acc_len = 0;
  19563. while (u -- > 0) {
  19564. uint32_t b;
  19565. b = buf[u];
  19566. acc |= (b << acc_len);
  19567. acc_len += 8;
  19568. if (acc_len >= 31) {
  19569. x[v ++] = acc & (uint32_t)0x7FFFFFFF;
  19570. acc_len -= 31;
  19571. acc = b >> (8 - acc_len);
  19572. }
  19573. }
  19574. if (acc_len != 0) {
  19575. x[v ++] = acc;
  19576. }
  19577. x[0] = br_i31_bit_length(x + 1, v - 1);
  19578. }
  19579. static void
  19580. br_i31_encode(void *dst, size_t len, const uint32_t *x)
  19581. {
  19582. unsigned char *buf;
  19583. size_t k, xlen;
  19584. uint32_t acc;
  19585. int acc_len;
  19586. xlen = (x[0] + 31) >> 5;
  19587. if (xlen == 0) {
  19588. memset(dst, 0, len);
  19589. return;
  19590. }
  19591. buf = (unsigned char *)dst + len;
  19592. k = 1;
  19593. acc = 0;
  19594. acc_len = 0;
  19595. while (len != 0) {
  19596. uint32_t w;
  19597. w = (k <= xlen) ? x[k] : 0;
  19598. k ++;
  19599. if (acc_len == 0) {
  19600. acc = w;
  19601. acc_len = 31;
  19602. } else {
  19603. uint32_t z;
  19604. z = acc | (w << acc_len);
  19605. acc_len --;
  19606. acc = w >> (31 - acc_len);
  19607. if (len >= 4) {
  19608. buf -= 4;
  19609. len -= 4;
  19610. br_enc32be(buf, z);
  19611. } else {
  19612. switch (len) {
  19613. case 3:
  19614. buf[-3] = (unsigned char)(z >> 16);
  19615. /* fall through */
  19616. case 2:
  19617. buf[-2] = (unsigned char)(z >> 8);
  19618. /* fall through */
  19619. case 1:
  19620. buf[-1] = (unsigned char)z;
  19621. break;
  19622. }
  19623. return;
  19624. }
  19625. }
  19626. }
  19627. }
  19628. static uint32_t
  19629. br_i31_ninv31(uint32_t x)
  19630. {
  19631. uint32_t y;
  19632. y = 2 - x;
  19633. y *= 2 - y * x;
  19634. y *= 2 - y * x;
  19635. y *= 2 - y * x;
  19636. y *= 2 - y * x;
  19637. return MUX(x & 1, -y, 0) & 0x7FFFFFFF;
  19638. }
  19639. static uint32_t
  19640. br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r)
  19641. {
  19642. /* TODO: optimize this */
  19643. uint32_t q;
  19644. uint32_t ch, cf;
  19645. int k;
  19646. q = 0;
  19647. ch = EQ(hi, d);
  19648. hi = MUX(ch, 0, hi);
  19649. for (k = 31; k > 0; k --) {
  19650. int j;
  19651. uint32_t w, ctl, hi2, lo2;
  19652. j = 32 - k;
  19653. w = (hi << j) | (lo >> k);
  19654. ctl = GE(w, d) | (hi >> k);
  19655. hi2 = (w - d) >> j;
  19656. lo2 = lo - (d << k);
  19657. hi = MUX(ctl, hi2, hi);
  19658. lo = MUX(ctl, lo2, lo);
  19659. q |= ctl << k;
  19660. }
  19661. cf = GE(lo, d) | hi;
  19662. q |= cf;
  19663. *r = MUX(cf, lo - d, lo);
  19664. return q;
  19665. }
  19666. static void
  19667. br_i31_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m)
  19668. {
  19669. uint32_t m_bitlen;
  19670. unsigned mblr;
  19671. size_t u, mlen;
  19672. uint32_t a0, a1, b0, hi, g, q, tb;
  19673. uint32_t under, over;
  19674. uint32_t cc;
  19675. /*
  19676. * We can test on the modulus bit length since we accept to
  19677. * leak that length.
  19678. */
  19679. m_bitlen = m[0];
  19680. if (m_bitlen == 0) {
  19681. return;
  19682. }
  19683. if (m_bitlen <= 31) {
  19684. uint32_t lo;
  19685. hi = x[1] >> 1;
  19686. lo = (x[1] << 31) | z;
  19687. x[1] = br_rem(hi, lo, m[1]);
  19688. return;
  19689. }
  19690. mlen = (m_bitlen + 31) >> 5;
  19691. mblr = (unsigned)m_bitlen & 31;
  19692. /*
  19693. * Principle: we estimate the quotient (x*2^31+z)/m by
  19694. * doing a 64/32 division with the high words.
  19695. *
  19696. * Let:
  19697. * w = 2^31
  19698. * a = (w*a0 + a1) * w^N + a2
  19699. * b = b0 * w^N + b2
  19700. * such that:
  19701. * 0 <= a0 < w
  19702. * 0 <= a1 < w
  19703. * 0 <= a2 < w^N
  19704. * w/2 <= b0 < w
  19705. * 0 <= b2 < w^N
  19706. * a < w*b
  19707. * I.e. the two top words of a are a0:a1, the top word of b is
  19708. * b0, we ensured that b0 is "full" (high bit set), and a is
  19709. * such that the quotient q = a/b fits on one word (0 <= q < w).
  19710. *
  19711. * If a = b*q + r (with 0 <= r < q), we can estimate q by
  19712. * doing an Euclidean division on the top words:
  19713. * a0*w+a1 = b0*u + v (with 0 <= v < b0)
  19714. * Then the following holds:
  19715. * 0 <= u <= w
  19716. * u-2 <= q <= u
  19717. */
  19718. hi = x[mlen];
  19719. if (mblr == 0) {
  19720. a0 = x[mlen];
  19721. memmove(x + 2, x + 1, (mlen - 1) * sizeof *x);
  19722. x[1] = z;
  19723. a1 = x[mlen];
  19724. b0 = m[mlen];
  19725. } else {
  19726. a0 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr))
  19727. & 0x7FFFFFFF;
  19728. memmove(x + 2, x + 1, (mlen - 1) * sizeof *x);
  19729. x[1] = z;
  19730. a1 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr))
  19731. & 0x7FFFFFFF;
  19732. b0 = ((m[mlen] << (31 - mblr)) | (m[mlen - 1] >> mblr))
  19733. & 0x7FFFFFFF;
  19734. }
  19735. /*
  19736. * We estimate a divisor q. If the quotient returned by br_div()
  19737. * is g:
  19738. * -- If a0 == b0 then g == 0; we want q = 0x7FFFFFFF.
  19739. * -- Otherwise:
  19740. * -- if g == 0 then we set q = 0;
  19741. * -- otherwise, we set q = g - 1.
  19742. * The properties described above then ensure that the true
  19743. * quotient is q-1, q or q+1.
  19744. *
  19745. * Take care that a0, a1 and b0 are 31-bit words, not 32-bit. We
  19746. * must adjust the parameters to br_div() accordingly.
  19747. */
  19748. g = br_div(a0 >> 1, a1 | (a0 << 31), b0);
  19749. q = MUX(EQ(a0, b0), 0x7FFFFFFF, MUX(EQ(g, 0), 0, g - 1));
  19750. /*
  19751. * We subtract q*m from x (with the extra high word of value 'hi').
  19752. * Since q may be off by 1 (in either direction), we may have to
  19753. * add or subtract m afterwards.
  19754. *
  19755. * The 'tb' flag will be true (1) at the end of the loop if the
  19756. * result is greater than or equal to the modulus (not counting
  19757. * 'hi' or the carry).
  19758. */
  19759. cc = 0;
  19760. tb = 1;
  19761. for (u = 1; u <= mlen; u ++) {
  19762. uint32_t mw, zw, xw, nxw;
  19763. uint64_t zl;
  19764. mw = m[u];
  19765. zl = MUL31(mw, q) + cc;
  19766. cc = (uint32_t)(zl >> 31);
  19767. zw = (uint32_t)zl & (uint32_t)0x7FFFFFFF;
  19768. xw = x[u];
  19769. nxw = xw - zw;
  19770. cc += nxw >> 31;
  19771. nxw &= 0x7FFFFFFF;
  19772. x[u] = nxw;
  19773. tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw));
  19774. }
  19775. /*
  19776. * If we underestimated q, then either cc < hi (one extra bit
  19777. * beyond the top array word), or cc == hi and tb is true (no
  19778. * extra bit, but the result is not lower than the modulus). In
  19779. * these cases we must subtract m once.
  19780. *
  19781. * Otherwise, we may have overestimated, which will show as
  19782. * cc > hi (thus a negative result). Correction is adding m once.
  19783. */
  19784. over = GT(cc, hi);
  19785. under = ~over & (tb | LT(cc, hi));
  19786. br_i31_add(x, m, over);
  19787. br_i31_sub(x, m, under);
  19788. }
  19789. static void
  19790. br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m)
  19791. {
  19792. uint32_t m_bitlen, a_bitlen;
  19793. size_t mlen, alen, u;
  19794. m_bitlen = m[0];
  19795. mlen = (m_bitlen + 31) >> 5;
  19796. x[0] = m_bitlen;
  19797. if (m_bitlen == 0) {
  19798. return;
  19799. }
  19800. /*
  19801. * If the source is shorter, then simply copy all words from a[]
  19802. * and zero out the upper words.
  19803. */
  19804. a_bitlen = a[0];
  19805. alen = (a_bitlen + 31) >> 5;
  19806. if (a_bitlen < m_bitlen) {
  19807. memcpy(x + 1, a + 1, alen * sizeof *a);
  19808. for (u = alen; u < mlen; u ++) {
  19809. x[u + 1] = 0;
  19810. }
  19811. return;
  19812. }
  19813. /*
  19814. * The source length is at least equal to that of the modulus.
  19815. * We must thus copy N-1 words, and input the remaining words
  19816. * one by one.
  19817. */
  19818. memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a);
  19819. x[mlen] = 0;
  19820. for (u = 1 + alen - mlen; u > 0; u --) {
  19821. br_i31_muladd_small(x, a[u], m);
  19822. }
  19823. }
  19824. static void
  19825. br_i31_rshift(uint32_t *x, int count)
  19826. {
  19827. size_t u, len;
  19828. uint32_t r;
  19829. len = (x[0] + 31) >> 5;
  19830. if (len == 0) {
  19831. return;
  19832. }
  19833. r = x[1] >> count;
  19834. for (u = 2; u <= len; u ++) {
  19835. uint32_t w;
  19836. w = x[u];
  19837. x[u - 1] = ((w << (31 - count)) | r) & 0x7FFFFFFF;
  19838. r = w >> count;
  19839. }
  19840. x[len] = r;
  19841. }
  19842. static void
  19843. br_i31_decode_reduce(uint32_t *x,
  19844. const void *src, size_t len, const uint32_t *m)
  19845. {
  19846. uint32_t m_ebitlen, m_rbitlen;
  19847. size_t mblen, k;
  19848. const unsigned char *buf;
  19849. uint32_t acc;
  19850. int acc_len;
  19851. /*
  19852. * Get the encoded bit length.
  19853. */
  19854. m_ebitlen = m[0];
  19855. /*
  19856. * Special case for an invalid (null) modulus.
  19857. */
  19858. if (m_ebitlen == 0) {
  19859. x[0] = 0;
  19860. return;
  19861. }
  19862. /*
  19863. * Clear the destination.
  19864. */
  19865. br_i31_zero(x, m_ebitlen);
  19866. /*
  19867. * First decode directly as many bytes as possible. This requires
  19868. * computing the actual bit length.
  19869. */
  19870. m_rbitlen = m_ebitlen >> 5;
  19871. m_rbitlen = (m_ebitlen & 31) + (m_rbitlen << 5) - m_rbitlen;
  19872. mblen = (m_rbitlen + 7) >> 3;
  19873. k = mblen - 1;
  19874. if (k >= len) {
  19875. br_i31_decode(x, src, len);
  19876. x[0] = m_ebitlen;
  19877. return;
  19878. }
  19879. buf = (const unsigned char *) src;
  19880. br_i31_decode(x, buf, k);
  19881. x[0] = m_ebitlen;
  19882. /*
  19883. * Input remaining bytes, using 31-bit words.
  19884. */
  19885. acc = 0;
  19886. acc_len = 0;
  19887. while (k < len) {
  19888. uint32_t v;
  19889. v = buf[k ++];
  19890. if (acc_len >= 23) {
  19891. acc_len -= 23;
  19892. acc <<= (8 - acc_len);
  19893. acc |= v >> acc_len;
  19894. br_i31_muladd_small(x, acc, m);
  19895. acc = v & (0xFF >> (8 - acc_len));
  19896. } else {
  19897. acc = (acc << 8) | v;
  19898. acc_len += 8;
  19899. }
  19900. }
  19901. /*
  19902. * We may have some bits accumulated. We then perform a shift to
  19903. * be able to inject these bits as a full 31-bit word.
  19904. */
  19905. if (acc_len != 0) {
  19906. acc = (acc | (x[1] << acc_len)) & 0x7FFFFFFF;
  19907. br_i31_rshift(x, 31 - acc_len);
  19908. br_i31_muladd_small(x, acc, m);
  19909. }
  19910. }
  19911. static void
  19912. br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b)
  19913. {
  19914. size_t alen, blen, u;
  19915. uint32_t dl, dh;
  19916. alen = (a[0] + 31) >> 5;
  19917. blen = (b[0] + 31) >> 5;
  19918. /*
  19919. * We want to add the two bit lengths, but these are encoded,
  19920. * which requires some extra care.
  19921. */
  19922. dl = (a[0] & 31) + (b[0] & 31);
  19923. dh = (a[0] >> 5) + (b[0] >> 5);
  19924. d[0] = (dh << 5) + dl + (~(uint32_t)(dl - 31) >> 31);
  19925. for (u = 0; u < blen; u ++) {
  19926. uint32_t f;
  19927. size_t v;
  19928. /*
  19929. * Carry always fits on 31 bits; we want to keep it in a
  19930. * 32-bit register on 32-bit architectures (on a 64-bit
  19931. * architecture, cast down from 64 to 32 bits means
  19932. * clearing the high bits, which is not free; on a 32-bit
  19933. * architecture, the same operation really means ignoring
  19934. * the top register, which has negative or zero cost).
  19935. */
  19936. #if BR_64
  19937. uint64_t cc;
  19938. #else
  19939. uint32_t cc;
  19940. #endif
  19941. f = b[1 + u];
  19942. cc = 0;
  19943. for (v = 0; v < alen; v ++) {
  19944. uint64_t z;
  19945. z = (uint64_t)d[1 + u + v] + MUL31(f, a[1 + v]) + cc;
  19946. cc = z >> 31;
  19947. d[1 + u + v] = (uint32_t)z & 0x7FFFFFFF;
  19948. }
  19949. d[1 + u + alen] = (uint32_t)cc;
  19950. }
  19951. }
  19952. static void
  19953. br_i31_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y,
  19954. const uint32_t *m, uint32_t m0i)
  19955. {
  19956. /*
  19957. * Each outer loop iteration computes:
  19958. * d <- (d + xu*y + f*m) / 2^31
  19959. * We have xu <= 2^31-1 and f <= 2^31-1.
  19960. * Thus, if d <= 2*m-1 on input, then:
  19961. * 2*m-1 + 2*(2^31-1)*m <= (2^32)*m-1
  19962. * and the new d value is less than 2*m.
  19963. *
  19964. * We represent d over 31-bit words, with an extra word 'dh'
  19965. * which can thus be only 0 or 1.
  19966. */
  19967. size_t len, len4, u, v;
  19968. uint32_t dh;
  19969. len = (m[0] + 31) >> 5;
  19970. len4 = len & ~(size_t)3;
  19971. br_i31_zero(d, m[0]);
  19972. dh = 0;
  19973. for (u = 0; u < len; u ++) {
  19974. /*
  19975. * The carry for each operation fits on 32 bits:
  19976. * d[v+1] <= 2^31-1
  19977. * xu*y[v+1] <= (2^31-1)*(2^31-1)
  19978. * f*m[v+1] <= (2^31-1)*(2^31-1)
  19979. * r <= 2^32-1
  19980. * (2^31-1) + 2*(2^31-1)*(2^31-1) + (2^32-1) = 2^63 - 2^31
  19981. * After division by 2^31, the new r is then at most 2^32-1
  19982. *
  19983. * Using a 32-bit carry has performance benefits on 32-bit
  19984. * systems; however, on 64-bit architectures, we prefer to
  19985. * keep the carry (r) in a 64-bit register, thus avoiding some
  19986. * "clear high bits" operations.
  19987. */
  19988. uint32_t f, xu;
  19989. #if BR_64
  19990. uint64_t r;
  19991. #else
  19992. uint32_t r;
  19993. #endif
  19994. xu = x[u + 1];
  19995. f = MUL31_lo((d[1] + MUL31_lo(x[u + 1], y[1])), m0i);
  19996. r = 0;
  19997. for (v = 0; v < len4; v += 4) {
  19998. uint64_t z;
  19999. z = (uint64_t)d[v + 1] + MUL31(xu, y[v + 1])
  20000. + MUL31(f, m[v + 1]) + r;
  20001. r = z >> 31;
  20002. d[v + 0] = (uint32_t)z & 0x7FFFFFFF;
  20003. z = (uint64_t)d[v + 2] + MUL31(xu, y[v + 2])
  20004. + MUL31(f, m[v + 2]) + r;
  20005. r = z >> 31;
  20006. d[v + 1] = (uint32_t)z & 0x7FFFFFFF;
  20007. z = (uint64_t)d[v + 3] + MUL31(xu, y[v + 3])
  20008. + MUL31(f, m[v + 3]) + r;
  20009. r = z >> 31;
  20010. d[v + 2] = (uint32_t)z & 0x7FFFFFFF;
  20011. z = (uint64_t)d[v + 4] + MUL31(xu, y[v + 4])
  20012. + MUL31(f, m[v + 4]) + r;
  20013. r = z >> 31;
  20014. d[v + 3] = (uint32_t)z & 0x7FFFFFFF;
  20015. }
  20016. for (; v < len; v ++) {
  20017. uint64_t z;
  20018. z = (uint64_t)d[v + 1] + MUL31(xu, y[v + 1])
  20019. + MUL31(f, m[v + 1]) + r;
  20020. r = z >> 31;
  20021. d[v] = (uint32_t)z & 0x7FFFFFFF;
  20022. }
  20023. /*
  20024. * Since the new dh can only be 0 or 1, the addition of
  20025. * the old dh with the carry MUST fit on 32 bits, and
  20026. * thus can be done into dh itself.
  20027. */
  20028. dh += (uint32_t) r;
  20029. d[len] = dh & 0x7FFFFFFF;
  20030. dh >>= 31;
  20031. }
  20032. /*
  20033. * We must write back the bit length because it was overwritten in
  20034. * the loop (not overwriting it would require a test in the loop,
  20035. * which would yield bigger and slower code).
  20036. */
  20037. d[0] = m[0];
  20038. /*
  20039. * d[] may still be greater than m[] at that point; notably, the
  20040. * 'dh' word may be non-zero.
  20041. */
  20042. br_i31_sub(d, m, NEQ(dh, 0) | NOT(br_i31_sub(d, m, 0)));
  20043. }
  20044. static void
  20045. br_i31_to_monty(uint32_t *x, const uint32_t *m)
  20046. {
  20047. uint32_t k;
  20048. for (k = (m[0] + 31) >> 5; k > 0; k --) {
  20049. br_i31_muladd_small(x, 0, m);
  20050. }
  20051. }
  20052. static void
  20053. br_i31_modpow(uint32_t *x,
  20054. const unsigned char *e, size_t elen,
  20055. const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2)
  20056. {
  20057. size_t mlen;
  20058. uint32_t k;
  20059. /*
  20060. * 'mlen' is the length of m[] expressed in bytes (including
  20061. * the "bit length" first field).
  20062. */
  20063. mlen = ((m[0] + 63) >> 5) * sizeof m[0];
  20064. /*
  20065. * Throughout the algorithm:
  20066. * -- t1[] is in Montgomery representation; it contains x, x^2,
  20067. * x^4, x^8...
  20068. * -- The result is accumulated, in normal representation, in
  20069. * the x[] array.
  20070. * -- t2[] is used as destination buffer for each multiplication.
  20071. *
  20072. * Note that there is no need to call br_i32_from_monty().
  20073. */
  20074. memcpy(t1, x, mlen);
  20075. br_i31_to_monty(t1, m);
  20076. br_i31_zero(x, m[0]);
  20077. x[1] = 1;
  20078. for (k = 0; k < ((uint32_t)elen << 3); k ++) {
  20079. uint32_t ctl;
  20080. ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1;
  20081. br_i31_montymul(t2, x, t1, m, m0i);
  20082. CCOPY(ctl, x, t2, mlen);
  20083. br_i31_montymul(t2, t1, t1, m, m0i);
  20084. memcpy(t1, t2, mlen);
  20085. }
  20086. }
  20087. static size_t rsa_trim(const uint8_t **p, size_t n) {
  20088. while (n > 0 && **p == 0) (*p)++, n--;
  20089. return n;
  20090. }
  20091. static int rsa_i31_len(size_t nbytes) {
  20092. int z = (int) (nbytes * 8U);
  20093. int n = 1;
  20094. while (z > 0) z -= 31, n++;
  20095. return n + (n & 1);
  20096. }
  20097. static int rsa_fail(uint8_t *out, size_t outsz) {
  20098. mg_bzero(out, outsz);
  20099. return -1;
  20100. }
  20101. static int rsa_i31_eq(const uint32_t *a, const uint32_t *b) {
  20102. uint32_t r = a[0] ^ b[0];
  20103. size_t u, n = (a[0] + 31) >> 5;
  20104. for (u = 1; u <= n; u++) r |= a[u] ^ b[u];
  20105. return r == 0;
  20106. }
  20107. int mg_rsa_mod_pow(const uint8_t *mod, size_t modsz, const uint8_t *exp,
  20108. size_t expsz, const uint8_t *msg, size_t msgsz,
  20109. uint8_t *out, size_t outsz) {
  20110. uint32_t tmp[4 * BR_RSA_WORDS], *m = tmp, *x, *t1, *t2, m0i;
  20111. int fwlen;
  20112. if (out == NULL) return -1;
  20113. mg_bzero(out, outsz);
  20114. if (mod == NULL || exp == NULL || msg == NULL) return -1;
  20115. modsz = rsa_trim(&mod, modsz);
  20116. expsz = rsa_trim(&exp, expsz);
  20117. if (modsz < 256 || modsz > (BR_MAX_RSA_SIZE >> 3) || expsz == 0 ||
  20118. expsz > modsz || outsz != modsz || msgsz != modsz) {
  20119. return -1;
  20120. }
  20121. if (memcmp(msg, mod, modsz) >= 0) return -1;
  20122. fwlen = rsa_i31_len(modsz);
  20123. if (4 * (size_t) fwlen > sizeof(tmp) / sizeof(tmp[0])) return -1;
  20124. x = m + fwlen, t1 = x + fwlen, t2 = t1 + fwlen;
  20125. br_i31_decode(m, mod, modsz);
  20126. m0i = br_i31_ninv31(m[1]);
  20127. if ((m0i & 1) == 0) return rsa_fail((uint8_t *) tmp, sizeof(tmp));
  20128. br_i31_decode_reduce(x, msg, msgsz, m);
  20129. br_i31_modpow(x, exp, expsz, m, m0i, t1, t2);
  20130. br_i31_encode(out, outsz, x);
  20131. mg_bzero((uint8_t *) tmp, sizeof(tmp));
  20132. return 0;
  20133. }
  20134. int mg_rsa_crt_sign(const uint8_t *em, size_t em_len,
  20135. const uint8_t *dP, size_t dP_len,
  20136. const uint8_t *dQ, size_t dQ_len,
  20137. const uint8_t *p, size_t p_len,
  20138. const uint8_t *q, size_t q_len,
  20139. const uint8_t *qInv, size_t qInv_len,
  20140. uint8_t *signature, size_t sig_len) {
  20141. uint32_t tmp[8 * BR_RSA_FACTOR_WORDS], *mq = tmp, *s2, *mp, *s1, *t1, *t2;
  20142. uint32_t *c1, *c2;
  20143. uint32_t p0i, q0i;
  20144. size_t plen, qlen, xlen = sig_len, u;
  20145. int fwlen, ok = 0;
  20146. uint8_t x[BR_MAX_RSA_SIZE >> 3];
  20147. if (signature == NULL) return -1;
  20148. mg_bzero(signature, sig_len);
  20149. if (em == NULL || dP == NULL || dQ == NULL || p == NULL || q == NULL ||
  20150. qInv == NULL) {
  20151. return -1;
  20152. }
  20153. p_len = rsa_trim(&p, p_len);
  20154. q_len = rsa_trim(&q, q_len);
  20155. dP_len = rsa_trim(&dP, dP_len);
  20156. dQ_len = rsa_trim(&dQ, dQ_len);
  20157. qInv_len = rsa_trim(&qInv, qInv_len);
  20158. if (p_len < 128 || q_len < 128 || p_len > (BR_MAX_RSA_FACTOR >> 3) ||
  20159. q_len > (BR_MAX_RSA_FACTOR >> 3) || dP_len == 0 || dQ_len == 0 ||
  20160. qInv_len == 0 || dP_len > p_len || dQ_len > q_len ||
  20161. qInv_len > p_len || xlen > sizeof(x) || em_len == 0 ||
  20162. em_len > xlen) {
  20163. return -1;
  20164. }
  20165. plen = p_len, qlen = q_len;
  20166. fwlen = rsa_i31_len(plen > qlen ? plen : qlen);
  20167. if (8 * fwlen > (int) (sizeof(tmp) / sizeof(tmp[0]))) return -1;
  20168. s2 = mq + fwlen, mp = mq + 2 * fwlen, s1 = mq + 3 * fwlen;
  20169. t1 = mq + 4 * fwlen, t2 = mq + 5 * fwlen;
  20170. c1 = mq + 6 * fwlen, c2 = mq + 7 * fwlen;
  20171. memset(x, 0, xlen - em_len);
  20172. memcpy(x + xlen - em_len, em, em_len);
  20173. br_i31_decode(mq, q, qlen);
  20174. br_i31_decode(mp, p, plen);
  20175. q0i = br_i31_ninv31(mq[1]);
  20176. p0i = br_i31_ninv31(mp[1]);
  20177. if (((p0i & q0i) & 1) == 0) goto done;
  20178. memset(t2, 0, 2 * (size_t) fwlen * sizeof(*t2));
  20179. t2[0] = mq[0];
  20180. br_i31_mulacc(t2, mq, mp);
  20181. if (xlen != ((t2[0] + 7) >> 3)) goto done;
  20182. br_i31_encode(signature, xlen, t2);
  20183. for (u = xlen, ok = 0; u > 0; u--) {
  20184. uint32_t wn = signature[u - 1], wx = x[u - 1];
  20185. ok = (int) (((wx - (wn + (uint32_t) ok)) >> 8) & 1);
  20186. }
  20187. if (!ok) goto done;
  20188. ok = 0;
  20189. br_i31_decode_reduce(s2, x, xlen, mq);
  20190. br_i31_modpow(s2, dQ, dQ_len, mq, q0i, t1, t2);
  20191. br_i31_decode_reduce(s1, x, xlen, mp);
  20192. br_i31_modpow(s1, dP, dP_len, mp, p0i, t1, t2);
  20193. memcpy(c1, s1, (size_t) fwlen * sizeof(*s1));
  20194. memcpy(c2, s2, (size_t) fwlen * sizeof(*s2));
  20195. br_i31_reduce(t2, s2, mp);
  20196. br_i31_add(s1, mp, br_i31_sub(s1, t2, 1));
  20197. br_i31_to_monty(s1, mp);
  20198. br_i31_decode_reduce(t1, qInv, qInv_len, mp);
  20199. br_i31_montymul(t2, s1, t1, mp, p0i);
  20200. br_i31_mulacc(s2, mq, t2);
  20201. br_i31_reduce(t1, s2, mq);
  20202. ok = rsa_i31_eq(t1, c2);
  20203. br_i31_decode(mp, p, plen);
  20204. br_i31_reduce(t1, s2, mp);
  20205. ok &= rsa_i31_eq(t1, c1);
  20206. if (!ok) goto done;
  20207. ok = 0;
  20208. br_i31_encode(signature, sig_len, s2);
  20209. ok = 1;
  20210. done:
  20211. mg_bzero((uint8_t *) tmp, sizeof(tmp));
  20212. mg_bzero(x, sizeof(x));
  20213. if (!ok) return rsa_fail(signature, sig_len);
  20214. return 0;
  20215. }
  20216. // MGF1-SHA256 RFC 8017 B.2.1
  20217. static void mgf1_sha256(const uint8_t *seed, size_t seed_len,
  20218. uint8_t *mask, size_t mask_len) {
  20219. uint8_t cnt[4]; // I2OSP(counter, 4), big-endian
  20220. uint8_t tmp[32]; // one SHA-256 output block
  20221. uint32_t counter = 0;
  20222. size_t off = 0;
  20223. mg_sha256_ctx ctx;
  20224. while (off < mask_len) {
  20225. size_t n = mask_len - off;
  20226. if (n > 32) n = 32;
  20227. br_enc32be(cnt, counter);
  20228. mg_sha256_init(&ctx);
  20229. mg_sha256_update(&ctx, seed, seed_len);
  20230. mg_sha256_update(&ctx, cnt, 4);
  20231. mg_sha256_final(tmp, &ctx);
  20232. memcpy(mask + off, tmp, n);
  20233. off += n;
  20234. ++counter;
  20235. }
  20236. }
  20237. // Full RSASSA-PSS-VERIFY for rsa_pss_rsae_sha256 (RFC 8017 9.1.2)
  20238. // em - output of RSA public-key primitive (nlen bytes)
  20239. // nlen - modulus byte length (66 to 512)
  20240. // mhash - SHA-256 of the TLS 1.3 signed content (tls->sighash, 32 bytes)
  20241. static bool pss_verify_sha256(const uint8_t *em, size_t nlen, const uint8_t *mhash) {
  20242. // TLS 1.3: H_len = salt_len = 32
  20243. uint8_t db[479]; // unmasked DB after MGF1 XOR
  20244. uint8_t dbmask[479]; // MGF1-SHA256(H, db_len); nlen - hLen - 1 = 479
  20245. uint8_t Hprime[32]; // SHA-256(0x00*8 || mhash || salt)
  20246. uint8_t Mprime[8 + 32 + 32]; // 0*8 || mhash || salt
  20247. const uint8_t *H;
  20248. const uint8_t *salt;
  20249. size_t db_len;
  20250. size_t i;
  20251. uint8_t bad;
  20252. if (nlen < 32 + 32 + 2 || nlen - 32 - 1 > sizeof(db)) return -1;
  20253. if (em[nlen - 1] != 0xbc) return false;
  20254. if (em[0] & 0x80) return false;
  20255. db_len = nlen - 32 - 1;
  20256. H = em + db_len;
  20257. mgf1_sha256(H, 32, dbmask, db_len);
  20258. for (i = 0; i < db_len; i++) db[i] = em[i] ^ dbmask[i];
  20259. db[0] &= 0x7f; // DB = 0x00^(db_len-salt_len-1) || 0x01 || salt(salt_Len)
  20260. bad = 0;
  20261. for (i = 0; i < db_len - 32 - 1; i++) bad |= db[i];
  20262. bad |= db[db_len - 32 - 1] ^ 0x01;
  20263. if (bad != 0) return false;
  20264. salt = db + db_len - 32;
  20265. memset(Mprime, 0, 8);
  20266. memcpy(Mprime + 8, mhash, 32);
  20267. memcpy(Mprime + 8 + 32, salt, 32);
  20268. mg_sha256(Hprime, Mprime, sizeof(Mprime));
  20269. bad = 0;
  20270. for (i = 0; i < 32; i++) bad |= Hprime[i] ^ H[i];
  20271. return (bad == 0);
  20272. }
  20273. bool mg_rsa_verify(const uint8_t *em, size_t nlen, const uint8_t *mhash) {
  20274. return pss_verify_sha256(em, nlen, mhash);
  20275. }
  20276. // Full RSASSA-PKCS1-v1_5-VERIFY for rsa_pkcs1_sha256/sha384 (RFC 8017 9.2)
  20277. // em - output of RSA public-key primitive (nlen bytes)
  20278. // nlen - modulus byte length
  20279. // hash - SHA-256 or SHA-384 of the certificate TBS data
  20280. // hashlen - hash length, 32 for SHA-256 or 48 for SHA-384
  20281. static bool pkcs1_v15_verify(const uint8_t *em, size_t nlen,
  20282. const uint8_t *hash, size_t hashlen) {
  20283. static const uint8_t sha256_di[] = {
  20284. 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
  20285. 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
  20286. static const uint8_t sha384_di[] = {
  20287. 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
  20288. 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
  20289. const uint8_t *di = hashlen == 32 ? sha256_di : sha384_di;
  20290. size_t disz = hashlen == 32 ? sizeof(sha256_di) : sizeof(sha384_di);
  20291. size_t pslen, i;
  20292. uint8_t bad = 0;
  20293. if (hashlen != 32 && hashlen != 48) return false;
  20294. if (nlen < 3 + 8 + disz + hashlen) return false;
  20295. pslen = nlen - 3 - disz - hashlen;
  20296. bad |= (uint8_t) (em[0] | (em[1] ^ 0x01));
  20297. for (i = 0; i < pslen; i++) bad |= (uint8_t) (em[2 + i] ^ 0xff);
  20298. bad |= em[2 + pslen];
  20299. for (i = 0; i < disz; i++) bad |= (uint8_t) (em[3 + pslen + i] ^ di[i]);
  20300. for (i = 0; i < hashlen; i++)
  20301. bad |= (uint8_t) (em[3 + pslen + disz + i] ^ hash[i]);
  20302. return bad == 0;
  20303. }
  20304. bool mg_rsa_pkcs_verify(const uint8_t *em, size_t nlen, const uint8_t *hash,
  20305. size_t hashlen) {
  20306. return pkcs1_v15_verify(em, nlen, hash, hashlen);
  20307. }
  20308. #endif /* MG_TLS == MG_TLS_BUILTIN */
  20309. #ifdef MG_ENABLE_LINES
  20310. #line 1 "src/tls_uecc.c"
  20311. #endif
  20312. /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
  20313. #if MG_TLS == MG_TLS_BUILTIN || defined(MG_OTA_PUBLIC_KEY)
  20314. #ifndef MG_UECC_RNG_MAX_TRIES
  20315. #define MG_UECC_RNG_MAX_TRIES 64
  20316. #endif
  20317. #if MG_UECC_ENABLE_VLI_API
  20318. #define MG_UECC_VLI_API
  20319. #else
  20320. #define MG_UECC_VLI_API static
  20321. #endif
  20322. #if (MG_UECC_PLATFORM == mg_uecc_avr) || (MG_UECC_PLATFORM == mg_uecc_arm) || \
  20323. (MG_UECC_PLATFORM == mg_uecc_arm_thumb) || \
  20324. (MG_UECC_PLATFORM == mg_uecc_arm_thumb2)
  20325. #define MG_UECC_CONCATX(a, ...) a##__VA_ARGS__
  20326. #define MG_UECC_CONCAT(a, ...) MG_UECC_CONCATX(a, __VA_ARGS__)
  20327. #define STRX(a) #a
  20328. #define STR(a) STRX(a)
  20329. #define EVAL(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__))))
  20330. #define EVAL1(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__))))
  20331. #define EVAL2(...) EVAL3(EVAL3(EVAL3(EVAL3(__VA_ARGS__))))
  20332. #define EVAL3(...) EVAL4(EVAL4(EVAL4(EVAL4(__VA_ARGS__))))
  20333. #define EVAL4(...) __VA_ARGS__
  20334. #define DEC_1 0
  20335. #define DEC_2 1
  20336. #define DEC_3 2
  20337. #define DEC_4 3
  20338. #define DEC_5 4
  20339. #define DEC_6 5
  20340. #define DEC_7 6
  20341. #define DEC_8 7
  20342. #define DEC_9 8
  20343. #define DEC_10 9
  20344. #define DEC_11 10
  20345. #define DEC_12 11
  20346. #define DEC_13 12
  20347. #define DEC_14 13
  20348. #define DEC_15 14
  20349. #define DEC_16 15
  20350. #define DEC_17 16
  20351. #define DEC_18 17
  20352. #define DEC_19 18
  20353. #define DEC_20 19
  20354. #define DEC_21 20
  20355. #define DEC_22 21
  20356. #define DEC_23 22
  20357. #define DEC_24 23
  20358. #define DEC_25 24
  20359. #define DEC_26 25
  20360. #define DEC_27 26
  20361. #define DEC_28 27
  20362. #define DEC_29 28
  20363. #define DEC_30 29
  20364. #define DEC_31 30
  20365. #define DEC_32 31
  20366. #define DEC_(N) MG_UECC_CONCAT(DEC_, N)
  20367. #define SECOND_ARG(_, val, ...) val
  20368. #define SOME_CHECK_0 ~, 0
  20369. #define GET_SECOND_ARG(...) SECOND_ARG(__VA_ARGS__, SOME, )
  20370. #define SOME_OR_0(N) GET_SECOND_ARG(MG_UECC_CONCAT(SOME_CHECK_, N))
  20371. #define MG_UECC_EMPTY(...)
  20372. #define DEFER(...) __VA_ARGS__ MG_UECC_EMPTY()
  20373. #define REPEAT_NAME_0() REPEAT_0
  20374. #define REPEAT_NAME_SOME() REPEAT_SOME
  20375. #define REPEAT_0(...)
  20376. #define REPEAT_SOME(N, stuff) \
  20377. DEFER(MG_UECC_CONCAT(REPEAT_NAME_, SOME_OR_0(DEC_(N))))()(DEC_(N), stuff) stuff
  20378. #define REPEAT(N, stuff) EVAL(REPEAT_SOME(N, stuff))
  20379. #define REPEATM_NAME_0() REPEATM_0
  20380. #define REPEATM_NAME_SOME() REPEATM_SOME
  20381. #define REPEATM_0(...)
  20382. #define REPEATM_SOME(N, macro) \
  20383. macro(N) DEFER(MG_UECC_CONCAT(REPEATM_NAME_, SOME_OR_0(DEC_(N))))()(DEC_(N), macro)
  20384. #define REPEATM(N, macro) EVAL(REPEATM_SOME(N, macro))
  20385. #endif
  20386. //
  20387. #if (MG_UECC_WORD_SIZE == 1)
  20388. #if MG_UECC_SUPPORTS_secp160r1
  20389. #define MG_UECC_MAX_WORDS 21 /* Due to the size of curve_n. */
  20390. #endif
  20391. #if MG_UECC_SUPPORTS_secp192r1
  20392. #undef MG_UECC_MAX_WORDS
  20393. #define MG_UECC_MAX_WORDS 24
  20394. #endif
  20395. #if MG_UECC_SUPPORTS_secp224r1
  20396. #undef MG_UECC_MAX_WORDS
  20397. #define MG_UECC_MAX_WORDS 28
  20398. #endif
  20399. #if (MG_UECC_SUPPORTS_secp256r1 || MG_UECC_SUPPORTS_secp256k1)
  20400. #undef MG_UECC_MAX_WORDS
  20401. #define MG_UECC_MAX_WORDS 32
  20402. #endif
  20403. #if MG_UECC_SUPPORTS_secp384r1
  20404. #undef MG_UECC_MAX_WORDS
  20405. #define MG_UECC_MAX_WORDS 48
  20406. #endif
  20407. #elif (MG_UECC_WORD_SIZE == 4)
  20408. #if MG_UECC_SUPPORTS_secp160r1
  20409. #define MG_UECC_MAX_WORDS 6 /* Due to the size of curve_n. */
  20410. #endif
  20411. #if MG_UECC_SUPPORTS_secp192r1
  20412. #undef MG_UECC_MAX_WORDS
  20413. #define MG_UECC_MAX_WORDS 6
  20414. #endif
  20415. #if MG_UECC_SUPPORTS_secp224r1
  20416. #undef MG_UECC_MAX_WORDS
  20417. #define MG_UECC_MAX_WORDS 7
  20418. #endif
  20419. #if (MG_UECC_SUPPORTS_secp256r1 || MG_UECC_SUPPORTS_secp256k1)
  20420. #undef MG_UECC_MAX_WORDS
  20421. #define MG_UECC_MAX_WORDS 8
  20422. #endif
  20423. #if MG_UECC_SUPPORTS_secp384r1
  20424. #undef MG_UECC_MAX_WORDS
  20425. #define MG_UECC_MAX_WORDS 12
  20426. #endif
  20427. #elif (MG_UECC_WORD_SIZE == 8)
  20428. #if MG_UECC_SUPPORTS_secp160r1
  20429. #define MG_UECC_MAX_WORDS 3
  20430. #endif
  20431. #if MG_UECC_SUPPORTS_secp192r1
  20432. #undef MG_UECC_MAX_WORDS
  20433. #define MG_UECC_MAX_WORDS 3
  20434. #endif
  20435. #if MG_UECC_SUPPORTS_secp224r1
  20436. #undef MG_UECC_MAX_WORDS
  20437. #define MG_UECC_MAX_WORDS 4
  20438. #endif
  20439. #if (MG_UECC_SUPPORTS_secp256r1 || MG_UECC_SUPPORTS_secp256k1)
  20440. #undef MG_UECC_MAX_WORDS
  20441. #define MG_UECC_MAX_WORDS 4
  20442. #endif
  20443. #if MG_UECC_SUPPORTS_secp384r1
  20444. #undef MG_UECC_MAX_WORDS
  20445. #define MG_UECC_MAX_WORDS 6
  20446. #endif
  20447. #endif /* MG_UECC_WORD_SIZE */
  20448. #define BITS_TO_WORDS(num_bits) \
  20449. ((wordcount_t) ((num_bits + ((MG_UECC_WORD_SIZE * 8) - 1)) / \
  20450. (MG_UECC_WORD_SIZE * 8)))
  20451. #define BITS_TO_BYTES(num_bits) ((num_bits + 7) / 8)
  20452. struct MG_UECC_Curve_t {
  20453. wordcount_t num_words;
  20454. wordcount_t num_bytes;
  20455. bitcount_t num_n_bits;
  20456. mg_uecc_word_t p[MG_UECC_MAX_WORDS];
  20457. mg_uecc_word_t n[MG_UECC_MAX_WORDS];
  20458. mg_uecc_word_t G[MG_UECC_MAX_WORDS * 2];
  20459. mg_uecc_word_t b[MG_UECC_MAX_WORDS];
  20460. void (*double_jacobian)(mg_uecc_word_t *X1, mg_uecc_word_t *Y1,
  20461. mg_uecc_word_t *Z1, MG_UECC_Curve curve);
  20462. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  20463. void (*mod_sqrt)(mg_uecc_word_t *a, MG_UECC_Curve curve);
  20464. #endif
  20465. void (*x_side)(mg_uecc_word_t *result, const mg_uecc_word_t *x,
  20466. MG_UECC_Curve curve);
  20467. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  20468. void (*mmod_fast)(mg_uecc_word_t *result, mg_uecc_word_t *product);
  20469. #endif
  20470. };
  20471. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  20472. static void bcopy(uint8_t *dst, const uint8_t *src, unsigned num_bytes) {
  20473. while (0 != num_bytes) {
  20474. num_bytes--;
  20475. dst[num_bytes] = src[num_bytes];
  20476. }
  20477. }
  20478. #endif
  20479. static cmpresult_t mg_uecc_vli_cmp_unsafe(const mg_uecc_word_t *left,
  20480. const mg_uecc_word_t *right,
  20481. wordcount_t num_words);
  20482. #if (MG_UECC_PLATFORM == mg_uecc_arm || \
  20483. MG_UECC_PLATFORM == mg_uecc_arm_thumb || \
  20484. MG_UECC_PLATFORM == mg_uecc_arm_thumb2)
  20485. #endif
  20486. #if (MG_UECC_PLATFORM == mg_uecc_avr)
  20487. #endif
  20488. #ifndef asm_clear
  20489. #define asm_clear 0
  20490. #endif
  20491. #ifndef asm_set
  20492. #define asm_set 0
  20493. #endif
  20494. #ifndef asm_add
  20495. #define asm_add 0
  20496. #endif
  20497. #ifndef asm_sub
  20498. #define asm_sub 0
  20499. #endif
  20500. #ifndef asm_mult
  20501. #define asm_mult 0
  20502. #endif
  20503. #ifndef asm_rshift1
  20504. #define asm_rshift1 0
  20505. #endif
  20506. #ifndef asm_mmod_fast_secp256r1
  20507. #define asm_mmod_fast_secp256r1 0
  20508. #endif
  20509. static MG_UECC_RNG_Function g_rng_function = NULL;
  20510. void mg_uecc_set_rng(MG_UECC_RNG_Function rng_function) {
  20511. g_rng_function = rng_function;
  20512. }
  20513. MG_UECC_RNG_Function mg_uecc_get_rng(void) {
  20514. return g_rng_function;
  20515. }
  20516. int mg_uecc_curve_private_key_size(MG_UECC_Curve curve) {
  20517. return BITS_TO_BYTES(curve->num_n_bits);
  20518. }
  20519. int mg_uecc_curve_public_key_size(MG_UECC_Curve curve) {
  20520. return 2 * curve->num_bytes;
  20521. }
  20522. #if !asm_clear
  20523. MG_UECC_VLI_API void mg_uecc_vli_clear(mg_uecc_word_t *vli,
  20524. wordcount_t num_words) {
  20525. wordcount_t i;
  20526. for (i = 0; i < num_words; ++i) {
  20527. vli[i] = 0;
  20528. }
  20529. }
  20530. #endif /* !asm_clear */
  20531. /* Constant-time comparison to zero - secure way to compare long integers */
  20532. /* Returns 1 if vli == 0, 0 otherwise. */
  20533. MG_UECC_VLI_API mg_uecc_word_t mg_uecc_vli_isZero(const mg_uecc_word_t *vli,
  20534. wordcount_t num_words) {
  20535. mg_uecc_word_t bits = 0;
  20536. wordcount_t i;
  20537. for (i = 0; i < num_words; ++i) {
  20538. bits |= vli[i];
  20539. }
  20540. return (bits == 0);
  20541. }
  20542. /* Returns nonzero if bit 'bit' of vli is set. */
  20543. MG_UECC_VLI_API mg_uecc_word_t mg_uecc_vli_testBit(const mg_uecc_word_t *vli,
  20544. bitcount_t bit) {
  20545. return (vli[bit >> MG_UECC_WORD_BITS_SHIFT] &
  20546. ((mg_uecc_word_t) 1 << (bit & MG_UECC_WORD_BITS_MASK)));
  20547. }
  20548. /* Counts the number of words in vli. */
  20549. static wordcount_t vli_numDigits(const mg_uecc_word_t *vli,
  20550. const wordcount_t max_words) {
  20551. wordcount_t i;
  20552. /* Search from the end until we find a non-zero digit.
  20553. We do it in reverse because we expect that most digits will be nonzero. */
  20554. for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) {
  20555. }
  20556. return (i + 1);
  20557. }
  20558. /* Counts the number of bits required to represent vli. */
  20559. MG_UECC_VLI_API bitcount_t mg_uecc_vli_numBits(const mg_uecc_word_t *vli,
  20560. const wordcount_t max_words) {
  20561. mg_uecc_word_t i;
  20562. mg_uecc_word_t digit;
  20563. wordcount_t num_digits = vli_numDigits(vli, max_words);
  20564. if (num_digits == 0) {
  20565. return 0;
  20566. }
  20567. digit = vli[num_digits - 1];
  20568. for (i = 0; digit; ++i) {
  20569. digit >>= 1;
  20570. }
  20571. return (((bitcount_t) ((num_digits - 1) << MG_UECC_WORD_BITS_SHIFT)) +
  20572. (bitcount_t) i);
  20573. }
  20574. /* Sets dest = src. */
  20575. #if !asm_set
  20576. MG_UECC_VLI_API void mg_uecc_vli_set(mg_uecc_word_t *dest,
  20577. const mg_uecc_word_t *src,
  20578. wordcount_t num_words) {
  20579. wordcount_t i;
  20580. for (i = 0; i < num_words; ++i) {
  20581. dest[i] = src[i];
  20582. }
  20583. }
  20584. #endif /* !asm_set */
  20585. /* Returns sign of left - right. */
  20586. static cmpresult_t mg_uecc_vli_cmp_unsafe(const mg_uecc_word_t *left,
  20587. const mg_uecc_word_t *right,
  20588. wordcount_t num_words) {
  20589. wordcount_t i;
  20590. for (i = num_words - 1; i >= 0; --i) {
  20591. if (left[i] > right[i]) {
  20592. return 1;
  20593. } else if (left[i] < right[i]) {
  20594. return -1;
  20595. }
  20596. }
  20597. return 0;
  20598. }
  20599. /* Constant-time comparison function - secure way to compare long integers */
  20600. /* Returns one if left == right, zero otherwise. */
  20601. MG_UECC_VLI_API mg_uecc_word_t mg_uecc_vli_equal(const mg_uecc_word_t *left,
  20602. const mg_uecc_word_t *right,
  20603. wordcount_t num_words) {
  20604. mg_uecc_word_t diff = 0;
  20605. wordcount_t i;
  20606. for (i = num_words - 1; i >= 0; --i) {
  20607. diff |= (left[i] ^ right[i]);
  20608. }
  20609. return (diff == 0);
  20610. }
  20611. MG_UECC_VLI_API mg_uecc_word_t mg_uecc_vli_sub(mg_uecc_word_t *result,
  20612. const mg_uecc_word_t *left,
  20613. const mg_uecc_word_t *right,
  20614. wordcount_t num_words);
  20615. /* Returns sign of left - right, in constant time. */
  20616. MG_UECC_VLI_API cmpresult_t mg_uecc_vli_cmp(const mg_uecc_word_t *left,
  20617. const mg_uecc_word_t *right,
  20618. wordcount_t num_words) {
  20619. mg_uecc_word_t tmp[MG_UECC_MAX_WORDS];
  20620. mg_uecc_word_t neg = !!mg_uecc_vli_sub(tmp, left, right, num_words);
  20621. mg_uecc_word_t equal = mg_uecc_vli_isZero(tmp, num_words);
  20622. return (cmpresult_t) (!equal - 2 * neg);
  20623. }
  20624. /* Computes vli = vli >> 1. */
  20625. #if !asm_rshift1
  20626. MG_UECC_VLI_API void mg_uecc_vli_rshift1(mg_uecc_word_t *vli,
  20627. wordcount_t num_words) {
  20628. mg_uecc_word_t *end = vli;
  20629. mg_uecc_word_t carry = 0;
  20630. vli += num_words;
  20631. while (vli-- > end) {
  20632. mg_uecc_word_t temp = *vli;
  20633. *vli = (temp >> 1) | carry;
  20634. carry = temp << (MG_UECC_WORD_BITS - 1);
  20635. }
  20636. }
  20637. #endif /* !asm_rshift1 */
  20638. /* Computes result = left + right, returning carry. Can modify in place. */
  20639. #if !asm_add
  20640. MG_UECC_VLI_API mg_uecc_word_t mg_uecc_vli_add(mg_uecc_word_t *result,
  20641. const mg_uecc_word_t *left,
  20642. const mg_uecc_word_t *right,
  20643. wordcount_t num_words) {
  20644. mg_uecc_word_t carry = 0;
  20645. wordcount_t i;
  20646. for (i = 0; i < num_words; ++i) {
  20647. mg_uecc_word_t sum = left[i] + right[i] + carry;
  20648. if (sum != left[i]) {
  20649. carry = (sum < left[i]);
  20650. }
  20651. result[i] = sum;
  20652. }
  20653. return carry;
  20654. }
  20655. #endif /* !asm_add */
  20656. /* Computes result = left - right, returning borrow. Can modify in place. */
  20657. #if !asm_sub
  20658. MG_UECC_VLI_API mg_uecc_word_t mg_uecc_vli_sub(mg_uecc_word_t *result,
  20659. const mg_uecc_word_t *left,
  20660. const mg_uecc_word_t *right,
  20661. wordcount_t num_words) {
  20662. mg_uecc_word_t borrow = 0;
  20663. wordcount_t i;
  20664. for (i = 0; i < num_words; ++i) {
  20665. mg_uecc_word_t diff = left[i] - right[i] - borrow;
  20666. if (diff != left[i]) {
  20667. borrow = (diff > left[i]);
  20668. }
  20669. result[i] = diff;
  20670. }
  20671. return borrow;
  20672. }
  20673. #endif /* !asm_sub */
  20674. #if !asm_mult || (MG_UECC_SQUARE_FUNC && !asm_square) || \
  20675. (MG_UECC_SUPPORTS_secp256k1 && (MG_UECC_OPTIMIZATION_LEVEL > 0) && \
  20676. ((MG_UECC_WORD_SIZE == 1) || (MG_UECC_WORD_SIZE == 8)))
  20677. static void muladd(mg_uecc_word_t a, mg_uecc_word_t b, mg_uecc_word_t *r0,
  20678. mg_uecc_word_t *r1, mg_uecc_word_t *r2) {
  20679. #if MG_UECC_WORD_SIZE == 8
  20680. uint64_t a0 = a & 0xffffffff;
  20681. uint64_t a1 = a >> 32;
  20682. uint64_t b0 = b & 0xffffffff;
  20683. uint64_t b1 = b >> 32;
  20684. uint64_t i0 = a0 * b0;
  20685. uint64_t i1 = a0 * b1;
  20686. uint64_t i2 = a1 * b0;
  20687. uint64_t i3 = a1 * b1;
  20688. uint64_t p0, p1;
  20689. i2 += (i0 >> 32);
  20690. i2 += i1;
  20691. if (i2 < i1) { /* overflow */
  20692. i3 += 0x100000000;
  20693. }
  20694. p0 = (i0 & 0xffffffff) | (i2 << 32);
  20695. p1 = i3 + (i2 >> 32);
  20696. *r0 += p0;
  20697. *r1 += (p1 + (*r0 < p0));
  20698. *r2 += ((*r1 < p1) || (*r1 == p1 && *r0 < p0));
  20699. #else
  20700. mg_uecc_dword_t p = (mg_uecc_dword_t) a * b;
  20701. mg_uecc_dword_t r01 = ((mg_uecc_dword_t) (*r1) << MG_UECC_WORD_BITS) | *r0;
  20702. r01 += p;
  20703. *r2 += (r01 < p);
  20704. *r1 = (mg_uecc_word_t) (r01 >> MG_UECC_WORD_BITS);
  20705. *r0 = (mg_uecc_word_t) r01;
  20706. #endif
  20707. }
  20708. #endif /* muladd needed */
  20709. #if !asm_mult
  20710. MG_UECC_VLI_API void mg_uecc_vli_mult(mg_uecc_word_t *result,
  20711. const mg_uecc_word_t *left,
  20712. const mg_uecc_word_t *right,
  20713. wordcount_t num_words) {
  20714. mg_uecc_word_t r0 = 0;
  20715. mg_uecc_word_t r1 = 0;
  20716. mg_uecc_word_t r2 = 0;
  20717. wordcount_t i, k;
  20718. /* Compute each digit of result in sequence, maintaining the carries. */
  20719. for (k = 0; k < num_words; ++k) {
  20720. for (i = 0; i <= k; ++i) {
  20721. muladd(left[i], right[k - i], &r0, &r1, &r2);
  20722. }
  20723. result[k] = r0;
  20724. r0 = r1;
  20725. r1 = r2;
  20726. r2 = 0;
  20727. }
  20728. for (k = num_words; k < num_words * 2 - 1; ++k) {
  20729. for (i = (wordcount_t) ((k + 1) - num_words); i < num_words; ++i) {
  20730. muladd(left[i], right[k - i], &r0, &r1, &r2);
  20731. }
  20732. result[k] = r0;
  20733. r0 = r1;
  20734. r1 = r2;
  20735. r2 = 0;
  20736. }
  20737. result[num_words * 2 - 1] = r0;
  20738. }
  20739. #endif /* !asm_mult */
  20740. #if MG_UECC_SQUARE_FUNC
  20741. #if !asm_square
  20742. static void mul2add(mg_uecc_word_t a, mg_uecc_word_t b, mg_uecc_word_t *r0,
  20743. mg_uecc_word_t *r1, mg_uecc_word_t *r2) {
  20744. #if MG_UECC_WORD_SIZE == 8
  20745. uint64_t a0 = a & 0xffffffffull;
  20746. uint64_t a1 = a >> 32;
  20747. uint64_t b0 = b & 0xffffffffull;
  20748. uint64_t b1 = b >> 32;
  20749. uint64_t i0 = a0 * b0;
  20750. uint64_t i1 = a0 * b1;
  20751. uint64_t i2 = a1 * b0;
  20752. uint64_t i3 = a1 * b1;
  20753. uint64_t p0, p1;
  20754. i2 += (i0 >> 32);
  20755. i2 += i1;
  20756. if (i2 < i1) { /* overflow */
  20757. i3 += 0x100000000ull;
  20758. }
  20759. p0 = (i0 & 0xffffffffull) | (i2 << 32);
  20760. p1 = i3 + (i2 >> 32);
  20761. *r2 += (p1 >> 63);
  20762. p1 = (p1 << 1) | (p0 >> 63);
  20763. p0 <<= 1;
  20764. *r0 += p0;
  20765. *r1 += (p1 + (*r0 < p0));
  20766. *r2 += ((*r1 < p1) || (*r1 == p1 && *r0 < p0));
  20767. #else
  20768. mg_uecc_dword_t p = (mg_uecc_dword_t) a * b;
  20769. mg_uecc_dword_t r01 = ((mg_uecc_dword_t) (*r1) << MG_UECC_WORD_BITS) | *r0;
  20770. *r2 += (p >> (MG_UECC_WORD_BITS * 2 - 1));
  20771. p *= 2;
  20772. r01 += p;
  20773. *r2 += (r01 < p);
  20774. *r1 = r01 >> MG_UECC_WORD_BITS;
  20775. *r0 = (mg_uecc_word_t) r01;
  20776. #endif
  20777. }
  20778. MG_UECC_VLI_API void mg_uecc_vli_square(mg_uecc_word_t *result,
  20779. const mg_uecc_word_t *left,
  20780. wordcount_t num_words) {
  20781. mg_uecc_word_t r0 = 0;
  20782. mg_uecc_word_t r1 = 0;
  20783. mg_uecc_word_t r2 = 0;
  20784. wordcount_t i, k;
  20785. for (k = 0; k < num_words * 2 - 1; ++k) {
  20786. mg_uecc_word_t min = (k < num_words ? 0 : (k + 1) - num_words);
  20787. for (i = min; i <= k && i <= k - i; ++i) {
  20788. if (i < k - i) {
  20789. mul2add(left[i], left[k - i], &r0, &r1, &r2);
  20790. } else {
  20791. muladd(left[i], left[k - i], &r0, &r1, &r2);
  20792. }
  20793. }
  20794. result[k] = r0;
  20795. r0 = r1;
  20796. r1 = r2;
  20797. r2 = 0;
  20798. }
  20799. result[num_words * 2 - 1] = r0;
  20800. }
  20801. #endif /* !asm_square */
  20802. #else /* MG_UECC_SQUARE_FUNC */
  20803. #if MG_UECC_ENABLE_VLI_API
  20804. MG_UECC_VLI_API void mg_uecc_vli_square(mg_uecc_word_t *result,
  20805. const mg_uecc_word_t *left,
  20806. wordcount_t num_words) {
  20807. mg_uecc_vli_mult(result, left, left, num_words);
  20808. }
  20809. #endif /* MG_UECC_ENABLE_VLI_API */
  20810. #endif /* MG_UECC_SQUARE_FUNC */
  20811. /* Computes result = (left + right) % mod.
  20812. Assumes that left < mod and right < mod, and that result does not overlap
  20813. mod. */
  20814. MG_UECC_VLI_API void mg_uecc_vli_modAdd(mg_uecc_word_t *result,
  20815. const mg_uecc_word_t *left,
  20816. const mg_uecc_word_t *right,
  20817. const mg_uecc_word_t *mod,
  20818. wordcount_t num_words) {
  20819. mg_uecc_word_t carry = mg_uecc_vli_add(result, left, right, num_words);
  20820. if (carry || mg_uecc_vli_cmp_unsafe(mod, result, num_words) != 1) {
  20821. /* result > mod (result = mod + remainder), so subtract mod to get
  20822. * remainder. */
  20823. mg_uecc_vli_sub(result, result, mod, num_words);
  20824. }
  20825. }
  20826. /* Computes result = (left - right) % mod.
  20827. Assumes that left < mod and right < mod, and that result does not overlap
  20828. mod. */
  20829. MG_UECC_VLI_API void mg_uecc_vli_modSub(mg_uecc_word_t *result,
  20830. const mg_uecc_word_t *left,
  20831. const mg_uecc_word_t *right,
  20832. const mg_uecc_word_t *mod,
  20833. wordcount_t num_words) {
  20834. mg_uecc_word_t l_borrow = mg_uecc_vli_sub(result, left, right, num_words);
  20835. if (l_borrow) {
  20836. /* In this case, result == -diff == (max int) - diff. Since -x % d == d - x,
  20837. we can get the correct result from result + mod (with overflow). */
  20838. mg_uecc_vli_add(result, result, mod, num_words);
  20839. }
  20840. }
  20841. /* Computes result = product % mod, where product is 2N words long. */
  20842. /* Currently only designed to work for curve_p or curve_n. */
  20843. MG_UECC_VLI_API void mg_uecc_vli_mmod(mg_uecc_word_t *result,
  20844. mg_uecc_word_t *product,
  20845. const mg_uecc_word_t *mod,
  20846. wordcount_t num_words) {
  20847. mg_uecc_word_t mod_multiple[2 * MG_UECC_MAX_WORDS];
  20848. mg_uecc_word_t tmp[2 * MG_UECC_MAX_WORDS];
  20849. mg_uecc_word_t *v[2] = {tmp, product};
  20850. mg_uecc_word_t index;
  20851. /* Shift mod so its highest set bit is at the maximum position. */
  20852. bitcount_t shift = (bitcount_t) ((num_words * 2 * MG_UECC_WORD_BITS) -
  20853. mg_uecc_vli_numBits(mod, num_words));
  20854. wordcount_t word_shift = (wordcount_t) (shift / MG_UECC_WORD_BITS);
  20855. wordcount_t bit_shift = (wordcount_t) (shift % MG_UECC_WORD_BITS);
  20856. mg_uecc_word_t carry = 0;
  20857. mg_uecc_vli_clear(mod_multiple, word_shift);
  20858. if (bit_shift > 0) {
  20859. for (index = 0; index < (mg_uecc_word_t) num_words; ++index) {
  20860. mod_multiple[(mg_uecc_word_t) word_shift + index] =
  20861. (mg_uecc_word_t) (mod[index] << bit_shift) | carry;
  20862. carry = mod[index] >> (MG_UECC_WORD_BITS - bit_shift);
  20863. }
  20864. } else {
  20865. mg_uecc_vli_set(mod_multiple + word_shift, mod, num_words);
  20866. }
  20867. for (index = 1; shift >= 0; --shift) {
  20868. mg_uecc_word_t borrow = 0;
  20869. wordcount_t i;
  20870. for (i = 0; i < num_words * 2; ++i) {
  20871. mg_uecc_word_t diff = v[index][i] - mod_multiple[i] - borrow;
  20872. if (diff != v[index][i]) {
  20873. borrow = (diff > v[index][i]);
  20874. }
  20875. v[1 - index][i] = diff;
  20876. }
  20877. index = !(index ^ borrow); /* Swap the index if there was no borrow */
  20878. mg_uecc_vli_rshift1(mod_multiple, num_words);
  20879. mod_multiple[num_words - 1] |= mod_multiple[num_words]
  20880. << (MG_UECC_WORD_BITS - 1);
  20881. mg_uecc_vli_rshift1(mod_multiple + num_words, num_words);
  20882. }
  20883. mg_uecc_vli_set(result, v[index], num_words);
  20884. }
  20885. /* Computes result = (left * right) % mod. */
  20886. MG_UECC_VLI_API void mg_uecc_vli_modMult(mg_uecc_word_t *result,
  20887. const mg_uecc_word_t *left,
  20888. const mg_uecc_word_t *right,
  20889. const mg_uecc_word_t *mod,
  20890. wordcount_t num_words) {
  20891. mg_uecc_word_t product[2 * MG_UECC_MAX_WORDS];
  20892. mg_uecc_vli_mult(product, left, right, num_words);
  20893. mg_uecc_vli_mmod(result, product, mod, num_words);
  20894. }
  20895. MG_UECC_VLI_API void mg_uecc_vli_modMult_fast(mg_uecc_word_t *result,
  20896. const mg_uecc_word_t *left,
  20897. const mg_uecc_word_t *right,
  20898. MG_UECC_Curve curve) {
  20899. mg_uecc_word_t product[2 * MG_UECC_MAX_WORDS];
  20900. mg_uecc_vli_mult(product, left, right, curve->num_words);
  20901. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  20902. curve->mmod_fast(result, product);
  20903. #else
  20904. mg_uecc_vli_mmod(result, product, curve->p, curve->num_words);
  20905. #endif
  20906. }
  20907. #if MG_UECC_SQUARE_FUNC
  20908. #if MG_UECC_ENABLE_VLI_API
  20909. /* Computes result = left^2 % mod. */
  20910. MG_UECC_VLI_API void mg_uecc_vli_modSquare(mg_uecc_word_t *result,
  20911. const mg_uecc_word_t *left,
  20912. const mg_uecc_word_t *mod,
  20913. wordcount_t num_words) {
  20914. mg_uecc_word_t product[2 * MG_UECC_MAX_WORDS];
  20915. mg_uecc_vli_square(product, left, num_words);
  20916. mg_uecc_vli_mmod(result, product, mod, num_words);
  20917. }
  20918. #endif /* MG_UECC_ENABLE_VLI_API */
  20919. MG_UECC_VLI_API void mg_uecc_vli_modSquare_fast(mg_uecc_word_t *result,
  20920. const mg_uecc_word_t *left,
  20921. MG_UECC_Curve curve) {
  20922. mg_uecc_word_t product[2 * MG_UECC_MAX_WORDS];
  20923. mg_uecc_vli_square(product, left, curve->num_words);
  20924. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  20925. curve->mmod_fast(result, product);
  20926. #else
  20927. mg_uecc_vli_mmod(result, product, curve->p, curve->num_words);
  20928. #endif
  20929. }
  20930. #else /* MG_UECC_SQUARE_FUNC */
  20931. #if MG_UECC_ENABLE_VLI_API
  20932. MG_UECC_VLI_API void mg_uecc_vli_modSquare(mg_uecc_word_t *result,
  20933. const mg_uecc_word_t *left,
  20934. const mg_uecc_word_t *mod,
  20935. wordcount_t num_words) {
  20936. mg_uecc_vli_modMult(result, left, left, mod, num_words);
  20937. }
  20938. #endif /* MG_UECC_ENABLE_VLI_API */
  20939. MG_UECC_VLI_API void mg_uecc_vli_modSquare_fast(mg_uecc_word_t *result,
  20940. const mg_uecc_word_t *left,
  20941. MG_UECC_Curve curve) {
  20942. mg_uecc_vli_modMult_fast(result, left, left, curve);
  20943. }
  20944. #endif /* MG_UECC_SQUARE_FUNC */
  20945. #define EVEN(vli) (!(vli[0] & 1))
  20946. static void vli_modInv_update(mg_uecc_word_t *uv, const mg_uecc_word_t *mod,
  20947. wordcount_t num_words) {
  20948. mg_uecc_word_t carry = 0;
  20949. if (!EVEN(uv)) {
  20950. carry = mg_uecc_vli_add(uv, uv, mod, num_words);
  20951. }
  20952. mg_uecc_vli_rshift1(uv, num_words);
  20953. if (carry) {
  20954. uv[num_words - 1] |= HIGH_BIT_SET;
  20955. }
  20956. }
  20957. /* Computes result = (1 / input) % mod. All VLIs are the same size.
  20958. See "From Euclid's GCD to Montgomery Multiplication to the Great Divide" */
  20959. MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result,
  20960. const mg_uecc_word_t *input,
  20961. const mg_uecc_word_t *mod,
  20962. wordcount_t num_words) {
  20963. mg_uecc_word_t a[MG_UECC_MAX_WORDS], b[MG_UECC_MAX_WORDS],
  20964. u[MG_UECC_MAX_WORDS], v[MG_UECC_MAX_WORDS];
  20965. cmpresult_t cmpResult;
  20966. if (mg_uecc_vli_isZero(input, num_words)) {
  20967. mg_uecc_vli_clear(result, num_words);
  20968. return;
  20969. }
  20970. mg_uecc_vli_set(a, input, num_words);
  20971. mg_uecc_vli_set(b, mod, num_words);
  20972. mg_uecc_vli_clear(u, num_words);
  20973. u[0] = 1;
  20974. mg_uecc_vli_clear(v, num_words);
  20975. while ((cmpResult = mg_uecc_vli_cmp_unsafe(a, b, num_words)) != 0) {
  20976. if (EVEN(a)) {
  20977. mg_uecc_vli_rshift1(a, num_words);
  20978. vli_modInv_update(u, mod, num_words);
  20979. } else if (EVEN(b)) {
  20980. mg_uecc_vli_rshift1(b, num_words);
  20981. vli_modInv_update(v, mod, num_words);
  20982. } else if (cmpResult > 0) {
  20983. mg_uecc_vli_sub(a, a, b, num_words);
  20984. mg_uecc_vli_rshift1(a, num_words);
  20985. if (mg_uecc_vli_cmp_unsafe(u, v, num_words) < 0) {
  20986. mg_uecc_vli_add(u, u, mod, num_words);
  20987. }
  20988. mg_uecc_vli_sub(u, u, v, num_words);
  20989. vli_modInv_update(u, mod, num_words);
  20990. } else {
  20991. mg_uecc_vli_sub(b, b, a, num_words);
  20992. mg_uecc_vli_rshift1(b, num_words);
  20993. if (mg_uecc_vli_cmp_unsafe(v, u, num_words) < 0) {
  20994. mg_uecc_vli_add(v, v, mod, num_words);
  20995. }
  20996. mg_uecc_vli_sub(v, v, u, num_words);
  20997. vli_modInv_update(v, mod, num_words);
  20998. }
  20999. }
  21000. mg_uecc_vli_set(result, u, num_words);
  21001. }
  21002. /* ------ Point operations ------ */
  21003. /* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
  21004. #ifndef _UECC_CURVE_SPECIFIC_H_
  21005. #define _UECC_CURVE_SPECIFIC_H_
  21006. #define num_bytes_secp160r1 20
  21007. #define num_bytes_secp192r1 24
  21008. #define num_bytes_secp224r1 28
  21009. #define num_bytes_secp256r1 32
  21010. #define num_bytes_secp256k1 32
  21011. #define num_bytes_secp384r1 48
  21012. #if (MG_UECC_WORD_SIZE == 1)
  21013. #define num_words_secp160r1 20
  21014. #define num_words_secp192r1 24
  21015. #define num_words_secp224r1 28
  21016. #define num_words_secp256r1 32
  21017. #define num_words_secp256k1 32
  21018. #define num_words_secp384r1 48
  21019. #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) \
  21020. 0x##a, 0x##b, 0x##c, 0x##d, 0x##e, 0x##f, 0x##g, 0x##h
  21021. #define BYTES_TO_WORDS_4(a, b, c, d) 0x##a, 0x##b, 0x##c, 0x##d
  21022. #elif (MG_UECC_WORD_SIZE == 4)
  21023. #define num_words_secp160r1 5
  21024. #define num_words_secp192r1 6
  21025. #define num_words_secp224r1 7
  21026. #define num_words_secp256r1 8
  21027. #define num_words_secp256k1 8
  21028. #define num_words_secp384r1 12
  21029. #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e
  21030. #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a
  21031. #elif (MG_UECC_WORD_SIZE == 8)
  21032. #define num_words_secp160r1 3
  21033. #define num_words_secp192r1 3
  21034. #define num_words_secp224r1 4
  21035. #define num_words_secp256r1 4
  21036. #define num_words_secp256k1 4
  21037. #define num_words_secp384r1 6
  21038. #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##h##g##f##e##d##c##b##a##U
  21039. #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a##U
  21040. #endif /* MG_UECC_WORD_SIZE */
  21041. #if MG_UECC_SUPPORTS_secp160r1 || MG_UECC_SUPPORTS_secp192r1 || \
  21042. MG_UECC_SUPPORTS_secp224r1 || MG_UECC_SUPPORTS_secp256r1 || \
  21043. MG_UECC_SUPPORTS_secp384r1
  21044. static void double_jacobian_default(mg_uecc_word_t *X1, mg_uecc_word_t *Y1,
  21045. mg_uecc_word_t *Z1, MG_UECC_Curve curve) {
  21046. /* t1 = X, t2 = Y, t3 = Z */
  21047. mg_uecc_word_t t4[MG_UECC_MAX_WORDS];
  21048. mg_uecc_word_t t5[MG_UECC_MAX_WORDS];
  21049. wordcount_t num_words = curve->num_words;
  21050. if (mg_uecc_vli_isZero(Z1, num_words)) {
  21051. return;
  21052. }
  21053. mg_uecc_vli_modSquare_fast(t4, Y1, curve); /* t4 = y1^2 */
  21054. mg_uecc_vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */
  21055. mg_uecc_vli_modSquare_fast(t4, t4, curve); /* t4 = y1^4 */
  21056. mg_uecc_vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */
  21057. mg_uecc_vli_modSquare_fast(Z1, Z1, curve); /* t3 = z1^2 */
  21058. mg_uecc_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */
  21059. mg_uecc_vli_modAdd(Z1, Z1, Z1, curve->p, num_words); /* t3 = 2*z1^2 */
  21060. mg_uecc_vli_modSub(Z1, X1, Z1, curve->p, num_words); /* t3 = x1 - z1^2 */
  21061. mg_uecc_vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */
  21062. mg_uecc_vli_modAdd(Z1, X1, X1, curve->p,
  21063. num_words); /* t3 = 2*(x1^2 - z1^4) */
  21064. mg_uecc_vli_modAdd(X1, X1, Z1, curve->p,
  21065. num_words); /* t1 = 3*(x1^2 - z1^4) */
  21066. if (mg_uecc_vli_testBit(X1, 0)) {
  21067. mg_uecc_word_t l_carry = mg_uecc_vli_add(X1, X1, curve->p, num_words);
  21068. mg_uecc_vli_rshift1(X1, num_words);
  21069. X1[num_words - 1] |= l_carry << (MG_UECC_WORD_BITS - 1);
  21070. } else {
  21071. mg_uecc_vli_rshift1(X1, num_words);
  21072. }
  21073. /* t1 = 3/2*(x1^2 - z1^4) = B */
  21074. mg_uecc_vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */
  21075. mg_uecc_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - A */
  21076. mg_uecc_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - 2A = x3 */
  21077. mg_uecc_vli_modSub(t5, t5, Z1, curve->p, num_words); /* t5 = A - x3 */
  21078. mg_uecc_vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */
  21079. mg_uecc_vli_modSub(t4, X1, t4, curve->p,
  21080. num_words); /* t4 = B * (A - x3) - y1^4 = y3 */
  21081. mg_uecc_vli_set(X1, Z1, num_words);
  21082. mg_uecc_vli_set(Z1, Y1, num_words);
  21083. mg_uecc_vli_set(Y1, t4, num_words);
  21084. }
  21085. /* Computes result = x^3 + ax + b. result must not overlap x. */
  21086. static void x_side_default(mg_uecc_word_t *result, const mg_uecc_word_t *x,
  21087. MG_UECC_Curve curve) {
  21088. mg_uecc_word_t _3[MG_UECC_MAX_WORDS] = {3}; /* -a = 3 */
  21089. wordcount_t num_words = curve->num_words;
  21090. mg_uecc_vli_modSquare_fast(result, x, curve); /* r = x^2 */
  21091. mg_uecc_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */
  21092. mg_uecc_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */
  21093. mg_uecc_vli_modAdd(result, result, curve->b, curve->p,
  21094. num_words); /* r = x^3 - 3x + b */
  21095. }
  21096. #endif /* MG_UECC_SUPPORTS_secp... */
  21097. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  21098. #if MG_UECC_SUPPORTS_secp160r1 || MG_UECC_SUPPORTS_secp192r1 || \
  21099. MG_UECC_SUPPORTS_secp256r1 || MG_UECC_SUPPORTS_secp256k1 || \
  21100. MG_UECC_SUPPORTS_secp384r1
  21101. /* Compute a = sqrt(a) (mod curve_p). */
  21102. static void mod_sqrt_default(mg_uecc_word_t *a, MG_UECC_Curve curve) {
  21103. bitcount_t i;
  21104. mg_uecc_word_t p1[MG_UECC_MAX_WORDS] = {1};
  21105. mg_uecc_word_t l_result[MG_UECC_MAX_WORDS] = {1};
  21106. wordcount_t num_words = curve->num_words;
  21107. /* When curve->p == 3 (mod 4), we can compute
  21108. sqrt(a) = a^((curve->p + 1) / 4) (mod curve->p). */
  21109. mg_uecc_vli_add(p1, curve->p, p1, num_words); /* p1 = curve_p + 1 */
  21110. for (i = mg_uecc_vli_numBits(p1, num_words) - 1; i > 1; --i) {
  21111. mg_uecc_vli_modSquare_fast(l_result, l_result, curve);
  21112. if (mg_uecc_vli_testBit(p1, i)) {
  21113. mg_uecc_vli_modMult_fast(l_result, l_result, a, curve);
  21114. }
  21115. }
  21116. mg_uecc_vli_set(a, l_result, num_words);
  21117. }
  21118. #endif /* MG_UECC_SUPPORTS_secp... */
  21119. #endif /* MG_UECC_SUPPORT_COMPRESSED_POINT */
  21120. #if MG_UECC_SUPPORTS_secp160r1
  21121. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  21122. static void vli_mmod_fast_secp160r1(mg_uecc_word_t *result,
  21123. mg_uecc_word_t *product);
  21124. #endif
  21125. static const struct MG_UECC_Curve_t curve_secp160r1 = {
  21126. num_words_secp160r1,
  21127. num_bytes_secp160r1,
  21128. 161, /* num_n_bits */
  21129. {BYTES_TO_WORDS_8(FF, FF, FF, 7F, FF, FF, FF, FF),
  21130. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  21131. BYTES_TO_WORDS_4(FF, FF, FF, FF)},
  21132. {BYTES_TO_WORDS_8(57, 22, 75, CA, D3, AE, 27, F9),
  21133. BYTES_TO_WORDS_8(C8, F4, 01, 00, 00, 00, 00, 00),
  21134. BYTES_TO_WORDS_8(00, 00, 00, 00, 01, 00, 00, 00)},
  21135. {BYTES_TO_WORDS_8(82, FC, CB, 13, B9, 8B, C3, 68),
  21136. BYTES_TO_WORDS_8(89, 69, 64, 46, 28, 73, F5, 8E),
  21137. BYTES_TO_WORDS_4(68, B5, 96, 4A),
  21138. BYTES_TO_WORDS_8(32, FB, C5, 7A, 37, 51, 23, 04),
  21139. BYTES_TO_WORDS_8(12, C9, DC, 59, 7D, 94, 68, 31),
  21140. BYTES_TO_WORDS_4(55, 28, A6, 23)},
  21141. {BYTES_TO_WORDS_8(45, FA, 65, C5, AD, D4, D4, 81),
  21142. BYTES_TO_WORDS_8(9F, F8, AC, 65, 8B, 7A, BD, 54),
  21143. BYTES_TO_WORDS_4(FC, BE, 97, 1C)},
  21144. &double_jacobian_default,
  21145. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  21146. &mod_sqrt_default,
  21147. #endif
  21148. &x_side_default,
  21149. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  21150. &vli_mmod_fast_secp160r1
  21151. #endif
  21152. };
  21153. MG_UECC_Curve mg_uecc_secp160r1(void) {
  21154. return &curve_secp160r1;
  21155. }
  21156. #if (MG_UECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp160r1)
  21157. /* Computes result = product % curve_p
  21158. see http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf page 354
  21159. Note that this only works if log2(omega) < log2(p) / 2 */
  21160. static void omega_mult_secp160r1(mg_uecc_word_t *result,
  21161. const mg_uecc_word_t *right);
  21162. #if MG_UECC_WORD_SIZE == 8
  21163. static void vli_mmod_fast_secp160r1(mg_uecc_word_t *result,
  21164. mg_uecc_word_t *product) {
  21165. mg_uecc_word_t tmp[2 * num_words_secp160r1];
  21166. mg_uecc_word_t copy;
  21167. mg_uecc_vli_clear(tmp, num_words_secp160r1);
  21168. mg_uecc_vli_clear(tmp + num_words_secp160r1, num_words_secp160r1);
  21169. omega_mult_secp160r1(tmp,
  21170. product + num_words_secp160r1 - 1); /* (Rq, q) = q * c */
  21171. product[num_words_secp160r1 - 1] &= 0xffffffff;
  21172. copy = tmp[num_words_secp160r1 - 1];
  21173. tmp[num_words_secp160r1 - 1] &= 0xffffffff;
  21174. mg_uecc_vli_add(result, product, tmp,
  21175. num_words_secp160r1); /* (C, r) = r + q */
  21176. mg_uecc_vli_clear(product, num_words_secp160r1);
  21177. tmp[num_words_secp160r1 - 1] = copy;
  21178. omega_mult_secp160r1(product, tmp + num_words_secp160r1 - 1); /* Rq*c */
  21179. mg_uecc_vli_add(result, result, product,
  21180. num_words_secp160r1); /* (C1, r) = r + Rq*c */
  21181. while (mg_uecc_vli_cmp_unsafe(result, curve_secp160r1.p,
  21182. num_words_secp160r1) > 0) {
  21183. mg_uecc_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1);
  21184. }
  21185. }
  21186. static void omega_mult_secp160r1(uint64_t *result, const uint64_t *right) {
  21187. uint32_t carry;
  21188. unsigned i;
  21189. /* Multiply by (2^31 + 1). */
  21190. carry = 0;
  21191. for (i = 0; i < num_words_secp160r1; ++i) {
  21192. uint64_t tmp = (right[i] >> 32) | (right[i + 1] << 32);
  21193. result[i] = (tmp << 31) + tmp + carry;
  21194. carry = (tmp >> 33) + (result[i] < tmp || (carry && result[i] == tmp));
  21195. }
  21196. result[i] = carry;
  21197. }
  21198. #else
  21199. static void vli_mmod_fast_secp160r1(mg_uecc_word_t *result,
  21200. mg_uecc_word_t *product) {
  21201. mg_uecc_word_t tmp[2 * num_words_secp160r1];
  21202. mg_uecc_word_t carry;
  21203. mg_uecc_vli_clear(tmp, num_words_secp160r1);
  21204. mg_uecc_vli_clear(tmp + num_words_secp160r1, num_words_secp160r1);
  21205. omega_mult_secp160r1(tmp,
  21206. product + num_words_secp160r1); /* (Rq, q) = q * c */
  21207. carry = mg_uecc_vli_add(result, product, tmp,
  21208. num_words_secp160r1); /* (C, r) = r + q */
  21209. mg_uecc_vli_clear(product, num_words_secp160r1);
  21210. omega_mult_secp160r1(product, tmp + num_words_secp160r1); /* Rq*c */
  21211. carry += mg_uecc_vli_add(result, result, product,
  21212. num_words_secp160r1); /* (C1, r) = r + Rq*c */
  21213. while (carry > 0) {
  21214. --carry;
  21215. mg_uecc_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1);
  21216. }
  21217. if (mg_uecc_vli_cmp_unsafe(result, curve_secp160r1.p, num_words_secp160r1) >
  21218. 0) {
  21219. mg_uecc_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1);
  21220. }
  21221. }
  21222. #endif
  21223. #if MG_UECC_WORD_SIZE == 1
  21224. static void omega_mult_secp160r1(uint8_t *result, const uint8_t *right) {
  21225. uint8_t carry;
  21226. uint8_t i;
  21227. /* Multiply by (2^31 + 1). */
  21228. mg_uecc_vli_set(result + 4, right, num_words_secp160r1); /* 2^32 */
  21229. mg_uecc_vli_rshift1(result + 4, num_words_secp160r1); /* 2^31 */
  21230. result[3] = right[0] << 7; /* get last bit from shift */
  21231. carry = mg_uecc_vli_add(result, result, right,
  21232. num_words_secp160r1); /* 2^31 + 1 */
  21233. for (i = num_words_secp160r1; carry; ++i) {
  21234. uint16_t sum = (uint16_t) result[i] + carry;
  21235. result[i] = (uint8_t) sum;
  21236. carry = sum >> 8;
  21237. }
  21238. }
  21239. #elif MG_UECC_WORD_SIZE == 4
  21240. static void omega_mult_secp160r1(uint32_t *result, const uint32_t *right) {
  21241. uint32_t carry;
  21242. unsigned i;
  21243. /* Multiply by (2^31 + 1). */
  21244. mg_uecc_vli_set(result + 1, right, num_words_secp160r1); /* 2^32 */
  21245. mg_uecc_vli_rshift1(result + 1, num_words_secp160r1); /* 2^31 */
  21246. result[0] = right[0] << 31; /* get last bit from shift */
  21247. carry = mg_uecc_vli_add(result, result, right,
  21248. num_words_secp160r1); /* 2^31 + 1 */
  21249. for (i = num_words_secp160r1; carry; ++i) {
  21250. uint64_t sum = (uint64_t) result[i] + carry;
  21251. result[i] = (uint32_t) sum;
  21252. carry = sum >> 32;
  21253. }
  21254. }
  21255. #endif /* MG_UECC_WORD_SIZE */
  21256. #endif /* (MG_UECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp160r1) */
  21257. #endif /* MG_UECC_SUPPORTS_secp160r1 */
  21258. #if MG_UECC_SUPPORTS_secp192r1
  21259. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  21260. static void vli_mmod_fast_secp192r1(mg_uecc_word_t *result,
  21261. mg_uecc_word_t *product);
  21262. #endif
  21263. static const struct MG_UECC_Curve_t curve_secp192r1 = {
  21264. num_words_secp192r1,
  21265. num_bytes_secp192r1,
  21266. 192, /* num_n_bits */
  21267. {BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  21268. BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF),
  21269. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF)},
  21270. {BYTES_TO_WORDS_8(31, 28, D2, B4, B1, C9, 6B, 14),
  21271. BYTES_TO_WORDS_8(36, F8, DE, 99, FF, FF, FF, FF),
  21272. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF)},
  21273. {BYTES_TO_WORDS_8(12, 10, FF, 82, FD, 0A, FF, F4),
  21274. BYTES_TO_WORDS_8(00, 88, A1, 43, EB, 20, BF, 7C),
  21275. BYTES_TO_WORDS_8(F6, 90, 30, B0, 0E, A8, 8D, 18),
  21276. BYTES_TO_WORDS_8(11, 48, 79, 1E, A1, 77, F9, 73),
  21277. BYTES_TO_WORDS_8(D5, CD, 24, 6B, ED, 11, 10, 63),
  21278. BYTES_TO_WORDS_8(78, DA, C8, FF, 95, 2B, 19, 07)},
  21279. {BYTES_TO_WORDS_8(B1, B9, 46, C1, EC, DE, B8, FE),
  21280. BYTES_TO_WORDS_8(49, 30, 24, 72, AB, E9, A7, 0F),
  21281. BYTES_TO_WORDS_8(E7, 80, 9C, E5, 19, 05, 21, 64)},
  21282. &double_jacobian_default,
  21283. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  21284. &mod_sqrt_default,
  21285. #endif
  21286. &x_side_default,
  21287. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  21288. &vli_mmod_fast_secp192r1
  21289. #endif
  21290. };
  21291. MG_UECC_Curve mg_uecc_secp192r1(void) {
  21292. return &curve_secp192r1;
  21293. }
  21294. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  21295. /* Computes result = product % curve_p.
  21296. See algorithm 5 and 6 from http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf
  21297. */
  21298. #if MG_UECC_WORD_SIZE == 1
  21299. static void vli_mmod_fast_secp192r1(uint8_t *result, uint8_t *product) {
  21300. uint8_t tmp[num_words_secp192r1];
  21301. uint8_t carry;
  21302. mg_uecc_vli_set(result, product, num_words_secp192r1);
  21303. mg_uecc_vli_set(tmp, &product[24], num_words_secp192r1);
  21304. carry = mg_uecc_vli_add(result, result, tmp, num_words_secp192r1);
  21305. tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0;
  21306. tmp[8] = product[24];
  21307. tmp[9] = product[25];
  21308. tmp[10] = product[26];
  21309. tmp[11] = product[27];
  21310. tmp[12] = product[28];
  21311. tmp[13] = product[29];
  21312. tmp[14] = product[30];
  21313. tmp[15] = product[31];
  21314. tmp[16] = product[32];
  21315. tmp[17] = product[33];
  21316. tmp[18] = product[34];
  21317. tmp[19] = product[35];
  21318. tmp[20] = product[36];
  21319. tmp[21] = product[37];
  21320. tmp[22] = product[38];
  21321. tmp[23] = product[39];
  21322. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp192r1);
  21323. tmp[0] = tmp[8] = product[40];
  21324. tmp[1] = tmp[9] = product[41];
  21325. tmp[2] = tmp[10] = product[42];
  21326. tmp[3] = tmp[11] = product[43];
  21327. tmp[4] = tmp[12] = product[44];
  21328. tmp[5] = tmp[13] = product[45];
  21329. tmp[6] = tmp[14] = product[46];
  21330. tmp[7] = tmp[15] = product[47];
  21331. tmp[16] = tmp[17] = tmp[18] = tmp[19] = tmp[20] = tmp[21] = tmp[22] =
  21332. tmp[23] = 0;
  21333. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp192r1);
  21334. while (carry || mg_uecc_vli_cmp_unsafe(curve_secp192r1.p, result,
  21335. num_words_secp192r1) != 1) {
  21336. carry -=
  21337. mg_uecc_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1);
  21338. }
  21339. }
  21340. #elif MG_UECC_WORD_SIZE == 4
  21341. static void vli_mmod_fast_secp192r1(uint32_t *result, uint32_t *product) {
  21342. uint32_t tmp[num_words_secp192r1];
  21343. int carry;
  21344. mg_uecc_vli_set(result, product, num_words_secp192r1);
  21345. mg_uecc_vli_set(tmp, &product[6], num_words_secp192r1);
  21346. carry = mg_uecc_vli_add(result, result, tmp, num_words_secp192r1);
  21347. tmp[0] = tmp[1] = 0;
  21348. tmp[2] = product[6];
  21349. tmp[3] = product[7];
  21350. tmp[4] = product[8];
  21351. tmp[5] = product[9];
  21352. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp192r1);
  21353. tmp[0] = tmp[2] = product[10];
  21354. tmp[1] = tmp[3] = product[11];
  21355. tmp[4] = tmp[5] = 0;
  21356. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp192r1);
  21357. while (carry || mg_uecc_vli_cmp_unsafe(curve_secp192r1.p, result,
  21358. num_words_secp192r1) != 1) {
  21359. carry -=
  21360. mg_uecc_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1);
  21361. }
  21362. }
  21363. #else
  21364. static void vli_mmod_fast_secp192r1(uint64_t *result, uint64_t *product) {
  21365. uint64_t tmp[num_words_secp192r1];
  21366. int carry;
  21367. mg_uecc_vli_set(result, product, num_words_secp192r1);
  21368. mg_uecc_vli_set(tmp, &product[3], num_words_secp192r1);
  21369. carry = (int) mg_uecc_vli_add(result, result, tmp, num_words_secp192r1);
  21370. tmp[0] = 0;
  21371. tmp[1] = product[3];
  21372. tmp[2] = product[4];
  21373. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp192r1);
  21374. tmp[0] = tmp[1] = product[5];
  21375. tmp[2] = 0;
  21376. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp192r1);
  21377. while (carry || mg_uecc_vli_cmp_unsafe(curve_secp192r1.p, result,
  21378. num_words_secp192r1) != 1) {
  21379. carry -=
  21380. mg_uecc_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1);
  21381. }
  21382. }
  21383. #endif /* MG_UECC_WORD_SIZE */
  21384. #endif /* (MG_UECC_OPTIMIZATION_LEVEL > 0) */
  21385. #endif /* MG_UECC_SUPPORTS_secp192r1 */
  21386. #if MG_UECC_SUPPORTS_secp224r1
  21387. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  21388. static void mod_sqrt_secp224r1(mg_uecc_word_t *a, MG_UECC_Curve curve);
  21389. #endif
  21390. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  21391. static void vli_mmod_fast_secp224r1(mg_uecc_word_t *result,
  21392. mg_uecc_word_t *product);
  21393. #endif
  21394. static const struct MG_UECC_Curve_t curve_secp224r1 = {
  21395. num_words_secp224r1,
  21396. num_bytes_secp224r1,
  21397. 224, /* num_n_bits */
  21398. {BYTES_TO_WORDS_8(01, 00, 00, 00, 00, 00, 00, 00),
  21399. BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF),
  21400. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  21401. BYTES_TO_WORDS_4(FF, FF, FF, FF)},
  21402. {BYTES_TO_WORDS_8(3D, 2A, 5C, 5C, 45, 29, DD, 13),
  21403. BYTES_TO_WORDS_8(3E, F0, B8, E0, A2, 16, FF, FF),
  21404. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  21405. BYTES_TO_WORDS_4(FF, FF, FF, FF)},
  21406. {BYTES_TO_WORDS_8(21, 1D, 5C, 11, D6, 80, 32, 34),
  21407. BYTES_TO_WORDS_8(22, 11, C2, 56, D3, C1, 03, 4A),
  21408. BYTES_TO_WORDS_8(B9, 90, 13, 32, 7F, BF, B4, 6B),
  21409. BYTES_TO_WORDS_4(BD, 0C, 0E, B7),
  21410. BYTES_TO_WORDS_8(34, 7E, 00, 85, 99, 81, D5, 44),
  21411. BYTES_TO_WORDS_8(64, 47, 07, 5A, A0, 75, 43, CD),
  21412. BYTES_TO_WORDS_8(E6, DF, 22, 4C, FB, 23, F7, B5),
  21413. BYTES_TO_WORDS_4(88, 63, 37, BD)},
  21414. {BYTES_TO_WORDS_8(B4, FF, 55, 23, 43, 39, 0B, 27),
  21415. BYTES_TO_WORDS_8(BA, D8, BF, D7, B7, B0, 44, 50),
  21416. BYTES_TO_WORDS_8(56, 32, 41, F5, AB, B3, 04, 0C),
  21417. BYTES_TO_WORDS_4(85, 0A, 05, B4)},
  21418. &double_jacobian_default,
  21419. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  21420. &mod_sqrt_secp224r1,
  21421. #endif
  21422. &x_side_default,
  21423. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  21424. &vli_mmod_fast_secp224r1
  21425. #endif
  21426. };
  21427. MG_UECC_Curve mg_uecc_secp224r1(void) {
  21428. return &curve_secp224r1;
  21429. }
  21430. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  21431. /* Routine 3.2.4 RS; from http://www.nsa.gov/ia/_files/nist-routines.pdf */
  21432. static void mod_sqrt_secp224r1_rs(mg_uecc_word_t *d1, mg_uecc_word_t *e1,
  21433. mg_uecc_word_t *f1, const mg_uecc_word_t *d0,
  21434. const mg_uecc_word_t *e0,
  21435. const mg_uecc_word_t *f0) {
  21436. mg_uecc_word_t t[num_words_secp224r1];
  21437. mg_uecc_vli_modSquare_fast(t, d0, &curve_secp224r1); /* t <-- d0 ^ 2 */
  21438. mg_uecc_vli_modMult_fast(e1, d0, e0, &curve_secp224r1); /* e1 <-- d0 * e0 */
  21439. mg_uecc_vli_modAdd(d1, t, f0, curve_secp224r1.p,
  21440. num_words_secp224r1); /* d1 <-- t + f0 */
  21441. mg_uecc_vli_modAdd(e1, e1, e1, curve_secp224r1.p,
  21442. num_words_secp224r1); /* e1 <-- e1 + e1 */
  21443. mg_uecc_vli_modMult_fast(f1, t, f0, &curve_secp224r1); /* f1 <-- t * f0 */
  21444. mg_uecc_vli_modAdd(f1, f1, f1, curve_secp224r1.p,
  21445. num_words_secp224r1); /* f1 <-- f1 + f1 */
  21446. mg_uecc_vli_modAdd(f1, f1, f1, curve_secp224r1.p,
  21447. num_words_secp224r1); /* f1 <-- f1 + f1 */
  21448. }
  21449. /* Routine 3.2.5 RSS; from http://www.nsa.gov/ia/_files/nist-routines.pdf */
  21450. static void mod_sqrt_secp224r1_rss(mg_uecc_word_t *d1, mg_uecc_word_t *e1,
  21451. mg_uecc_word_t *f1, const mg_uecc_word_t *d0,
  21452. const mg_uecc_word_t *e0,
  21453. const mg_uecc_word_t *f0,
  21454. const bitcount_t j) {
  21455. bitcount_t i;
  21456. mg_uecc_vli_set(d1, d0, num_words_secp224r1); /* d1 <-- d0 */
  21457. mg_uecc_vli_set(e1, e0, num_words_secp224r1); /* e1 <-- e0 */
  21458. mg_uecc_vli_set(f1, f0, num_words_secp224r1); /* f1 <-- f0 */
  21459. for (i = 1; i <= j; i++) {
  21460. mod_sqrt_secp224r1_rs(d1, e1, f1, d1, e1, f1); /* RS (d1,e1,f1,d1,e1,f1) */
  21461. }
  21462. }
  21463. /* Routine 3.2.6 RM; from http://www.nsa.gov/ia/_files/nist-routines.pdf */
  21464. static void mod_sqrt_secp224r1_rm(mg_uecc_word_t *d2, mg_uecc_word_t *e2,
  21465. mg_uecc_word_t *f2, const mg_uecc_word_t *c,
  21466. const mg_uecc_word_t *d0,
  21467. const mg_uecc_word_t *e0,
  21468. const mg_uecc_word_t *d1,
  21469. const mg_uecc_word_t *e1) {
  21470. mg_uecc_word_t t1[num_words_secp224r1];
  21471. mg_uecc_word_t t2[num_words_secp224r1];
  21472. mg_uecc_vli_modMult_fast(t1, e0, e1, &curve_secp224r1); /* t1 <-- e0 * e1 */
  21473. mg_uecc_vli_modMult_fast(t1, t1, c, &curve_secp224r1); /* t1 <-- t1 * c */
  21474. /* t1 <-- p - t1 */
  21475. mg_uecc_vli_modSub(t1, curve_secp224r1.p, t1, curve_secp224r1.p,
  21476. num_words_secp224r1);
  21477. mg_uecc_vli_modMult_fast(t2, d0, d1, &curve_secp224r1); /* t2 <-- d0 * d1 */
  21478. mg_uecc_vli_modAdd(t2, t2, t1, curve_secp224r1.p,
  21479. num_words_secp224r1); /* t2 <-- t2 + t1 */
  21480. mg_uecc_vli_modMult_fast(t1, d0, e1, &curve_secp224r1); /* t1 <-- d0 * e1 */
  21481. mg_uecc_vli_modMult_fast(e2, d1, e0, &curve_secp224r1); /* e2 <-- d1 * e0 */
  21482. mg_uecc_vli_modAdd(e2, e2, t1, curve_secp224r1.p,
  21483. num_words_secp224r1); /* e2 <-- e2 + t1 */
  21484. mg_uecc_vli_modSquare_fast(f2, e2, &curve_secp224r1); /* f2 <-- e2^2 */
  21485. mg_uecc_vli_modMult_fast(f2, f2, c, &curve_secp224r1); /* f2 <-- f2 * c */
  21486. /* f2 <-- p - f2 */
  21487. mg_uecc_vli_modSub(f2, curve_secp224r1.p, f2, curve_secp224r1.p,
  21488. num_words_secp224r1);
  21489. mg_uecc_vli_set(d2, t2, num_words_secp224r1); /* d2 <-- t2 */
  21490. }
  21491. /* Routine 3.2.7 RP; from http://www.nsa.gov/ia/_files/nist-routines.pdf */
  21492. static void mod_sqrt_secp224r1_rp(mg_uecc_word_t *d1, mg_uecc_word_t *e1,
  21493. mg_uecc_word_t *f1, const mg_uecc_word_t *c,
  21494. const mg_uecc_word_t *r) {
  21495. wordcount_t i;
  21496. wordcount_t pow2i = 1;
  21497. mg_uecc_word_t d0[num_words_secp224r1];
  21498. mg_uecc_word_t e0[num_words_secp224r1] = {1}; /* e0 <-- 1 */
  21499. mg_uecc_word_t f0[num_words_secp224r1];
  21500. mg_uecc_vli_set(d0, r, num_words_secp224r1); /* d0 <-- r */
  21501. /* f0 <-- p - c */
  21502. mg_uecc_vli_modSub(f0, curve_secp224r1.p, c, curve_secp224r1.p,
  21503. num_words_secp224r1);
  21504. for (i = 0; i <= 6; i++) {
  21505. mod_sqrt_secp224r1_rss(d1, e1, f1, d0, e0, f0,
  21506. pow2i); /* RSS (d1,e1,f1,d0,e0,f0,2^i) */
  21507. mod_sqrt_secp224r1_rm(d1, e1, f1, c, d1, e1, d0,
  21508. e0); /* RM (d1,e1,f1,c,d1,e1,d0,e0) */
  21509. mg_uecc_vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */
  21510. mg_uecc_vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */
  21511. mg_uecc_vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */
  21512. pow2i *= 2;
  21513. }
  21514. }
  21515. /* Compute a = sqrt(a) (mod curve_p). */
  21516. /* Routine 3.2.8 mp_mod_sqrt_224; from
  21517. * http://www.nsa.gov/ia/_files/nist-routines.pdf */
  21518. static void mod_sqrt_secp224r1(mg_uecc_word_t *a, MG_UECC_Curve curve) {
  21519. (void) curve;
  21520. bitcount_t i;
  21521. mg_uecc_word_t e1[num_words_secp224r1];
  21522. mg_uecc_word_t f1[num_words_secp224r1];
  21523. mg_uecc_word_t d0[num_words_secp224r1];
  21524. mg_uecc_word_t e0[num_words_secp224r1];
  21525. mg_uecc_word_t f0[num_words_secp224r1];
  21526. mg_uecc_word_t d1[num_words_secp224r1];
  21527. /* s = a; using constant instead of random value */
  21528. mod_sqrt_secp224r1_rp(d0, e0, f0, a, a); /* RP (d0, e0, f0, c, s) */
  21529. mod_sqrt_secp224r1_rs(d1, e1, f1, d0, e0,
  21530. f0); /* RS (d1, e1, f1, d0, e0, f0) */
  21531. for (i = 1; i <= 95; i++) {
  21532. mg_uecc_vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */
  21533. mg_uecc_vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */
  21534. mg_uecc_vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */
  21535. mod_sqrt_secp224r1_rs(d1, e1, f1, d0, e0,
  21536. f0); /* RS (d1, e1, f1, d0, e0, f0) */
  21537. if (mg_uecc_vli_isZero(d1, num_words_secp224r1)) { /* if d1 == 0 */
  21538. break;
  21539. }
  21540. }
  21541. mg_uecc_vli_modInv(f1, e0, curve_secp224r1.p,
  21542. num_words_secp224r1); /* f1 <-- 1 / e0 */
  21543. mg_uecc_vli_modMult_fast(a, d0, f1, &curve_secp224r1); /* a <-- d0 / e0 */
  21544. }
  21545. #endif /* MG_UECC_SUPPORT_COMPRESSED_POINT */
  21546. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  21547. /* Computes result = product % curve_p
  21548. from http://www.nsa.gov/ia/_files/nist-routines.pdf */
  21549. #if MG_UECC_WORD_SIZE == 1
  21550. static void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) {
  21551. uint8_t tmp[num_words_secp224r1];
  21552. int8_t carry;
  21553. /* t */
  21554. mg_uecc_vli_set(result, product, num_words_secp224r1);
  21555. /* s1 */
  21556. tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0;
  21557. tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0;
  21558. tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0;
  21559. tmp[12] = product[28];
  21560. tmp[13] = product[29];
  21561. tmp[14] = product[30];
  21562. tmp[15] = product[31];
  21563. tmp[16] = product[32];
  21564. tmp[17] = product[33];
  21565. tmp[18] = product[34];
  21566. tmp[19] = product[35];
  21567. tmp[20] = product[36];
  21568. tmp[21] = product[37];
  21569. tmp[22] = product[38];
  21570. tmp[23] = product[39];
  21571. tmp[24] = product[40];
  21572. tmp[25] = product[41];
  21573. tmp[26] = product[42];
  21574. tmp[27] = product[43];
  21575. carry = mg_uecc_vli_add(result, result, tmp, num_words_secp224r1);
  21576. /* s2 */
  21577. tmp[12] = product[44];
  21578. tmp[13] = product[45];
  21579. tmp[14] = product[46];
  21580. tmp[15] = product[47];
  21581. tmp[16] = product[48];
  21582. tmp[17] = product[49];
  21583. tmp[18] = product[50];
  21584. tmp[19] = product[51];
  21585. tmp[20] = product[52];
  21586. tmp[21] = product[53];
  21587. tmp[22] = product[54];
  21588. tmp[23] = product[55];
  21589. tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0;
  21590. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp224r1);
  21591. /* d1 */
  21592. tmp[0] = product[28];
  21593. tmp[1] = product[29];
  21594. tmp[2] = product[30];
  21595. tmp[3] = product[31];
  21596. tmp[4] = product[32];
  21597. tmp[5] = product[33];
  21598. tmp[6] = product[34];
  21599. tmp[7] = product[35];
  21600. tmp[8] = product[36];
  21601. tmp[9] = product[37];
  21602. tmp[10] = product[38];
  21603. tmp[11] = product[39];
  21604. tmp[12] = product[40];
  21605. tmp[13] = product[41];
  21606. tmp[14] = product[42];
  21607. tmp[15] = product[43];
  21608. tmp[16] = product[44];
  21609. tmp[17] = product[45];
  21610. tmp[18] = product[46];
  21611. tmp[19] = product[47];
  21612. tmp[20] = product[48];
  21613. tmp[21] = product[49];
  21614. tmp[22] = product[50];
  21615. tmp[23] = product[51];
  21616. tmp[24] = product[52];
  21617. tmp[25] = product[53];
  21618. tmp[26] = product[54];
  21619. tmp[27] = product[55];
  21620. carry -= mg_uecc_vli_sub(result, result, tmp, num_words_secp224r1);
  21621. /* d2 */
  21622. tmp[0] = product[44];
  21623. tmp[1] = product[45];
  21624. tmp[2] = product[46];
  21625. tmp[3] = product[47];
  21626. tmp[4] = product[48];
  21627. tmp[5] = product[49];
  21628. tmp[6] = product[50];
  21629. tmp[7] = product[51];
  21630. tmp[8] = product[52];
  21631. tmp[9] = product[53];
  21632. tmp[10] = product[54];
  21633. tmp[11] = product[55];
  21634. tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0;
  21635. tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0;
  21636. tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0;
  21637. tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0;
  21638. carry -= mg_uecc_vli_sub(result, result, tmp, num_words_secp224r1);
  21639. if (carry < 0) {
  21640. do {
  21641. carry += mg_uecc_vli_add(result, result, curve_secp224r1.p,
  21642. num_words_secp224r1);
  21643. } while (carry < 0);
  21644. } else {
  21645. while (carry || mg_uecc_vli_cmp_unsafe(curve_secp224r1.p, result,
  21646. num_words_secp224r1) != 1) {
  21647. carry -= mg_uecc_vli_sub(result, result, curve_secp224r1.p,
  21648. num_words_secp224r1);
  21649. }
  21650. }
  21651. }
  21652. #elif MG_UECC_WORD_SIZE == 4
  21653. static void vli_mmod_fast_secp224r1(uint32_t *result, uint32_t *product) {
  21654. uint32_t tmp[num_words_secp224r1];
  21655. int carry;
  21656. /* t */
  21657. mg_uecc_vli_set(result, product, num_words_secp224r1);
  21658. /* s1 */
  21659. tmp[0] = tmp[1] = tmp[2] = 0;
  21660. tmp[3] = product[7];
  21661. tmp[4] = product[8];
  21662. tmp[5] = product[9];
  21663. tmp[6] = product[10];
  21664. carry = mg_uecc_vli_add(result, result, tmp, num_words_secp224r1);
  21665. /* s2 */
  21666. tmp[3] = product[11];
  21667. tmp[4] = product[12];
  21668. tmp[5] = product[13];
  21669. tmp[6] = 0;
  21670. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp224r1);
  21671. /* d1 */
  21672. tmp[0] = product[7];
  21673. tmp[1] = product[8];
  21674. tmp[2] = product[9];
  21675. tmp[3] = product[10];
  21676. tmp[4] = product[11];
  21677. tmp[5] = product[12];
  21678. tmp[6] = product[13];
  21679. carry -= mg_uecc_vli_sub(result, result, tmp, num_words_secp224r1);
  21680. /* d2 */
  21681. tmp[0] = product[11];
  21682. tmp[1] = product[12];
  21683. tmp[2] = product[13];
  21684. tmp[3] = tmp[4] = tmp[5] = tmp[6] = 0;
  21685. carry -= mg_uecc_vli_sub(result, result, tmp, num_words_secp224r1);
  21686. if (carry < 0) {
  21687. do {
  21688. carry += mg_uecc_vli_add(result, result, curve_secp224r1.p,
  21689. num_words_secp224r1);
  21690. } while (carry < 0);
  21691. } else {
  21692. while (carry || mg_uecc_vli_cmp_unsafe(curve_secp224r1.p, result,
  21693. num_words_secp224r1) != 1) {
  21694. carry -= mg_uecc_vli_sub(result, result, curve_secp224r1.p,
  21695. num_words_secp224r1);
  21696. }
  21697. }
  21698. }
  21699. #else
  21700. static void vli_mmod_fast_secp224r1(uint64_t *result, uint64_t *product) {
  21701. uint64_t tmp[num_words_secp224r1];
  21702. int carry = 0;
  21703. /* t */
  21704. mg_uecc_vli_set(result, product, num_words_secp224r1);
  21705. result[num_words_secp224r1 - 1] &= 0xffffffff;
  21706. /* s1 */
  21707. tmp[0] = 0;
  21708. tmp[1] = product[3] & 0xffffffff00000000ull;
  21709. tmp[2] = product[4];
  21710. tmp[3] = product[5] & 0xffffffff;
  21711. mg_uecc_vli_add(result, result, tmp, num_words_secp224r1);
  21712. /* s2 */
  21713. tmp[1] = product[5] & 0xffffffff00000000ull;
  21714. tmp[2] = product[6];
  21715. tmp[3] = 0;
  21716. mg_uecc_vli_add(result, result, tmp, num_words_secp224r1);
  21717. /* d1 */
  21718. tmp[0] = (product[3] >> 32) | (product[4] << 32);
  21719. tmp[1] = (product[4] >> 32) | (product[5] << 32);
  21720. tmp[2] = (product[5] >> 32) | (product[6] << 32);
  21721. tmp[3] = product[6] >> 32;
  21722. carry -= mg_uecc_vli_sub(result, result, tmp, num_words_secp224r1);
  21723. /* d2 */
  21724. tmp[0] = (product[5] >> 32) | (product[6] << 32);
  21725. tmp[1] = product[6] >> 32;
  21726. tmp[2] = tmp[3] = 0;
  21727. carry -= mg_uecc_vli_sub(result, result, tmp, num_words_secp224r1);
  21728. if (carry < 0) {
  21729. do {
  21730. carry += mg_uecc_vli_add(result, result, curve_secp224r1.p,
  21731. num_words_secp224r1);
  21732. } while (carry < 0);
  21733. } else {
  21734. while (mg_uecc_vli_cmp_unsafe(curve_secp224r1.p, result,
  21735. num_words_secp224r1) != 1) {
  21736. mg_uecc_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1);
  21737. }
  21738. }
  21739. }
  21740. #endif /* MG_UECC_WORD_SIZE */
  21741. #endif /* (MG_UECC_OPTIMIZATION_LEVEL > 0) */
  21742. #endif /* MG_UECC_SUPPORTS_secp224r1 */
  21743. #if MG_UECC_SUPPORTS_secp256r1
  21744. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  21745. static void vli_mmod_fast_secp256r1(mg_uecc_word_t *result,
  21746. mg_uecc_word_t *product);
  21747. #endif
  21748. static const struct MG_UECC_Curve_t curve_secp256r1 = {
  21749. num_words_secp256r1,
  21750. num_bytes_secp256r1,
  21751. 256, /* num_n_bits */
  21752. {BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  21753. BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00),
  21754. BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00),
  21755. BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF)},
  21756. {BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3),
  21757. BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC),
  21758. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  21759. BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF)},
  21760. {BYTES_TO_WORDS_8(96, C2, 98, D8, 45, 39, A1, F4),
  21761. BYTES_TO_WORDS_8(A0, 33, EB, 2D, 81, 7D, 03, 77),
  21762. BYTES_TO_WORDS_8(F2, 40, A4, 63, E5, E6, BC, F8),
  21763. BYTES_TO_WORDS_8(47, 42, 2C, E1, F2, D1, 17, 6B),
  21764. BYTES_TO_WORDS_8(F5, 51, BF, 37, 68, 40, B6, CB),
  21765. BYTES_TO_WORDS_8(CE, 5E, 31, 6B, 57, 33, CE, 2B),
  21766. BYTES_TO_WORDS_8(16, 9E, 0F, 7C, 4A, EB, E7, 8E),
  21767. BYTES_TO_WORDS_8(9B, 7F, 1A, FE, E2, 42, E3, 4F)},
  21768. {BYTES_TO_WORDS_8(4B, 60, D2, 27, 3E, 3C, CE, 3B),
  21769. BYTES_TO_WORDS_8(F6, B0, 53, CC, B0, 06, 1D, 65),
  21770. BYTES_TO_WORDS_8(BC, 86, 98, 76, 55, BD, EB, B3),
  21771. BYTES_TO_WORDS_8(E7, 93, 3A, AA, D8, 35, C6, 5A)},
  21772. &double_jacobian_default,
  21773. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  21774. &mod_sqrt_default,
  21775. #endif
  21776. &x_side_default,
  21777. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  21778. &vli_mmod_fast_secp256r1
  21779. #endif
  21780. };
  21781. MG_UECC_Curve mg_uecc_secp256r1(void) {
  21782. return &curve_secp256r1;
  21783. }
  21784. #if (MG_UECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256r1)
  21785. /* Computes result = product % curve_p
  21786. from http://www.nsa.gov/ia/_files/nist-routines.pdf */
  21787. #if MG_UECC_WORD_SIZE == 1
  21788. static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) {
  21789. uint8_t tmp[num_words_secp256r1];
  21790. int8_t carry;
  21791. /* t */
  21792. mg_uecc_vli_set(result, product, num_words_secp256r1);
  21793. /* s1 */
  21794. tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0;
  21795. tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0;
  21796. tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0;
  21797. tmp[12] = product[44];
  21798. tmp[13] = product[45];
  21799. tmp[14] = product[46];
  21800. tmp[15] = product[47];
  21801. tmp[16] = product[48];
  21802. tmp[17] = product[49];
  21803. tmp[18] = product[50];
  21804. tmp[19] = product[51];
  21805. tmp[20] = product[52];
  21806. tmp[21] = product[53];
  21807. tmp[22] = product[54];
  21808. tmp[23] = product[55];
  21809. tmp[24] = product[56];
  21810. tmp[25] = product[57];
  21811. tmp[26] = product[58];
  21812. tmp[27] = product[59];
  21813. tmp[28] = product[60];
  21814. tmp[29] = product[61];
  21815. tmp[30] = product[62];
  21816. tmp[31] = product[63];
  21817. carry = mg_uecc_vli_add(tmp, tmp, tmp, num_words_secp256r1);
  21818. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  21819. /* s2 */
  21820. tmp[12] = product[48];
  21821. tmp[13] = product[49];
  21822. tmp[14] = product[50];
  21823. tmp[15] = product[51];
  21824. tmp[16] = product[52];
  21825. tmp[17] = product[53];
  21826. tmp[18] = product[54];
  21827. tmp[19] = product[55];
  21828. tmp[20] = product[56];
  21829. tmp[21] = product[57];
  21830. tmp[22] = product[58];
  21831. tmp[23] = product[59];
  21832. tmp[24] = product[60];
  21833. tmp[25] = product[61];
  21834. tmp[26] = product[62];
  21835. tmp[27] = product[63];
  21836. tmp[28] = tmp[29] = tmp[30] = tmp[31] = 0;
  21837. carry += mg_uecc_vli_add(tmp, tmp, tmp, num_words_secp256r1);
  21838. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  21839. /* s3 */
  21840. tmp[0] = product[32];
  21841. tmp[1] = product[33];
  21842. tmp[2] = product[34];
  21843. tmp[3] = product[35];
  21844. tmp[4] = product[36];
  21845. tmp[5] = product[37];
  21846. tmp[6] = product[38];
  21847. tmp[7] = product[39];
  21848. tmp[8] = product[40];
  21849. tmp[9] = product[41];
  21850. tmp[10] = product[42];
  21851. tmp[11] = product[43];
  21852. tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0;
  21853. tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0;
  21854. tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0;
  21855. tmp[24] = product[56];
  21856. tmp[25] = product[57];
  21857. tmp[26] = product[58];
  21858. tmp[27] = product[59];
  21859. tmp[28] = product[60];
  21860. tmp[29] = product[61];
  21861. tmp[30] = product[62];
  21862. tmp[31] = product[63];
  21863. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  21864. /* s4 */
  21865. tmp[0] = product[36];
  21866. tmp[1] = product[37];
  21867. tmp[2] = product[38];
  21868. tmp[3] = product[39];
  21869. tmp[4] = product[40];
  21870. tmp[5] = product[41];
  21871. tmp[6] = product[42];
  21872. tmp[7] = product[43];
  21873. tmp[8] = product[44];
  21874. tmp[9] = product[45];
  21875. tmp[10] = product[46];
  21876. tmp[11] = product[47];
  21877. tmp[12] = product[52];
  21878. tmp[13] = product[53];
  21879. tmp[14] = product[54];
  21880. tmp[15] = product[55];
  21881. tmp[16] = product[56];
  21882. tmp[17] = product[57];
  21883. tmp[18] = product[58];
  21884. tmp[19] = product[59];
  21885. tmp[20] = product[60];
  21886. tmp[21] = product[61];
  21887. tmp[22] = product[62];
  21888. tmp[23] = product[63];
  21889. tmp[24] = product[52];
  21890. tmp[25] = product[53];
  21891. tmp[26] = product[54];
  21892. tmp[27] = product[55];
  21893. tmp[28] = product[32];
  21894. tmp[29] = product[33];
  21895. tmp[30] = product[34];
  21896. tmp[31] = product[35];
  21897. carry += mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  21898. /* d1 */
  21899. tmp[0] = product[44];
  21900. tmp[1] = product[45];
  21901. tmp[2] = product[46];
  21902. tmp[3] = product[47];
  21903. tmp[4] = product[48];
  21904. tmp[5] = product[49];
  21905. tmp[6] = product[50];
  21906. tmp[7] = product[51];
  21907. tmp[8] = product[52];
  21908. tmp[9] = product[53];
  21909. tmp[10] = product[54];
  21910. tmp[11] = product[55];
  21911. tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0;
  21912. tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0;
  21913. tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0;
  21914. tmp[24] = product[32];
  21915. tmp[25] = product[33];
  21916. tmp[26] = product[34];
  21917. tmp[27] = product[35];
  21918. tmp[28] = product[40];
  21919. tmp[29] = product[41];
  21920. tmp[30] = product[42];
  21921. tmp[31] = product[43];
  21922. carry -= mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  21923. /* d2 */
  21924. tmp[0] = product[48];
  21925. tmp[1] = product[49];
  21926. tmp[2] = product[50];
  21927. tmp[3] = product[51];
  21928. tmp[4] = product[52];
  21929. tmp[5] = product[53];
  21930. tmp[6] = product[54];
  21931. tmp[7] = product[55];
  21932. tmp[8] = product[56];
  21933. tmp[9] = product[57];
  21934. tmp[10] = product[58];
  21935. tmp[11] = product[59];
  21936. tmp[12] = product[60];
  21937. tmp[13] = product[61];
  21938. tmp[14] = product[62];
  21939. tmp[15] = product[63];
  21940. tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0;
  21941. tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0;
  21942. tmp[24] = product[36];
  21943. tmp[25] = product[37];
  21944. tmp[26] = product[38];
  21945. tmp[27] = product[39];
  21946. tmp[28] = product[44];
  21947. tmp[29] = product[45];
  21948. tmp[30] = product[46];
  21949. tmp[31] = product[47];
  21950. carry -= mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  21951. /* d3 */
  21952. tmp[0] = product[52];
  21953. tmp[1] = product[53];
  21954. tmp[2] = product[54];
  21955. tmp[3] = product[55];
  21956. tmp[4] = product[56];
  21957. tmp[5] = product[57];
  21958. tmp[6] = product[58];
  21959. tmp[7] = product[59];
  21960. tmp[8] = product[60];
  21961. tmp[9] = product[61];
  21962. tmp[10] = product[62];
  21963. tmp[11] = product[63];
  21964. tmp[12] = product[32];
  21965. tmp[13] = product[33];
  21966. tmp[14] = product[34];
  21967. tmp[15] = product[35];
  21968. tmp[16] = product[36];
  21969. tmp[17] = product[37];
  21970. tmp[18] = product[38];
  21971. tmp[19] = product[39];
  21972. tmp[20] = product[40];
  21973. tmp[21] = product[41];
  21974. tmp[22] = product[42];
  21975. tmp[23] = product[43];
  21976. tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0;
  21977. tmp[28] = product[48];
  21978. tmp[29] = product[49];
  21979. tmp[30] = product[50];
  21980. tmp[31] = product[51];
  21981. carry -= mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  21982. /* d4 */
  21983. tmp[0] = product[56];
  21984. tmp[1] = product[57];
  21985. tmp[2] = product[58];
  21986. tmp[3] = product[59];
  21987. tmp[4] = product[60];
  21988. tmp[5] = product[61];
  21989. tmp[6] = product[62];
  21990. tmp[7] = product[63];
  21991. tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0;
  21992. tmp[12] = product[36];
  21993. tmp[13] = product[37];
  21994. tmp[14] = product[38];
  21995. tmp[15] = product[39];
  21996. tmp[16] = product[40];
  21997. tmp[17] = product[41];
  21998. tmp[18] = product[42];
  21999. tmp[19] = product[43];
  22000. tmp[20] = product[44];
  22001. tmp[21] = product[45];
  22002. tmp[22] = product[46];
  22003. tmp[23] = product[47];
  22004. tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0;
  22005. tmp[28] = product[52];
  22006. tmp[29] = product[53];
  22007. tmp[30] = product[54];
  22008. tmp[31] = product[55];
  22009. carry -= mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  22010. if (carry < 0) {
  22011. do {
  22012. carry += mg_uecc_vli_add(result, result, curve_secp256r1.p,
  22013. num_words_secp256r1);
  22014. } while (carry < 0);
  22015. } else {
  22016. while (carry || mg_uecc_vli_cmp_unsafe(curve_secp256r1.p, result,
  22017. num_words_secp256r1) != 1) {
  22018. carry -= mg_uecc_vli_sub(result, result, curve_secp256r1.p,
  22019. num_words_secp256r1);
  22020. }
  22021. }
  22022. }
  22023. #elif MG_UECC_WORD_SIZE == 4
  22024. static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) {
  22025. uint32_t tmp[num_words_secp256r1];
  22026. int carry;
  22027. /* t */
  22028. mg_uecc_vli_set(result, product, num_words_secp256r1);
  22029. /* s1 */
  22030. tmp[0] = tmp[1] = tmp[2] = 0;
  22031. tmp[3] = product[11];
  22032. tmp[4] = product[12];
  22033. tmp[5] = product[13];
  22034. tmp[6] = product[14];
  22035. tmp[7] = product[15];
  22036. carry = (int) mg_uecc_vli_add(tmp, tmp, tmp, num_words_secp256r1);
  22037. carry += (int) mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  22038. /* s2 */
  22039. tmp[3] = product[12];
  22040. tmp[4] = product[13];
  22041. tmp[5] = product[14];
  22042. tmp[6] = product[15];
  22043. tmp[7] = 0;
  22044. carry += (int) mg_uecc_vli_add(tmp, tmp, tmp, num_words_secp256r1);
  22045. carry += (int) mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  22046. /* s3 */
  22047. tmp[0] = product[8];
  22048. tmp[1] = product[9];
  22049. tmp[2] = product[10];
  22050. tmp[3] = tmp[4] = tmp[5] = 0;
  22051. tmp[6] = product[14];
  22052. tmp[7] = product[15];
  22053. carry += (int) mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  22054. /* s4 */
  22055. tmp[0] = product[9];
  22056. tmp[1] = product[10];
  22057. tmp[2] = product[11];
  22058. tmp[3] = product[13];
  22059. tmp[4] = product[14];
  22060. tmp[5] = product[15];
  22061. tmp[6] = product[13];
  22062. tmp[7] = product[8];
  22063. carry += (int) mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  22064. /* d1 */
  22065. tmp[0] = product[11];
  22066. tmp[1] = product[12];
  22067. tmp[2] = product[13];
  22068. tmp[3] = tmp[4] = tmp[5] = 0;
  22069. tmp[6] = product[8];
  22070. tmp[7] = product[10];
  22071. carry -= (int) mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  22072. /* d2 */
  22073. tmp[0] = product[12];
  22074. tmp[1] = product[13];
  22075. tmp[2] = product[14];
  22076. tmp[3] = product[15];
  22077. tmp[4] = tmp[5] = 0;
  22078. tmp[6] = product[9];
  22079. tmp[7] = product[11];
  22080. carry -= (int) mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  22081. /* d3 */
  22082. tmp[0] = product[13];
  22083. tmp[1] = product[14];
  22084. tmp[2] = product[15];
  22085. tmp[3] = product[8];
  22086. tmp[4] = product[9];
  22087. tmp[5] = product[10];
  22088. tmp[6] = 0;
  22089. tmp[7] = product[12];
  22090. carry -= (int) mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  22091. /* d4 */
  22092. tmp[0] = product[14];
  22093. tmp[1] = product[15];
  22094. tmp[2] = 0;
  22095. tmp[3] = product[9];
  22096. tmp[4] = product[10];
  22097. tmp[5] = product[11];
  22098. tmp[6] = 0;
  22099. tmp[7] = product[13];
  22100. carry -= (int) mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  22101. if (carry < 0) {
  22102. do {
  22103. carry += (int) mg_uecc_vli_add(result, result, curve_secp256r1.p,
  22104. num_words_secp256r1);
  22105. } while (carry < 0);
  22106. } else {
  22107. while (carry || mg_uecc_vli_cmp_unsafe(curve_secp256r1.p, result,
  22108. num_words_secp256r1) != 1) {
  22109. carry -= (int) mg_uecc_vli_sub(result, result, curve_secp256r1.p,
  22110. num_words_secp256r1);
  22111. }
  22112. }
  22113. }
  22114. #else
  22115. static void vli_mmod_fast_secp256r1(uint64_t *result, uint64_t *product) {
  22116. uint64_t tmp[num_words_secp256r1];
  22117. int carry;
  22118. /* t */
  22119. mg_uecc_vli_set(result, product, num_words_secp256r1);
  22120. /* s1 */
  22121. tmp[0] = 0;
  22122. tmp[1] = product[5] & 0xffffffff00000000U;
  22123. tmp[2] = product[6];
  22124. tmp[3] = product[7];
  22125. carry = (int) mg_uecc_vli_add(tmp, tmp, tmp, num_words_secp256r1);
  22126. carry += (int) mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  22127. /* s2 */
  22128. tmp[1] = product[6] << 32;
  22129. tmp[2] = (product[6] >> 32) | (product[7] << 32);
  22130. tmp[3] = product[7] >> 32;
  22131. carry += (int) mg_uecc_vli_add(tmp, tmp, tmp, num_words_secp256r1);
  22132. carry += (int) mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  22133. /* s3 */
  22134. tmp[0] = product[4];
  22135. tmp[1] = product[5] & 0xffffffff;
  22136. tmp[2] = 0;
  22137. tmp[3] = product[7];
  22138. carry += (int) mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  22139. /* s4 */
  22140. tmp[0] = (product[4] >> 32) | (product[5] << 32);
  22141. tmp[1] = (product[5] >> 32) | (product[6] & 0xffffffff00000000U);
  22142. tmp[2] = product[7];
  22143. tmp[3] = (product[6] >> 32) | (product[4] << 32);
  22144. carry += (int) mg_uecc_vli_add(result, result, tmp, num_words_secp256r1);
  22145. /* d1 */
  22146. tmp[0] = (product[5] >> 32) | (product[6] << 32);
  22147. tmp[1] = (product[6] >> 32);
  22148. tmp[2] = 0;
  22149. tmp[3] = (product[4] & 0xffffffff) | (product[5] << 32);
  22150. carry -= (int) mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  22151. /* d2 */
  22152. tmp[0] = product[6];
  22153. tmp[1] = product[7];
  22154. tmp[2] = 0;
  22155. tmp[3] = (product[4] >> 32) | (product[5] & 0xffffffff00000000);
  22156. carry -= (int) mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  22157. /* d3 */
  22158. tmp[0] = (product[6] >> 32) | (product[7] << 32);
  22159. tmp[1] = (product[7] >> 32) | (product[4] << 32);
  22160. tmp[2] = (product[4] >> 32) | (product[5] << 32);
  22161. tmp[3] = (product[6] << 32);
  22162. carry -= (int) mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  22163. /* d4 */
  22164. tmp[0] = product[7];
  22165. tmp[1] = product[4] & 0xffffffff00000000U;
  22166. tmp[2] = product[5];
  22167. tmp[3] = product[6] & 0xffffffff00000000U;
  22168. carry -= (int) mg_uecc_vli_sub(result, result, tmp, num_words_secp256r1);
  22169. if (carry < 0) {
  22170. do {
  22171. carry += (int) mg_uecc_vli_add(result, result, curve_secp256r1.p,
  22172. num_words_secp256r1);
  22173. } while (carry < 0);
  22174. } else {
  22175. while (carry || mg_uecc_vli_cmp_unsafe(curve_secp256r1.p, result,
  22176. num_words_secp256r1) != 1) {
  22177. carry -= (int) mg_uecc_vli_sub(result, result, curve_secp256r1.p,
  22178. num_words_secp256r1);
  22179. }
  22180. }
  22181. }
  22182. #endif /* MG_UECC_WORD_SIZE */
  22183. #endif /* (MG_UECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256r1) */
  22184. #endif /* MG_UECC_SUPPORTS_secp256r1 */
  22185. #if MG_UECC_SUPPORTS_secp256k1
  22186. static void double_jacobian_secp256k1(mg_uecc_word_t *X1, mg_uecc_word_t *Y1,
  22187. mg_uecc_word_t *Z1, MG_UECC_Curve curve);
  22188. static void x_side_secp256k1(mg_uecc_word_t *result, const mg_uecc_word_t *x,
  22189. MG_UECC_Curve curve);
  22190. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  22191. static void vli_mmod_fast_secp256k1(mg_uecc_word_t *result,
  22192. mg_uecc_word_t *product);
  22193. #endif
  22194. static const struct MG_UECC_Curve_t curve_secp256k1 = {
  22195. num_words_secp256k1,
  22196. num_bytes_secp256k1,
  22197. 256, /* num_n_bits */
  22198. {BYTES_TO_WORDS_8(2F, FC, FF, FF, FE, FF, FF, FF),
  22199. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  22200. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  22201. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF)},
  22202. {BYTES_TO_WORDS_8(41, 41, 36, D0, 8C, 5E, D2, BF),
  22203. BYTES_TO_WORDS_8(3B, A0, 48, AF, E6, DC, AE, BA),
  22204. BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF),
  22205. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF)},
  22206. {BYTES_TO_WORDS_8(98, 17, F8, 16, 5B, 81, F2, 59),
  22207. BYTES_TO_WORDS_8(D9, 28, CE, 2D, DB, FC, 9B, 02),
  22208. BYTES_TO_WORDS_8(07, 0B, 87, CE, 95, 62, A0, 55),
  22209. BYTES_TO_WORDS_8(AC, BB, DC, F9, 7E, 66, BE, 79),
  22210. BYTES_TO_WORDS_8(B8, D4, 10, FB, 8F, D0, 47, 9C),
  22211. BYTES_TO_WORDS_8(19, 54, 85, A6, 48, B4, 17, FD),
  22212. BYTES_TO_WORDS_8(A8, 08, 11, 0E, FC, FB, A4, 5D),
  22213. BYTES_TO_WORDS_8(65, C4, A3, 26, 77, DA, 3A, 48)},
  22214. {BYTES_TO_WORDS_8(07, 00, 00, 00, 00, 00, 00, 00),
  22215. BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00),
  22216. BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00),
  22217. BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00)},
  22218. &double_jacobian_secp256k1,
  22219. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  22220. &mod_sqrt_default,
  22221. #endif
  22222. &x_side_secp256k1,
  22223. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  22224. &vli_mmod_fast_secp256k1
  22225. #endif
  22226. };
  22227. MG_UECC_Curve mg_uecc_secp256k1(void) {
  22228. return &curve_secp256k1;
  22229. }
  22230. /* Double in place */
  22231. static void double_jacobian_secp256k1(mg_uecc_word_t *X1, mg_uecc_word_t *Y1,
  22232. mg_uecc_word_t *Z1, MG_UECC_Curve curve) {
  22233. /* t1 = X, t2 = Y, t3 = Z */
  22234. mg_uecc_word_t t4[num_words_secp256k1];
  22235. mg_uecc_word_t t5[num_words_secp256k1];
  22236. if (mg_uecc_vli_isZero(Z1, num_words_secp256k1)) {
  22237. return;
  22238. }
  22239. mg_uecc_vli_modSquare_fast(t5, Y1, curve); /* t5 = y1^2 */
  22240. mg_uecc_vli_modMult_fast(t4, X1, t5, curve); /* t4 = x1*y1^2 = A */
  22241. mg_uecc_vli_modSquare_fast(X1, X1, curve); /* t1 = x1^2 */
  22242. mg_uecc_vli_modSquare_fast(t5, t5, curve); /* t5 = y1^4 */
  22243. mg_uecc_vli_modMult_fast(Z1, Y1, Z1, curve); /* t3 = y1*z1 = z3 */
  22244. mg_uecc_vli_modAdd(Y1, X1, X1, curve->p,
  22245. num_words_secp256k1); /* t2 = 2*x1^2 */
  22246. mg_uecc_vli_modAdd(Y1, Y1, X1, curve->p,
  22247. num_words_secp256k1); /* t2 = 3*x1^2 */
  22248. if (mg_uecc_vli_testBit(Y1, 0)) {
  22249. mg_uecc_word_t carry =
  22250. mg_uecc_vli_add(Y1, Y1, curve->p, num_words_secp256k1);
  22251. mg_uecc_vli_rshift1(Y1, num_words_secp256k1);
  22252. Y1[num_words_secp256k1 - 1] |= carry << (MG_UECC_WORD_BITS - 1);
  22253. } else {
  22254. mg_uecc_vli_rshift1(Y1, num_words_secp256k1);
  22255. }
  22256. /* t2 = 3/2*(x1^2) = B */
  22257. mg_uecc_vli_modSquare_fast(X1, Y1, curve); /* t1 = B^2 */
  22258. mg_uecc_vli_modSub(X1, X1, t4, curve->p,
  22259. num_words_secp256k1); /* t1 = B^2 - A */
  22260. mg_uecc_vli_modSub(X1, X1, t4, curve->p,
  22261. num_words_secp256k1); /* t1 = B^2 - 2A = x3 */
  22262. mg_uecc_vli_modSub(t4, t4, X1, curve->p,
  22263. num_words_secp256k1); /* t4 = A - x3 */
  22264. mg_uecc_vli_modMult_fast(Y1, Y1, t4, curve); /* t2 = B * (A - x3) */
  22265. mg_uecc_vli_modSub(Y1, Y1, t5, curve->p,
  22266. num_words_secp256k1); /* t2 = B * (A - x3) - y1^4 = y3 */
  22267. }
  22268. /* Computes result = x^3 + b. result must not overlap x. */
  22269. static void x_side_secp256k1(mg_uecc_word_t *result, const mg_uecc_word_t *x,
  22270. MG_UECC_Curve curve) {
  22271. mg_uecc_vli_modSquare_fast(result, x, curve); /* r = x^2 */
  22272. mg_uecc_vli_modMult_fast(result, result, x, curve); /* r = x^3 */
  22273. mg_uecc_vli_modAdd(result, result, curve->b, curve->p,
  22274. num_words_secp256k1); /* r = x^3 + b */
  22275. }
  22276. #if (MG_UECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256k1)
  22277. static void omega_mult_secp256k1(mg_uecc_word_t *result,
  22278. const mg_uecc_word_t *right);
  22279. static void vli_mmod_fast_secp256k1(mg_uecc_word_t *result,
  22280. mg_uecc_word_t *product) {
  22281. mg_uecc_word_t tmp[2 * num_words_secp256k1];
  22282. mg_uecc_word_t carry;
  22283. mg_uecc_vli_clear(tmp, num_words_secp256k1);
  22284. mg_uecc_vli_clear(tmp + num_words_secp256k1, num_words_secp256k1);
  22285. omega_mult_secp256k1(tmp,
  22286. product + num_words_secp256k1); /* (Rq, q) = q * c */
  22287. carry = mg_uecc_vli_add(result, product, tmp,
  22288. num_words_secp256k1); /* (C, r) = r + q */
  22289. mg_uecc_vli_clear(product, num_words_secp256k1);
  22290. omega_mult_secp256k1(product, tmp + num_words_secp256k1); /* Rq*c */
  22291. carry += mg_uecc_vli_add(result, result, product,
  22292. num_words_secp256k1); /* (C1, r) = r + Rq*c */
  22293. while (carry > 0) {
  22294. --carry;
  22295. mg_uecc_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1);
  22296. }
  22297. if (mg_uecc_vli_cmp_unsafe(result, curve_secp256k1.p, num_words_secp256k1) >
  22298. 0) {
  22299. mg_uecc_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1);
  22300. }
  22301. }
  22302. #if MG_UECC_WORD_SIZE == 1
  22303. static void omega_mult_secp256k1(uint8_t *result, const uint8_t *right) {
  22304. /* Multiply by (2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */
  22305. mg_uecc_word_t r0 = 0;
  22306. mg_uecc_word_t r1 = 0;
  22307. mg_uecc_word_t r2 = 0;
  22308. wordcount_t k;
  22309. /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */
  22310. muladd(0xD1, right[0], &r0, &r1, &r2);
  22311. result[0] = r0;
  22312. r0 = r1;
  22313. r1 = r2;
  22314. /* r2 is still 0 */
  22315. for (k = 1; k < num_words_secp256k1; ++k) {
  22316. muladd(0x03, right[k - 1], &r0, &r1, &r2);
  22317. muladd(0xD1, right[k], &r0, &r1, &r2);
  22318. result[k] = r0;
  22319. r0 = r1;
  22320. r1 = r2;
  22321. r2 = 0;
  22322. }
  22323. muladd(0x03, right[num_words_secp256k1 - 1], &r0, &r1, &r2);
  22324. result[num_words_secp256k1] = r0;
  22325. result[num_words_secp256k1 + 1] = r1;
  22326. /* add the 2^32 multiple */
  22327. result[4 + num_words_secp256k1] =
  22328. mg_uecc_vli_add(result + 4, result + 4, right, num_words_secp256k1);
  22329. }
  22330. #elif MG_UECC_WORD_SIZE == 4
  22331. static void omega_mult_secp256k1(uint32_t *result, const uint32_t *right) {
  22332. /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */
  22333. uint32_t carry = 0;
  22334. wordcount_t k;
  22335. for (k = 0; k < num_words_secp256k1; ++k) {
  22336. uint64_t p = (uint64_t) 0x3D1 * right[k] + carry;
  22337. result[k] = (uint32_t) p;
  22338. carry = p >> 32;
  22339. }
  22340. result[num_words_secp256k1] = carry;
  22341. /* add the 2^32 multiple */
  22342. result[1 + num_words_secp256k1] =
  22343. mg_uecc_vli_add(result + 1, result + 1, right, num_words_secp256k1);
  22344. }
  22345. #else
  22346. static void omega_mult_secp256k1(uint64_t *result, const uint64_t *right) {
  22347. mg_uecc_word_t r0 = 0;
  22348. mg_uecc_word_t r1 = 0;
  22349. mg_uecc_word_t r2 = 0;
  22350. wordcount_t k;
  22351. /* Multiply by (2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */
  22352. for (k = 0; k < num_words_secp256k1; ++k) {
  22353. muladd(0x1000003D1ull, right[k], &r0, &r1, &r2);
  22354. result[k] = r0;
  22355. r0 = r1;
  22356. r1 = r2;
  22357. r2 = 0;
  22358. }
  22359. result[num_words_secp256k1] = r0;
  22360. }
  22361. #endif /* MG_UECC_WORD_SIZE */
  22362. #endif /* (MG_UECC_OPTIMIZATION_LEVEL > 0 && && !asm_mmod_fast_secp256k1) */
  22363. #endif /* MG_UECC_SUPPORTS_secp256k1 */
  22364. #if MG_UECC_SUPPORTS_secp384r1
  22365. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  22366. static void vli_mmod_fast_secp384r1(mg_uecc_word_t *result,
  22367. mg_uecc_word_t *product);
  22368. #endif
  22369. static const struct MG_UECC_Curve_t curve_secp384r1 = {
  22370. num_words_secp384r1,
  22371. num_bytes_secp384r1,
  22372. 384, /* num_n_bits */
  22373. /* p */
  22374. {BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00),
  22375. BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF),
  22376. BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF),
  22377. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  22378. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  22379. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF)},
  22380. /* n */
  22381. {BYTES_TO_WORDS_8(73, 29, C5, CC, 6A, 19, EC, EC),
  22382. BYTES_TO_WORDS_8(7A, A7, B0, 48, B2, 0D, 1A, 58),
  22383. BYTES_TO_WORDS_8(DF, 2D, 37, F4, 81, 4D, 63, C7),
  22384. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  22385. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
  22386. BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF)},
  22387. /* G = (Gx || Gy) little-endian */
  22388. {BYTES_TO_WORDS_8(B7, 0A, 76, 72, 38, 5E, 54, 3A),
  22389. BYTES_TO_WORDS_8(6C, 29, 55, BF, 5D, F2, 02, 55),
  22390. BYTES_TO_WORDS_8(38, 2A, 54, 82, E0, 41, F7, 59),
  22391. BYTES_TO_WORDS_8(98, 9B, A7, 8B, 62, 3B, 1D, 6E),
  22392. BYTES_TO_WORDS_8(74, AD, 20, F3, 1E, C7, B1, 8E),
  22393. BYTES_TO_WORDS_8(37, 05, 8B, BE, 22, CA, 87, AA),
  22394. BYTES_TO_WORDS_8(5F, 0E, EA, 90, 7C, 1D, 43, 7A),
  22395. BYTES_TO_WORDS_8(9D, 81, 7E, 1D, CE, B1, 60, 0A),
  22396. BYTES_TO_WORDS_8(C0, B8, F0, B5, 13, 31, DA, E9),
  22397. BYTES_TO_WORDS_8(7C, 14, 9A, 28, BD, 1D, F4, F8),
  22398. BYTES_TO_WORDS_8(29, DC, 92, 92, BF, 98, 9E, 5D),
  22399. BYTES_TO_WORDS_8(6F, 2C, 26, 96, 4A, DE, 17, 36)},
  22400. /* b */
  22401. {BYTES_TO_WORDS_8(EF, 2A, EC, D3, ED, C8, 85, 2A),
  22402. BYTES_TO_WORDS_8(9D, D1, 2E, 8A, 8D, 39, 56, C6),
  22403. BYTES_TO_WORDS_8(5A, 87, 13, 50, 8F, 08, 14, 03),
  22404. BYTES_TO_WORDS_8(12, 41, 81, FE, 6E, 9C, 1D, 18),
  22405. BYTES_TO_WORDS_8(19, 2D, F8, E3, 6B, 05, 8E, 98),
  22406. BYTES_TO_WORDS_8(E4, E7, 3E, E2, A7, 2F, 31, B3)},
  22407. &double_jacobian_default,
  22408. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  22409. &mod_sqrt_default,
  22410. #endif
  22411. &x_side_default,
  22412. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  22413. &vli_mmod_fast_secp384r1
  22414. #endif
  22415. };
  22416. MG_UECC_Curve mg_uecc_secp384r1(void) {
  22417. return &curve_secp384r1;
  22418. }
  22419. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  22420. static void vli_mmod_fast_secp384r1(mg_uecc_word_t *result,
  22421. mg_uecc_word_t *product) {
  22422. mg_uecc_vli_mmod(result, product, curve_secp384r1.p, num_words_secp384r1);
  22423. }
  22424. #endif
  22425. #endif /* MG_UECC_SUPPORTS_secp384r1 */
  22426. #endif /* _UECC_CURVE_SPECIFIC_H_ */
  22427. /* Returns 1 if 'point' is the point at infinity, 0 otherwise. */
  22428. #define EccPoint_isZero(point, curve) \
  22429. mg_uecc_vli_isZero((point), (wordcount_t) ((curve)->num_words * 2))
  22430. /* Point multiplication algorithm using Montgomery's ladder with co-Z
  22431. coordinates. From http://eprint.iacr.org/2011/338.pdf
  22432. */
  22433. /* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */
  22434. static void apply_z(mg_uecc_word_t *X1, mg_uecc_word_t *Y1,
  22435. const mg_uecc_word_t *const Z, MG_UECC_Curve curve) {
  22436. mg_uecc_word_t t1[MG_UECC_MAX_WORDS];
  22437. mg_uecc_vli_modSquare_fast(t1, Z, curve); /* z^2 */
  22438. mg_uecc_vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */
  22439. mg_uecc_vli_modMult_fast(t1, t1, Z, curve); /* z^3 */
  22440. mg_uecc_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */
  22441. }
  22442. /* P = (x1, y1) => 2P, (x2, y2) => P' */
  22443. static void XYcZ_initial_double(mg_uecc_word_t *X1, mg_uecc_word_t *Y1,
  22444. mg_uecc_word_t *X2, mg_uecc_word_t *Y2,
  22445. const mg_uecc_word_t *const initial_Z,
  22446. MG_UECC_Curve curve) {
  22447. mg_uecc_word_t z[MG_UECC_MAX_WORDS];
  22448. wordcount_t num_words = curve->num_words;
  22449. if (initial_Z) {
  22450. mg_uecc_vli_set(z, initial_Z, num_words);
  22451. } else {
  22452. mg_uecc_vli_clear(z, num_words);
  22453. z[0] = 1;
  22454. }
  22455. mg_uecc_vli_set(X2, X1, num_words);
  22456. mg_uecc_vli_set(Y2, Y1, num_words);
  22457. apply_z(X1, Y1, z, curve);
  22458. curve->double_jacobian(X1, Y1, z, curve);
  22459. apply_z(X2, Y2, z, curve);
  22460. }
  22461. /* Input P = (x1, y1, Z), Q = (x2, y2, Z)
  22462. Output P' = (x1', y1', Z3), P + Q = (x3, y3, Z3)
  22463. or P => P', Q => P + Q
  22464. */
  22465. static void XYcZ_add(mg_uecc_word_t *X1, mg_uecc_word_t *Y1, mg_uecc_word_t *X2,
  22466. mg_uecc_word_t *Y2, MG_UECC_Curve curve) {
  22467. /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
  22468. mg_uecc_word_t t5[MG_UECC_MAX_WORDS] = {0};
  22469. wordcount_t num_words = curve->num_words;
  22470. mg_uecc_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */
  22471. mg_uecc_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */
  22472. mg_uecc_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */
  22473. mg_uecc_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */
  22474. mg_uecc_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */
  22475. mg_uecc_vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */
  22476. mg_uecc_vli_modSub(t5, t5, X1, curve->p, num_words); /* t5 = D - B */
  22477. mg_uecc_vli_modSub(t5, t5, X2, curve->p, num_words); /* t5 = D - B - C = x3 */
  22478. mg_uecc_vli_modSub(X2, X2, X1, curve->p, num_words); /* t3 = C - B */
  22479. mg_uecc_vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */
  22480. mg_uecc_vli_modSub(X2, X1, t5, curve->p, num_words); /* t3 = B - x3 */
  22481. mg_uecc_vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */
  22482. mg_uecc_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y3 */
  22483. mg_uecc_vli_set(X2, t5, num_words);
  22484. }
  22485. /* Input P = (x1, y1, Z), Q = (x2, y2, Z)
  22486. Output P + Q = (x3, y3, Z3), P - Q = (x3', y3', Z3)
  22487. or P => P - Q, Q => P + Q
  22488. */
  22489. static void XYcZ_addC(mg_uecc_word_t *X1, mg_uecc_word_t *Y1,
  22490. mg_uecc_word_t *X2, mg_uecc_word_t *Y2,
  22491. MG_UECC_Curve curve) {
  22492. /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
  22493. mg_uecc_word_t t5[MG_UECC_MAX_WORDS] = {0};
  22494. mg_uecc_word_t t6[MG_UECC_MAX_WORDS];
  22495. mg_uecc_word_t t7[MG_UECC_MAX_WORDS];
  22496. wordcount_t num_words = curve->num_words;
  22497. mg_uecc_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */
  22498. mg_uecc_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */
  22499. mg_uecc_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */
  22500. mg_uecc_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */
  22501. mg_uecc_vli_modAdd(t5, Y2, Y1, curve->p, num_words); /* t5 = y2 + y1 */
  22502. mg_uecc_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */
  22503. mg_uecc_vli_modSub(t6, X2, X1, curve->p, num_words); /* t6 = C - B */
  22504. mg_uecc_vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */
  22505. mg_uecc_vli_modAdd(t6, X1, X2, curve->p, num_words); /* t6 = B + C */
  22506. mg_uecc_vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */
  22507. mg_uecc_vli_modSub(X2, X2, t6, curve->p,
  22508. num_words); /* t3 = D - (B + C) = x3 */
  22509. mg_uecc_vli_modSub(t7, X1, X2, curve->p, num_words); /* t7 = B - x3 */
  22510. mg_uecc_vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */
  22511. mg_uecc_vli_modSub(Y2, Y2, Y1, curve->p,
  22512. num_words); /* t4 = (y2 - y1)*(B - x3) - E = y3 */
  22513. mg_uecc_vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */
  22514. mg_uecc_vli_modSub(t7, t7, t6, curve->p,
  22515. num_words); /* t7 = F - (B + C) = x3' */
  22516. mg_uecc_vli_modSub(t6, t7, X1, curve->p, num_words); /* t6 = x3' - B */
  22517. mg_uecc_vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2+y1)*(x3' - B) */
  22518. mg_uecc_vli_modSub(Y1, t6, Y1, curve->p,
  22519. num_words); /* t2 = (y2+y1)*(x3' - B) - E = y3' */
  22520. mg_uecc_vli_set(X1, t7, num_words);
  22521. }
  22522. /* result may overlap point. */
  22523. static void EccPoint_mult(mg_uecc_word_t *result, const mg_uecc_word_t *point,
  22524. const mg_uecc_word_t *scalar,
  22525. const mg_uecc_word_t *initial_Z, bitcount_t num_bits,
  22526. MG_UECC_Curve curve) {
  22527. /* R0 and R1 */
  22528. mg_uecc_word_t Rx[2][MG_UECC_MAX_WORDS];
  22529. mg_uecc_word_t Ry[2][MG_UECC_MAX_WORDS];
  22530. mg_uecc_word_t z[MG_UECC_MAX_WORDS];
  22531. bitcount_t i;
  22532. mg_uecc_word_t nb;
  22533. wordcount_t num_words = curve->num_words;
  22534. mg_uecc_vli_set(Rx[1], point, num_words);
  22535. mg_uecc_vli_set(Ry[1], point + num_words, num_words);
  22536. XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], initial_Z, curve);
  22537. for (i = num_bits - 2; i > 0; --i) {
  22538. nb = !mg_uecc_vli_testBit(scalar, i);
  22539. XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve);
  22540. XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve);
  22541. }
  22542. nb = !mg_uecc_vli_testBit(scalar, 0);
  22543. XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve);
  22544. /* Find final 1/Z value. */
  22545. mg_uecc_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */
  22546. mg_uecc_vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */
  22547. mg_uecc_vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */
  22548. mg_uecc_vli_modInv(z, z, curve->p, num_words); /* 1 / (xP * Yb * (X1 - X0)) */
  22549. /* yP / (xP * Yb * (X1 - X0)) */
  22550. mg_uecc_vli_modMult_fast(z, z, point + num_words, curve);
  22551. mg_uecc_vli_modMult_fast(z, z, Rx[1 - nb],
  22552. curve); /* Xb * yP / (xP * Yb * (X1 - X0)) */
  22553. /* End 1/Z calculation */
  22554. XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve);
  22555. apply_z(Rx[0], Ry[0], z, curve);
  22556. mg_uecc_vli_set(result, Rx[0], num_words);
  22557. mg_uecc_vli_set(result + num_words, Ry[0], num_words);
  22558. }
  22559. static mg_uecc_word_t regularize_k(const mg_uecc_word_t *const k,
  22560. mg_uecc_word_t *k0, mg_uecc_word_t *k1,
  22561. MG_UECC_Curve curve) {
  22562. wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
  22563. bitcount_t num_n_bits = curve->num_n_bits;
  22564. mg_uecc_word_t carry =
  22565. mg_uecc_vli_add(k0, k, curve->n, num_n_words) ||
  22566. (num_n_bits < ((bitcount_t) num_n_words * MG_UECC_WORD_SIZE * 8) &&
  22567. mg_uecc_vli_testBit(k0, num_n_bits));
  22568. mg_uecc_vli_add(k1, k0, curve->n, num_n_words);
  22569. return carry;
  22570. }
  22571. /* Generates a random integer in the range 0 < random < top.
  22572. Both random and top have num_words words. */
  22573. MG_UECC_VLI_API int mg_uecc_generate_random_int(mg_uecc_word_t *random,
  22574. const mg_uecc_word_t *top,
  22575. wordcount_t num_words) {
  22576. mg_uecc_word_t mask = (mg_uecc_word_t) -1;
  22577. mg_uecc_word_t tries;
  22578. bitcount_t num_bits = mg_uecc_vli_numBits(top, num_words);
  22579. for (tries = 0; tries < MG_UECC_RNG_MAX_TRIES; ++tries) {
  22580. unsigned int len = (unsigned int) (num_words * MG_UECC_WORD_SIZE);
  22581. if (!(g_rng_function == NULL ? mg_random((uint8_t *) random, len)
  22582. : g_rng_function((uint8_t *) random, len)))
  22583. return 0;
  22584. random[num_words - 1] &=
  22585. mask >> ((bitcount_t) (num_words * MG_UECC_WORD_SIZE * 8 - num_bits));
  22586. if (!mg_uecc_vli_isZero(random, num_words) &&
  22587. mg_uecc_vli_cmp(top, random, num_words) == 1) {
  22588. return 1;
  22589. }
  22590. }
  22591. return 0;
  22592. }
  22593. static mg_uecc_word_t EccPoint_compute_public_key(mg_uecc_word_t *result,
  22594. mg_uecc_word_t *private_key,
  22595. MG_UECC_Curve curve) {
  22596. mg_uecc_word_t tmp1[MG_UECC_MAX_WORDS];
  22597. mg_uecc_word_t tmp2[MG_UECC_MAX_WORDS];
  22598. mg_uecc_word_t *p2[2] = {tmp1, tmp2};
  22599. mg_uecc_word_t *initial_Z = 0;
  22600. mg_uecc_word_t carry;
  22601. /* Regularize the bitcount for the private key so that attackers cannot use a
  22602. side channel attack to learn the number of leading zeros. */
  22603. carry = regularize_k(private_key, tmp1, tmp2, curve);
  22604. /* If an RNG function was specified, try to get a random initial Z value to
  22605. improve protection against side-channel attacks. */
  22606. if (g_rng_function) {
  22607. if (!mg_uecc_generate_random_int(p2[carry], curve->p, curve->num_words)) {
  22608. return 0;
  22609. }
  22610. initial_Z = p2[carry];
  22611. }
  22612. EccPoint_mult(result, curve->G, p2[!carry], initial_Z,
  22613. (bitcount_t) (curve->num_n_bits + 1), curve);
  22614. if (EccPoint_isZero(result, curve)) {
  22615. return 0;
  22616. }
  22617. return 1;
  22618. }
  22619. #if MG_UECC_WORD_SIZE == 1
  22620. MG_UECC_VLI_API void mg_uecc_vli_nativeToBytes(uint8_t *bytes, int num_bytes,
  22621. const uint8_t *native) {
  22622. wordcount_t i;
  22623. for (i = 0; i < num_bytes; ++i) {
  22624. bytes[i] = native[(num_bytes - 1) - i];
  22625. }
  22626. }
  22627. MG_UECC_VLI_API void mg_uecc_vli_bytesToNative(uint8_t *native,
  22628. const uint8_t *bytes,
  22629. int num_bytes) {
  22630. mg_uecc_vli_nativeToBytes(native, num_bytes, bytes);
  22631. }
  22632. #else
  22633. MG_UECC_VLI_API void mg_uecc_vli_nativeToBytes(uint8_t *bytes, int num_bytes,
  22634. const mg_uecc_word_t *native) {
  22635. int i;
  22636. for (i = 0; i < num_bytes; ++i) {
  22637. unsigned b = (unsigned) (num_bytes - 1 - i);
  22638. bytes[i] = (uint8_t) (native[b / MG_UECC_WORD_SIZE] >>
  22639. (8 * (b % MG_UECC_WORD_SIZE)));
  22640. }
  22641. }
  22642. MG_UECC_VLI_API void mg_uecc_vli_bytesToNative(mg_uecc_word_t *native,
  22643. const uint8_t *bytes,
  22644. int num_bytes) {
  22645. int i;
  22646. mg_uecc_vli_clear(native,
  22647. (wordcount_t) ((num_bytes + (MG_UECC_WORD_SIZE - 1)) /
  22648. MG_UECC_WORD_SIZE));
  22649. for (i = 0; i < num_bytes; ++i) {
  22650. unsigned b = (unsigned) (num_bytes - 1 - i);
  22651. native[b / MG_UECC_WORD_SIZE] |= (mg_uecc_word_t) bytes[i]
  22652. << (8 * (b % MG_UECC_WORD_SIZE));
  22653. }
  22654. }
  22655. #endif /* MG_UECC_WORD_SIZE */
  22656. int mg_uecc_make_key(uint8_t *public_key, uint8_t *private_key,
  22657. MG_UECC_Curve curve) {
  22658. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22659. mg_uecc_word_t *_private = (mg_uecc_word_t *) private_key;
  22660. mg_uecc_word_t *_public = (mg_uecc_word_t *) public_key;
  22661. #else
  22662. mg_uecc_word_t _private[MG_UECC_MAX_WORDS];
  22663. mg_uecc_word_t _public[MG_UECC_MAX_WORDS * 2];
  22664. #endif
  22665. mg_uecc_word_t tries;
  22666. for (tries = 0; tries < MG_UECC_RNG_MAX_TRIES; ++tries) {
  22667. if (!mg_uecc_generate_random_int(_private, curve->n,
  22668. BITS_TO_WORDS(curve->num_n_bits))) {
  22669. return 0;
  22670. }
  22671. if (EccPoint_compute_public_key(_public, _private, curve)) {
  22672. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  22673. mg_uecc_vli_nativeToBytes(private_key, BITS_TO_BYTES(curve->num_n_bits),
  22674. _private);
  22675. mg_uecc_vli_nativeToBytes(public_key, curve->num_bytes, _public);
  22676. mg_uecc_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes,
  22677. _public + curve->num_words);
  22678. #endif
  22679. return 1;
  22680. }
  22681. }
  22682. return 0;
  22683. }
  22684. int mg_uecc_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
  22685. uint8_t *secret, MG_UECC_Curve curve) {
  22686. mg_uecc_word_t _public[MG_UECC_MAX_WORDS * 2];
  22687. mg_uecc_word_t _private[MG_UECC_MAX_WORDS];
  22688. mg_uecc_word_t tmp[MG_UECC_MAX_WORDS];
  22689. mg_uecc_word_t *p2[2] = {_private, tmp};
  22690. mg_uecc_word_t *initial_Z = 0;
  22691. mg_uecc_word_t carry;
  22692. wordcount_t num_words = curve->num_words;
  22693. wordcount_t num_bytes = curve->num_bytes;
  22694. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22695. bcopy((uint8_t *) _private, private_key, num_bytes);
  22696. bcopy((uint8_t *) _public, public_key, num_bytes * 2);
  22697. #else
  22698. mg_uecc_vli_bytesToNative(_private, private_key,
  22699. BITS_TO_BYTES(curve->num_n_bits));
  22700. mg_uecc_vli_bytesToNative(_public, public_key, num_bytes);
  22701. mg_uecc_vli_bytesToNative(_public + num_words, public_key + num_bytes,
  22702. num_bytes);
  22703. #endif
  22704. /* Regularize the bitcount for the private key so that attackers cannot use a
  22705. side channel attack to learn the number of leading zeros. */
  22706. carry = regularize_k(_private, _private, tmp, curve);
  22707. /* If an RNG function was specified, try to get a random initial Z value to
  22708. improve protection against side-channel attacks. */
  22709. if (g_rng_function) {
  22710. if (!mg_uecc_generate_random_int(p2[carry], curve->p, num_words)) {
  22711. return 0;
  22712. }
  22713. initial_Z = p2[carry];
  22714. }
  22715. EccPoint_mult(_public, _public, p2[!carry], initial_Z,
  22716. (bitcount_t) (curve->num_n_bits + 1), curve);
  22717. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22718. bcopy((uint8_t *) secret, (uint8_t *) _public, num_bytes);
  22719. #else
  22720. mg_uecc_vli_nativeToBytes(secret, num_bytes, _public);
  22721. #endif
  22722. return !EccPoint_isZero(_public, curve);
  22723. }
  22724. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  22725. void mg_uecc_compress(const uint8_t *public_key, uint8_t *compressed,
  22726. MG_UECC_Curve curve) {
  22727. wordcount_t i;
  22728. for (i = 0; i < curve->num_bytes; ++i) {
  22729. compressed[i + 1] = public_key[i];
  22730. }
  22731. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22732. compressed[0] = 2 + (public_key[curve->num_bytes] & 0x01);
  22733. #else
  22734. compressed[0] = 2 + (public_key[curve->num_bytes * 2 - 1] & 0x01);
  22735. #endif
  22736. }
  22737. void mg_uecc_decompress(const uint8_t *compressed, uint8_t *public_key,
  22738. MG_UECC_Curve curve) {
  22739. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22740. mg_uecc_word_t *point = (mg_uecc_word_t *) public_key;
  22741. #else
  22742. mg_uecc_word_t point[MG_UECC_MAX_WORDS * 2];
  22743. #endif
  22744. mg_uecc_word_t *y = point + curve->num_words;
  22745. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22746. bcopy(public_key, compressed + 1, curve->num_bytes);
  22747. #else
  22748. mg_uecc_vli_bytesToNative(point, compressed + 1, curve->num_bytes);
  22749. #endif
  22750. curve->x_side(y, point, curve);
  22751. curve->mod_sqrt(y, curve);
  22752. if ((uint8_t) (y[0] & 0x01) != (compressed[0] & 0x01)) {
  22753. mg_uecc_vli_sub(y, curve->p, y, curve->num_words);
  22754. }
  22755. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  22756. mg_uecc_vli_nativeToBytes(public_key, curve->num_bytes, point);
  22757. mg_uecc_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes, y);
  22758. #endif
  22759. }
  22760. #endif /* MG_UECC_SUPPORT_COMPRESSED_POINT */
  22761. MG_UECC_VLI_API int mg_uecc_valid_point(const mg_uecc_word_t *point,
  22762. MG_UECC_Curve curve) {
  22763. mg_uecc_word_t tmp1[MG_UECC_MAX_WORDS];
  22764. mg_uecc_word_t tmp2[MG_UECC_MAX_WORDS];
  22765. wordcount_t num_words = curve->num_words;
  22766. /* The point at infinity is invalid. */
  22767. if (EccPoint_isZero(point, curve)) {
  22768. return 0;
  22769. }
  22770. /* x and y must be smaller than p. */
  22771. if (mg_uecc_vli_cmp_unsafe(curve->p, point, num_words) != 1 ||
  22772. mg_uecc_vli_cmp_unsafe(curve->p, point + num_words, num_words) != 1) {
  22773. return 0;
  22774. }
  22775. mg_uecc_vli_modSquare_fast(tmp1, point + num_words, curve);
  22776. curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */
  22777. /* Make sure that y^2 == x^3 + ax + b */
  22778. return (int) (mg_uecc_vli_equal(tmp1, tmp2, num_words));
  22779. }
  22780. int mg_uecc_valid_public_key(const uint8_t *public_key, MG_UECC_Curve curve) {
  22781. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22782. mg_uecc_word_t *_public = (mg_uecc_word_t *) public_key;
  22783. #else
  22784. mg_uecc_word_t _public[MG_UECC_MAX_WORDS * 2];
  22785. #endif
  22786. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  22787. mg_uecc_vli_bytesToNative(_public, public_key, curve->num_bytes);
  22788. mg_uecc_vli_bytesToNative(_public + curve->num_words,
  22789. public_key + curve->num_bytes, curve->num_bytes);
  22790. #endif
  22791. return mg_uecc_valid_point(_public, curve);
  22792. }
  22793. int mg_uecc_compute_public_key(const uint8_t *private_key, uint8_t *public_key,
  22794. MG_UECC_Curve curve) {
  22795. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22796. mg_uecc_word_t *_private = (mg_uecc_word_t *) private_key;
  22797. mg_uecc_word_t *_public = (mg_uecc_word_t *) public_key;
  22798. #else
  22799. mg_uecc_word_t _private[MG_UECC_MAX_WORDS];
  22800. mg_uecc_word_t _public[MG_UECC_MAX_WORDS * 2];
  22801. #endif
  22802. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  22803. mg_uecc_vli_bytesToNative(_private, private_key,
  22804. BITS_TO_BYTES(curve->num_n_bits));
  22805. #endif
  22806. /* Make sure the private key is in the range [1, n-1]. */
  22807. if (mg_uecc_vli_isZero(_private, BITS_TO_WORDS(curve->num_n_bits))) {
  22808. return 0;
  22809. }
  22810. if (mg_uecc_vli_cmp(curve->n, _private, BITS_TO_WORDS(curve->num_n_bits)) !=
  22811. 1) {
  22812. return 0;
  22813. }
  22814. /* Compute public key. */
  22815. if (!EccPoint_compute_public_key(_public, _private, curve)) {
  22816. return 0;
  22817. }
  22818. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  22819. mg_uecc_vli_nativeToBytes(public_key, curve->num_bytes, _public);
  22820. mg_uecc_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes,
  22821. _public + curve->num_words);
  22822. #endif
  22823. return 1;
  22824. }
  22825. /* -------- ECDSA code -------- */
  22826. static void bits2int(mg_uecc_word_t *native, const uint8_t *bits,
  22827. unsigned bits_size, MG_UECC_Curve curve) {
  22828. unsigned num_n_bytes = (unsigned) BITS_TO_BYTES(curve->num_n_bits);
  22829. unsigned num_n_words = (unsigned) BITS_TO_WORDS(curve->num_n_bits);
  22830. int shift;
  22831. mg_uecc_word_t carry;
  22832. mg_uecc_word_t *ptr;
  22833. if (bits_size > num_n_bytes) {
  22834. bits_size = num_n_bytes;
  22835. }
  22836. mg_uecc_vli_clear(native, (wordcount_t) num_n_words);
  22837. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22838. bcopy((uint8_t *) native, bits, bits_size);
  22839. #else
  22840. mg_uecc_vli_bytesToNative(native, bits, (int) bits_size);
  22841. #endif
  22842. if (bits_size * 8 <= (unsigned) curve->num_n_bits) {
  22843. return;
  22844. }
  22845. shift = (int) bits_size * 8 - curve->num_n_bits;
  22846. carry = 0;
  22847. ptr = native + num_n_words;
  22848. while (ptr-- > native) {
  22849. mg_uecc_word_t temp = *ptr;
  22850. *ptr = (temp >> shift) | carry;
  22851. carry = temp << (MG_UECC_WORD_BITS - shift);
  22852. }
  22853. /* Reduce mod curve_n */
  22854. if (mg_uecc_vli_cmp_unsafe(curve->n, native, (wordcount_t) num_n_words) !=
  22855. 1) {
  22856. mg_uecc_vli_sub(native, native, curve->n, (wordcount_t) num_n_words);
  22857. }
  22858. }
  22859. static int mg_uecc_sign_with_k_internal(const uint8_t *private_key,
  22860. const uint8_t *message_hash,
  22861. unsigned hash_size, mg_uecc_word_t *k,
  22862. uint8_t *signature,
  22863. MG_UECC_Curve curve) {
  22864. mg_uecc_word_t tmp[MG_UECC_MAX_WORDS];
  22865. mg_uecc_word_t s[MG_UECC_MAX_WORDS];
  22866. mg_uecc_word_t *k2[2] = {tmp, s};
  22867. mg_uecc_word_t *initial_Z = 0;
  22868. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22869. mg_uecc_word_t *p = (mg_uecc_word_t *) signature;
  22870. #else
  22871. mg_uecc_word_t p[MG_UECC_MAX_WORDS * 2];
  22872. #endif
  22873. mg_uecc_word_t carry;
  22874. wordcount_t num_words = curve->num_words;
  22875. wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
  22876. bitcount_t num_n_bits = curve->num_n_bits;
  22877. /* Make sure 0 < k < curve_n */
  22878. if (mg_uecc_vli_isZero(k, num_words) ||
  22879. mg_uecc_vli_cmp(curve->n, k, num_n_words) != 1) {
  22880. return 0;
  22881. }
  22882. carry = regularize_k(k, tmp, s, curve);
  22883. /* If an RNG function was specified, try to get a random initial Z value to
  22884. improve protection against side-channel attacks. */
  22885. if (g_rng_function) {
  22886. if (!mg_uecc_generate_random_int(k2[carry], curve->p, num_words)) {
  22887. return 0;
  22888. }
  22889. initial_Z = k2[carry];
  22890. }
  22891. EccPoint_mult(p, curve->G, k2[!carry], initial_Z,
  22892. (bitcount_t) (num_n_bits + 1), curve);
  22893. if (mg_uecc_vli_isZero(p, num_words)) {
  22894. return 0;
  22895. }
  22896. /* If an RNG function was specified, get a random number
  22897. to prevent side channel analysis of k. */
  22898. if (!g_rng_function) {
  22899. mg_uecc_vli_clear(tmp, num_n_words);
  22900. tmp[0] = 1;
  22901. } else if (!mg_uecc_generate_random_int(tmp, curve->n, num_n_words)) {
  22902. return 0;
  22903. }
  22904. /* Prevent side channel analysis of mg_uecc_vli_modInv() to determine
  22905. bits of k / the private key by premultiplying by a random number */
  22906. mg_uecc_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */
  22907. mg_uecc_vli_modInv(k, k, curve->n, num_n_words); /* k = 1 / k' */
  22908. mg_uecc_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */
  22909. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  22910. mg_uecc_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */
  22911. #endif
  22912. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22913. bcopy((uint8_t *) tmp, private_key, BITS_TO_BYTES(curve->num_n_bits));
  22914. #else
  22915. mg_uecc_vli_bytesToNative(tmp, private_key,
  22916. BITS_TO_BYTES(curve->num_n_bits)); /* tmp = d */
  22917. #endif
  22918. s[num_n_words - 1] = 0;
  22919. mg_uecc_vli_set(s, p, num_words);
  22920. mg_uecc_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */
  22921. bits2int(tmp, message_hash, hash_size, curve);
  22922. mg_uecc_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */
  22923. mg_uecc_vli_modMult(s, s, k, curve->n, num_n_words); /* s = (e + r*d) / k */
  22924. if (mg_uecc_vli_numBits(s, num_n_words) > (bitcount_t) curve->num_bytes * 8) {
  22925. return 0;
  22926. }
  22927. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  22928. bcopy((uint8_t *) signature + curve->num_bytes, (uint8_t *) s,
  22929. curve->num_bytes);
  22930. #else
  22931. mg_uecc_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s);
  22932. #endif
  22933. return 1;
  22934. }
  22935. #if 0
  22936. /* For testing - sign with an explicitly specified k value */
  22937. int mg_uecc_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash,
  22938. unsigned hash_size, const uint8_t *k, uint8_t *signature,
  22939. MG_UECC_Curve curve) {
  22940. mg_uecc_word_t k2[MG_UECC_MAX_WORDS];
  22941. bits2int(k2, k, (unsigned) BITS_TO_BYTES(curve->num_n_bits), curve);
  22942. return mg_uecc_sign_with_k_internal(private_key, message_hash, hash_size, k2,
  22943. signature, curve);
  22944. }
  22945. #endif
  22946. int mg_uecc_sign(const uint8_t *private_key, const uint8_t *message_hash,
  22947. unsigned hash_size, uint8_t *signature, MG_UECC_Curve curve) {
  22948. mg_uecc_word_t k[MG_UECC_MAX_WORDS];
  22949. mg_uecc_word_t tries;
  22950. for (tries = 0; tries < MG_UECC_RNG_MAX_TRIES; ++tries) {
  22951. if (!mg_uecc_generate_random_int(k, curve->n,
  22952. BITS_TO_WORDS(curve->num_n_bits))) {
  22953. return 0;
  22954. }
  22955. if (mg_uecc_sign_with_k_internal(private_key, message_hash, hash_size, k,
  22956. signature, curve)) {
  22957. return 1;
  22958. }
  22959. }
  22960. return 0;
  22961. }
  22962. /* Compute an HMAC using K as a key (as in RFC 6979). Note that K is always
  22963. the same size as the hash result size. */
  22964. static void HMAC_init(const MG_UECC_HashContext *hash_context,
  22965. const uint8_t *K) {
  22966. uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size;
  22967. unsigned i;
  22968. for (i = 0; i < hash_context->result_size; ++i) pad[i] = K[i] ^ 0x36;
  22969. for (; i < hash_context->block_size; ++i) pad[i] = 0x36;
  22970. hash_context->init_hash(hash_context);
  22971. hash_context->update_hash(hash_context, pad, hash_context->block_size);
  22972. }
  22973. static void HMAC_update(const MG_UECC_HashContext *hash_context,
  22974. const uint8_t *message, unsigned message_size) {
  22975. hash_context->update_hash(hash_context, message, message_size);
  22976. }
  22977. static void HMAC_finish(const MG_UECC_HashContext *hash_context,
  22978. const uint8_t *K, uint8_t *result) {
  22979. uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size;
  22980. unsigned i;
  22981. for (i = 0; i < hash_context->result_size; ++i) pad[i] = K[i] ^ 0x5c;
  22982. for (; i < hash_context->block_size; ++i) pad[i] = 0x5c;
  22983. hash_context->finish_hash(hash_context, result);
  22984. hash_context->init_hash(hash_context);
  22985. hash_context->update_hash(hash_context, pad, hash_context->block_size);
  22986. hash_context->update_hash(hash_context, result, hash_context->result_size);
  22987. hash_context->finish_hash(hash_context, result);
  22988. }
  22989. /* V = HMAC_K(V) */
  22990. static void update_V(const MG_UECC_HashContext *hash_context, uint8_t *K,
  22991. uint8_t *V) {
  22992. HMAC_init(hash_context, K);
  22993. HMAC_update(hash_context, V, hash_context->result_size);
  22994. HMAC_finish(hash_context, K, V);
  22995. }
  22996. /* Deterministic signing, similar to RFC 6979. Differences are:
  22997. * We just use H(m) directly rather than bits2octets(H(m))
  22998. (it is not reduced modulo curve_n).
  22999. * We generate a value for k (aka T) directly rather than converting
  23000. endianness.
  23001. Layout of hash_context->tmp: <K> | <V> | (1 byte overlapped 0x00 or 0x01) /
  23002. <HMAC pad> */
  23003. int mg_uecc_sign_deterministic(const uint8_t *private_key,
  23004. const uint8_t *message_hash, unsigned hash_size,
  23005. const MG_UECC_HashContext *hash_context,
  23006. uint8_t *signature, MG_UECC_Curve curve) {
  23007. uint8_t *K = hash_context->tmp;
  23008. uint8_t *V = K + hash_context->result_size;
  23009. wordcount_t num_bytes = curve->num_bytes;
  23010. wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
  23011. bitcount_t num_n_bits = curve->num_n_bits;
  23012. mg_uecc_word_t tries;
  23013. unsigned i;
  23014. for (i = 0; i < hash_context->result_size; ++i) {
  23015. V[i] = 0x01;
  23016. K[i] = 0;
  23017. }
  23018. /* K = HMAC_K(V || 0x00 || int2octets(x) || h(m)) */
  23019. HMAC_init(hash_context, K);
  23020. V[hash_context->result_size] = 0x00;
  23021. HMAC_update(hash_context, V, hash_context->result_size + 1);
  23022. HMAC_update(hash_context, private_key, (unsigned int) num_bytes);
  23023. HMAC_update(hash_context, message_hash, hash_size);
  23024. HMAC_finish(hash_context, K, K);
  23025. update_V(hash_context, K, V);
  23026. /* K = HMAC_K(V || 0x01 || int2octets(x) || h(m)) */
  23027. HMAC_init(hash_context, K);
  23028. V[hash_context->result_size] = 0x01;
  23029. HMAC_update(hash_context, V, hash_context->result_size + 1);
  23030. HMAC_update(hash_context, private_key, (unsigned int) num_bytes);
  23031. HMAC_update(hash_context, message_hash, hash_size);
  23032. HMAC_finish(hash_context, K, K);
  23033. update_V(hash_context, K, V);
  23034. for (tries = 0; tries < MG_UECC_RNG_MAX_TRIES; ++tries) {
  23035. mg_uecc_word_t T[MG_UECC_MAX_WORDS];
  23036. uint8_t *T_ptr = (uint8_t *) T;
  23037. wordcount_t T_bytes = 0;
  23038. for (;;) {
  23039. update_V(hash_context, K, V);
  23040. for (i = 0; i < hash_context->result_size; ++i) {
  23041. T_ptr[T_bytes++] = V[i];
  23042. if (T_bytes >= num_n_words * MG_UECC_WORD_SIZE) {
  23043. goto filled;
  23044. }
  23045. }
  23046. }
  23047. filled:
  23048. if ((bitcount_t) num_n_words * MG_UECC_WORD_SIZE * 8 > num_n_bits) {
  23049. mg_uecc_word_t mask = (mg_uecc_word_t) -1;
  23050. T[num_n_words - 1] &=
  23051. mask >>
  23052. ((bitcount_t) (num_n_words * MG_UECC_WORD_SIZE * 8 - num_n_bits));
  23053. }
  23054. if (mg_uecc_sign_with_k_internal(private_key, message_hash, hash_size, T,
  23055. signature, curve)) {
  23056. return 1;
  23057. }
  23058. /* K = HMAC_K(V || 0x00) */
  23059. HMAC_init(hash_context, K);
  23060. V[hash_context->result_size] = 0x00;
  23061. HMAC_update(hash_context, V, hash_context->result_size + 1);
  23062. HMAC_finish(hash_context, K, K);
  23063. update_V(hash_context, K, V);
  23064. }
  23065. return 0;
  23066. }
  23067. static bitcount_t smax(bitcount_t a, bitcount_t b) {
  23068. return (a > b ? a : b);
  23069. }
  23070. int mg_uecc_verify(const uint8_t *public_key, const uint8_t *message_hash,
  23071. unsigned hash_size, const uint8_t *signature,
  23072. MG_UECC_Curve curve) {
  23073. mg_uecc_word_t u1[MG_UECC_MAX_WORDS], u2[MG_UECC_MAX_WORDS];
  23074. mg_uecc_word_t z[MG_UECC_MAX_WORDS];
  23075. mg_uecc_word_t sum[MG_UECC_MAX_WORDS * 2];
  23076. mg_uecc_word_t rx[MG_UECC_MAX_WORDS];
  23077. mg_uecc_word_t ry[MG_UECC_MAX_WORDS];
  23078. mg_uecc_word_t tx[MG_UECC_MAX_WORDS];
  23079. mg_uecc_word_t ty[MG_UECC_MAX_WORDS];
  23080. mg_uecc_word_t tz[MG_UECC_MAX_WORDS];
  23081. const mg_uecc_word_t *points[4];
  23082. const mg_uecc_word_t *point;
  23083. bitcount_t num_bits;
  23084. bitcount_t i;
  23085. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  23086. mg_uecc_word_t *_public = (mg_uecc_word_t *) public_key;
  23087. #else
  23088. mg_uecc_word_t _public[MG_UECC_MAX_WORDS * 2];
  23089. #endif
  23090. mg_uecc_word_t r[MG_UECC_MAX_WORDS], s[MG_UECC_MAX_WORDS];
  23091. wordcount_t num_words = curve->num_words;
  23092. wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
  23093. rx[num_n_words - 1] = 0;
  23094. r[num_n_words - 1] = 0;
  23095. s[num_n_words - 1] = 0;
  23096. #if MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  23097. bcopy((uint8_t *) r, signature, curve->num_bytes);
  23098. bcopy((uint8_t *) s, signature + curve->num_bytes, curve->num_bytes);
  23099. #else
  23100. mg_uecc_vli_bytesToNative(_public, public_key, curve->num_bytes);
  23101. mg_uecc_vli_bytesToNative(_public + num_words, public_key + curve->num_bytes,
  23102. curve->num_bytes);
  23103. mg_uecc_vli_bytesToNative(r, signature, curve->num_bytes);
  23104. mg_uecc_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes);
  23105. #endif
  23106. /* r, s must not be 0. */
  23107. if (mg_uecc_vli_isZero(r, num_words) || mg_uecc_vli_isZero(s, num_words)) {
  23108. return 0;
  23109. }
  23110. /* r, s must be < n. */
  23111. if (mg_uecc_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 ||
  23112. mg_uecc_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) {
  23113. return 0;
  23114. }
  23115. /* Calculate u1 and u2. */
  23116. mg_uecc_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */
  23117. u1[num_n_words - 1] = 0;
  23118. bits2int(u1, message_hash, hash_size, curve);
  23119. mg_uecc_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */
  23120. mg_uecc_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */
  23121. /* Calculate sum = G + Q. */
  23122. mg_uecc_vli_set(sum, _public, num_words);
  23123. mg_uecc_vli_set(sum + num_words, _public + num_words, num_words);
  23124. mg_uecc_vli_set(tx, curve->G, num_words);
  23125. mg_uecc_vli_set(ty, curve->G + num_words, num_words);
  23126. mg_uecc_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */
  23127. XYcZ_add(tx, ty, sum, sum + num_words, curve);
  23128. mg_uecc_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */
  23129. apply_z(sum, sum + num_words, z, curve);
  23130. /* Use Shamir's trick to calculate u1*G + u2*Q */
  23131. points[0] = 0;
  23132. points[1] = curve->G;
  23133. points[2] = _public;
  23134. points[3] = sum;
  23135. num_bits = smax(mg_uecc_vli_numBits(u1, num_n_words),
  23136. mg_uecc_vli_numBits(u2, num_n_words));
  23137. point =
  23138. points[(!!mg_uecc_vli_testBit(u1, (bitcount_t) (num_bits - 1))) |
  23139. ((!!mg_uecc_vli_testBit(u2, (bitcount_t) (num_bits - 1))) << 1)];
  23140. mg_uecc_vli_set(rx, point, num_words);
  23141. mg_uecc_vli_set(ry, point + num_words, num_words);
  23142. mg_uecc_vli_clear(z, num_words);
  23143. z[0] = 1;
  23144. for (i = num_bits - 2; i >= 0; --i) {
  23145. mg_uecc_word_t index;
  23146. curve->double_jacobian(rx, ry, z, curve);
  23147. index = (!!mg_uecc_vli_testBit(u1, i)) |
  23148. (mg_uecc_word_t) ((!!mg_uecc_vli_testBit(u2, i)) << 1);
  23149. point = points[index];
  23150. if (point) {
  23151. mg_uecc_vli_set(tx, point, num_words);
  23152. mg_uecc_vli_set(ty, point + num_words, num_words);
  23153. apply_z(tx, ty, z, curve);
  23154. mg_uecc_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */
  23155. XYcZ_add(tx, ty, rx, ry, curve);
  23156. mg_uecc_vli_modMult_fast(z, z, tz, curve);
  23157. }
  23158. }
  23159. mg_uecc_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */
  23160. apply_z(rx, ry, z, curve);
  23161. /* v = x1 (mod n) */
  23162. if (mg_uecc_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) {
  23163. mg_uecc_vli_sub(rx, rx, curve->n, num_n_words);
  23164. }
  23165. /* Accept only if v == r. */
  23166. return (int) (mg_uecc_vli_equal(rx, r, num_words));
  23167. }
  23168. #if MG_UECC_ENABLE_VLI_API
  23169. unsigned mg_uecc_curve_num_words(MG_UECC_Curve curve) {
  23170. return curve->num_words;
  23171. }
  23172. unsigned mg_uecc_curve_num_bytes(MG_UECC_Curve curve) {
  23173. return curve->num_bytes;
  23174. }
  23175. unsigned mg_uecc_curve_num_bits(MG_UECC_Curve curve) {
  23176. return curve->num_bytes * 8;
  23177. }
  23178. unsigned mg_uecc_curve_num_n_words(MG_UECC_Curve curve) {
  23179. return BITS_TO_WORDS(curve->num_n_bits);
  23180. }
  23181. unsigned mg_uecc_curve_num_n_bytes(MG_UECC_Curve curve) {
  23182. return BITS_TO_BYTES(curve->num_n_bits);
  23183. }
  23184. unsigned mg_uecc_curve_num_n_bits(MG_UECC_Curve curve) {
  23185. return curve->num_n_bits;
  23186. }
  23187. const mg_uecc_word_t *mg_uecc_curve_p(MG_UECC_Curve curve) {
  23188. return curve->p;
  23189. }
  23190. const mg_uecc_word_t *mg_uecc_curve_n(MG_UECC_Curve curve) {
  23191. return curve->n;
  23192. }
  23193. const mg_uecc_word_t *mg_uecc_curve_G(MG_UECC_Curve curve) {
  23194. return curve->G;
  23195. }
  23196. const mg_uecc_word_t *mg_uecc_curve_b(MG_UECC_Curve curve) {
  23197. return curve->b;
  23198. }
  23199. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  23200. void mg_uecc_vli_mod_sqrt(mg_uecc_word_t *a, MG_UECC_Curve curve) {
  23201. curve->mod_sqrt(a, curve);
  23202. }
  23203. #endif
  23204. void mg_uecc_vli_mmod_fast(mg_uecc_word_t *result, mg_uecc_word_t *product,
  23205. MG_UECC_Curve curve) {
  23206. #if (MG_UECC_OPTIMIZATION_LEVEL > 0)
  23207. curve->mmod_fast(result, product);
  23208. #else
  23209. mg_uecc_vli_mmod(result, product, curve->p, curve->num_words);
  23210. #endif
  23211. }
  23212. void mg_uecc_point_mult(mg_uecc_word_t *result, const mg_uecc_word_t *point,
  23213. const mg_uecc_word_t *scalar, MG_UECC_Curve curve) {
  23214. mg_uecc_word_t tmp1[MG_UECC_MAX_WORDS];
  23215. mg_uecc_word_t tmp2[MG_UECC_MAX_WORDS];
  23216. mg_uecc_word_t *p2[2] = {tmp1, tmp2};
  23217. mg_uecc_word_t carry = regularize_k(scalar, tmp1, tmp2, curve);
  23218. EccPoint_mult(result, point, p2[!carry], 0, curve->num_n_bits + 1, curve);
  23219. }
  23220. #endif /* MG_UECC_ENABLE_VLI_API */
  23221. #endif // MG_TLS_BUILTIN
  23222. // End of uecc BSD-2
  23223. #ifdef MG_ENABLE_LINES
  23224. #line 1 "src/tls_x25519.c"
  23225. #endif
  23226. /**
  23227. * Adapted from STROBE: https://strobe.sourceforge.io/
  23228. * Copyright (c) 2015-2016 Cryptography Research, Inc.
  23229. * Author: Mike Hamburg
  23230. * License: MIT License
  23231. */
  23232. #if MG_TLS == MG_TLS_BUILTIN
  23233. const uint8_t X25519_BASE_POINT[X25519_BYTES] = {9};
  23234. #define X25519_WBITS 32
  23235. typedef uint32_t limb_t;
  23236. typedef uint64_t dlimb_t;
  23237. typedef int64_t sdlimb_t;
  23238. #define NLIMBS (256 / X25519_WBITS)
  23239. typedef limb_t mg_fe[NLIMBS];
  23240. static limb_t umaal(limb_t *carry, limb_t acc, limb_t mand, limb_t mier) {
  23241. dlimb_t tmp = (dlimb_t) mand * mier + acc + *carry;
  23242. *carry = (limb_t) (tmp >> X25519_WBITS);
  23243. return (limb_t) tmp;
  23244. }
  23245. // These functions are implemented in terms of umaal on ARM
  23246. static limb_t adc(limb_t *carry, limb_t acc, limb_t mand) {
  23247. dlimb_t total = (dlimb_t) *carry + acc + mand;
  23248. *carry = (limb_t) (total >> X25519_WBITS);
  23249. return (limb_t) total;
  23250. }
  23251. static limb_t adc0(limb_t *carry, limb_t acc) {
  23252. dlimb_t total = (dlimb_t) *carry + acc;
  23253. *carry = (limb_t) (total >> X25519_WBITS);
  23254. return (limb_t) total;
  23255. }
  23256. // - Precondition: carry is small.
  23257. // - Invariant: result of propagate is < 2^255 + 1 word
  23258. // - In particular, always less than 2p.
  23259. // - Also, output x >= min(x,19)
  23260. static void propagate(mg_fe x, limb_t over) {
  23261. unsigned i;
  23262. limb_t carry;
  23263. over = x[NLIMBS - 1] >> (X25519_WBITS - 1) | over << 1;
  23264. x[NLIMBS - 1] &= ~((limb_t) 1 << (X25519_WBITS - 1));
  23265. carry = over * 19;
  23266. for (i = 0; i < NLIMBS; i++) {
  23267. x[i] = adc0(&carry, x[i]);
  23268. }
  23269. }
  23270. static void add(mg_fe out, const mg_fe a, const mg_fe b) {
  23271. unsigned i;
  23272. limb_t carry = 0;
  23273. for (i = 0; i < NLIMBS; i++) {
  23274. out[i] = adc(&carry, a[i], b[i]);
  23275. }
  23276. propagate(out, carry);
  23277. }
  23278. static void sub(mg_fe out, const mg_fe a, const mg_fe b) {
  23279. unsigned i;
  23280. sdlimb_t carry = -38;
  23281. for (i = 0; i < NLIMBS; i++) {
  23282. carry = carry + a[i] - b[i];
  23283. out[i] = (limb_t) carry;
  23284. carry >>= X25519_WBITS;
  23285. }
  23286. propagate(out, (limb_t) (1 + carry));
  23287. }
  23288. // `b` can contain less than 8 limbs, thus we use `limb_t *` instead of `mg_fe`
  23289. // to avoid build warnings
  23290. static void mul(mg_fe out, const mg_fe a, const limb_t *b, unsigned nb) {
  23291. limb_t accum[2 * NLIMBS] = {0};
  23292. unsigned i, j;
  23293. limb_t carry2;
  23294. for (i = 0; i < nb; i++) {
  23295. limb_t mand = b[i];
  23296. carry2 = 0;
  23297. for (j = 0; j < NLIMBS; j++) {
  23298. limb_t tmp; // "a" may be misaligned
  23299. memcpy(&tmp, &a[j], sizeof(tmp)); // So make an aligned copy
  23300. accum[i + j] = umaal(&carry2, accum[i + j], mand, tmp);
  23301. }
  23302. accum[i + j] = carry2;
  23303. }
  23304. carry2 = 0;
  23305. for (j = 0; j < NLIMBS; j++) {
  23306. out[j] = umaal(&carry2, accum[j], 38, accum[j + NLIMBS]);
  23307. }
  23308. propagate(out, carry2);
  23309. }
  23310. static void sqr(mg_fe out, const mg_fe a) {
  23311. mul(out, a, a, NLIMBS);
  23312. }
  23313. static void mul1(mg_fe out, const mg_fe a) {
  23314. mul(out, a, out, NLIMBS);
  23315. }
  23316. static void sqr1(mg_fe a) {
  23317. mul1(a, a);
  23318. }
  23319. static void condswap(limb_t a[2 * NLIMBS], limb_t b[2 * NLIMBS],
  23320. limb_t doswap) {
  23321. unsigned i;
  23322. for (i = 0; i < 2 * NLIMBS; i++) {
  23323. limb_t xor_ab = (a[i] ^ b[i]) & doswap;
  23324. a[i] ^= xor_ab;
  23325. b[i] ^= xor_ab;
  23326. }
  23327. }
  23328. // Canonicalize a field element x, reducing it to the least residue which is
  23329. // congruent to it mod 2^255-19
  23330. // - Precondition: x < 2^255 + 1 word
  23331. static limb_t canon(mg_fe x) {
  23332. // First, add 19.
  23333. unsigned i;
  23334. limb_t carry0 = 19;
  23335. limb_t res;
  23336. sdlimb_t carry;
  23337. for (i = 0; i < NLIMBS; i++) {
  23338. x[i] = adc0(&carry0, x[i]);
  23339. }
  23340. propagate(x, carry0);
  23341. // Here, 19 <= x2 < 2^255
  23342. // - This is because we added 19, so before propagate it can't be less
  23343. // than 19. After propagate, it still can't be less than 19, because if
  23344. // propagate does anything it adds 19.
  23345. // - We know that the high bit must be clear, because either the input was ~
  23346. // 2^255 + one word + 19 (in which case it propagates to at most 2 words) or
  23347. // it was < 2^255. So now, if we subtract 19, we will get back to something in
  23348. // [0,2^255-19).
  23349. carry = -19;
  23350. res = 0;
  23351. for (i = 0; i < NLIMBS; i++) {
  23352. carry += x[i];
  23353. res |= x[i] = (limb_t) carry;
  23354. carry >>= X25519_WBITS;
  23355. }
  23356. return (limb_t) (((dlimb_t) res - 1) >> X25519_WBITS);
  23357. }
  23358. static const limb_t a24[1] = {121665};
  23359. static void ladder_part1(mg_fe xs[5]) {
  23360. limb_t *x2 = xs[0], *z2 = xs[1], *x3 = xs[2], *z3 = xs[3], *t1 = xs[4];
  23361. add(t1, x2, z2); // t1 = A
  23362. sub(z2, x2, z2); // z2 = B
  23363. add(x2, x3, z3); // x2 = C
  23364. sub(z3, x3, z3); // z3 = D
  23365. mul1(z3, t1); // z3 = DA
  23366. mul1(x2, z2); // x3 = BC
  23367. add(x3, z3, x2); // x3 = DA+CB
  23368. sub(z3, z3, x2); // z3 = DA-CB
  23369. sqr1(t1); // t1 = AA
  23370. sqr1(z2); // z2 = BB
  23371. sub(x2, t1, z2); // x2 = E = AA-BB
  23372. mul(z2, x2, a24, sizeof(a24) / sizeof(a24[0])); // z2 = E*a24
  23373. add(z2, z2, t1); // z2 = E*a24 + AA
  23374. }
  23375. static void ladder_part2(mg_fe xs[5], const mg_fe x1) {
  23376. limb_t *x2 = xs[0], *z2 = xs[1], *x3 = xs[2], *z3 = xs[3], *t1 = xs[4];
  23377. sqr1(z3); // z3 = (DA-CB)^2
  23378. mul1(z3, x1); // z3 = x1 * (DA-CB)^2
  23379. sqr1(x3); // x3 = (DA+CB)^2
  23380. mul1(z2, x2); // z2 = AA*(E*a24+AA)
  23381. sub(x2, t1, x2); // x2 = BB again
  23382. mul1(x2, t1); // x2 = AA*BB
  23383. }
  23384. static void x25519_core(mg_fe xs[5], const uint8_t scalar[X25519_BYTES],
  23385. const uint8_t *x1, int clamp) {
  23386. int i;
  23387. mg_fe x1_limbs;
  23388. limb_t swap = 0;
  23389. limb_t *x2 = xs[0], *x3 = xs[2], *z3 = xs[3];
  23390. memset(xs, 0, 4 * sizeof(mg_fe));
  23391. x2[0] = z3[0] = 1;
  23392. for (i = 0; i < NLIMBS; i++) {
  23393. x3[i] = x1_limbs[i] =
  23394. MG_U32(x1[i * 4 + 3], x1[i * 4 + 2], x1[i * 4 + 1], x1[i * 4]);
  23395. }
  23396. for (i = 255; i >= 0; i--) {
  23397. uint8_t bytei = scalar[i / 8];
  23398. limb_t doswap;
  23399. if (clamp) {
  23400. if (i / 8 == 0) {
  23401. bytei &= (uint8_t) ~7U;
  23402. } else if (i / 8 == X25519_BYTES - 1) {
  23403. bytei &= 0x7F;
  23404. bytei |= 0x40;
  23405. }
  23406. }
  23407. doswap = 0 - (limb_t) ((bytei >> (i % 8)) & 1);
  23408. condswap(x2, x3, swap ^ doswap);
  23409. swap = doswap;
  23410. ladder_part1(xs);
  23411. ladder_part2(xs, (const limb_t *) x1_limbs);
  23412. }
  23413. condswap(x2, x3, swap);
  23414. }
  23415. int mg_tls_x25519(uint8_t out[X25519_BYTES], const uint8_t scalar[X25519_BYTES],
  23416. const uint8_t x1[X25519_BYTES], int clamp) {
  23417. int i, ret;
  23418. mg_fe xs[5], out_limbs;
  23419. limb_t *x2, *z2, *z3, *prev;
  23420. static const struct {
  23421. uint8_t a, c, n;
  23422. } steps[13] = {{2, 1, 1}, {2, 1, 1}, {4, 2, 3}, {2, 4, 6}, {3, 1, 1},
  23423. {3, 2, 12}, {4, 3, 25}, {2, 3, 25}, {2, 4, 50}, {3, 2, 125},
  23424. {3, 1, 2}, {3, 1, 2}, {3, 1, 1}};
  23425. x25519_core(xs, scalar, x1, clamp);
  23426. // Precomputed inversion chain
  23427. x2 = xs[0];
  23428. z2 = xs[1];
  23429. z3 = xs[3];
  23430. prev = z2;
  23431. for (i = 0; i < 13; i++) {
  23432. int j;
  23433. limb_t *a = xs[steps[i].a];
  23434. for (j = steps[i].n; j > 0; j--) {
  23435. sqr(a, prev);
  23436. prev = a;
  23437. }
  23438. mul1(a, xs[steps[i].c]);
  23439. }
  23440. // Here prev = z3
  23441. // x2 /= z2
  23442. mul(out_limbs, x2, z3, NLIMBS);
  23443. ret = (int) canon(out_limbs);
  23444. if (!clamp) ret = 0;
  23445. for (i = 0; i < NLIMBS; i++) {
  23446. uint32_t n = out_limbs[i];
  23447. out[i * 4] = (uint8_t) (n & 0xff);
  23448. out[i * 4 + 1] = (uint8_t) ((n >> 8) & 0xff);
  23449. out[i * 4 + 2] = (uint8_t) ((n >> 16) & 0xff);
  23450. out[i * 4 + 3] = (uint8_t) ((n >> 24) & 0xff);
  23451. }
  23452. return ret;
  23453. }
  23454. #endif
  23455. #ifdef MG_ENABLE_LINES
  23456. #line 1 "src/url.c"
  23457. #endif
  23458. struct url {
  23459. size_t key, user, pass, host, port, uri, end;
  23460. };
  23461. bool mg_url_is_ssl(const char *url) {
  23462. return strncmp(url, "wss:", 4) == 0 || strncmp(url, "https:", 6) == 0 ||
  23463. strncmp(url, "mqtts:", 6) == 0 || strncmp(url, "ssl:", 4) == 0 ||
  23464. strncmp(url, "tls:", 4) == 0 || strncmp(url, "tcps:", 5) == 0;
  23465. }
  23466. static struct url urlparse(const char *url) {
  23467. size_t i;
  23468. struct url u;
  23469. memset(&u, 0, sizeof(u));
  23470. for (i = 0; url[i] != '\0'; i++) {
  23471. if (url[i] == '/' && i > 0 && u.host == 0 && url[i - 1] == '/') {
  23472. u.host = i + 1;
  23473. u.port = 0;
  23474. } else if (url[i] == ']') {
  23475. u.port = 0; // IPv6 URLs, like http://[::1]/bar
  23476. } else if (url[i] == ':' && u.port == 0 && u.uri == 0) {
  23477. u.port = i + 1;
  23478. } else if (url[i] == '@' && u.user == 0 && u.pass == 0 && u.uri == 0) {
  23479. u.user = u.host;
  23480. u.pass = u.port;
  23481. u.host = i + 1;
  23482. u.port = 0;
  23483. } else if (url[i] == '/' && u.host && u.uri == 0) {
  23484. u.uri = i;
  23485. }
  23486. }
  23487. u.end = i;
  23488. #if 0
  23489. printf("[%s] %d %d %d %d %d\n", url, u.user, u.pass, u.host, u.port, u.uri);
  23490. #endif
  23491. return u;
  23492. }
  23493. struct mg_str mg_url_host(const char *url) {
  23494. struct url u = urlparse(url);
  23495. size_t n = u.port ? u.port - u.host - 1
  23496. : u.uri ? u.uri - u.host
  23497. : u.end - u.host;
  23498. struct mg_str s = mg_str_n(url + u.host, n);
  23499. return s;
  23500. }
  23501. const char *mg_url_uri(const char *url) {
  23502. struct url u = urlparse(url);
  23503. return u.uri ? url + u.uri : "/";
  23504. }
  23505. unsigned short mg_url_port(const char *url) {
  23506. struct url u = urlparse(url);
  23507. unsigned short port = 0;
  23508. if (strncmp(url, "http:", 5) == 0 || strncmp(url, "ws:", 3) == 0) port = 80;
  23509. if (strncmp(url, "wss:", 4) == 0 || strncmp(url, "https:", 6) == 0)
  23510. port = 443;
  23511. if (strncmp(url, "mqtt:", 5) == 0) port = 1883;
  23512. if (strncmp(url, "mqtts:", 6) == 0) port = 8883;
  23513. if (u.port) port = (unsigned short) atoi(url + u.port);
  23514. return port;
  23515. }
  23516. struct mg_str mg_url_user(const char *url) {
  23517. struct url u = urlparse(url);
  23518. struct mg_str s = mg_str("");
  23519. if (u.user && (u.pass || u.host)) {
  23520. size_t n = u.pass ? u.pass - u.user - 1 : u.host - u.user - 1;
  23521. s = mg_str_n(url + u.user, n);
  23522. }
  23523. return s;
  23524. }
  23525. struct mg_str mg_url_pass(const char *url) {
  23526. struct url u = urlparse(url);
  23527. struct mg_str s = mg_str_n("", 0UL);
  23528. if (u.pass && u.host) {
  23529. size_t n = u.host - u.pass - 1;
  23530. s = mg_str_n(url + u.pass, n);
  23531. }
  23532. return s;
  23533. }
  23534. #ifdef MG_ENABLE_LINES
  23535. #line 1 "src/util.c"
  23536. #endif
  23537. // Not using memset for zeroing memory, cause it can be dropped by compiler
  23538. // See https://github.com/cesanta/mongoose/pull/1265
  23539. void mg_bzero(volatile unsigned char *buf, size_t len) {
  23540. if (buf != NULL) {
  23541. while (len--) *buf++ = 0;
  23542. }
  23543. }
  23544. uint64_t mg_timegm(unsigned int year, unsigned int month, unsigned int day,
  23545. unsigned int hour, unsigned int min, unsigned int sec) {
  23546. static const uint16_t dm[12] = {0, 31, 59, 90, 120, 151,
  23547. 181, 212, 243, 273, 304, 334};
  23548. const uint64_t day_secs = 86400;
  23549. const uint64_t year_secs = 31536000;
  23550. unsigned int y, ly;
  23551. if (year < 1970) return 0;
  23552. y = year - 1900;
  23553. ly = month > 2 ? y + 1 : y;
  23554. return (uint64_t) sec + 60 * min + 3600 * hour +
  23555. day_secs * (dm[month - 1] + day - 1) + year_secs * (y - 70) +
  23556. day_secs * ((ly - 69) / 4) - day_secs * ((ly - 1) / 100) +
  23557. day_secs * ((ly + 299) / 400);
  23558. }
  23559. bool mg_memeq(const void *a, const void *b, size_t n) {
  23560. const uint8_t *p = (const uint8_t *) a, *q = (const uint8_t *) b;
  23561. uint8_t r = 0;
  23562. size_t i;
  23563. for (i = 0; i < n; i++) r = (uint8_t) (r | (uint8_t) (p[i] ^ q[i]));
  23564. return r == 0;
  23565. }
  23566. #if MG_ENABLE_CUSTOM_RANDOM
  23567. #else
  23568. bool mg_random(void *buf, size_t len) {
  23569. bool success = false;
  23570. unsigned char *p = (unsigned char *) buf;
  23571. #if MG_ARCH == MG_ARCH_ESP32
  23572. while (len--) *p++ = (unsigned char) (esp_random() & 255);
  23573. success = true;
  23574. #elif MG_ARCH == MG_ARCH_CUBE && defined(HAL_RNG_MODULE_ENABLED)
  23575. extern RNG_HandleTypeDef hrng;
  23576. for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
  23577. uint32_t r = HAL_RNG_ReadLastRandomNumber(&hrng);
  23578. memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
  23579. }
  23580. success = true;
  23581. #elif MG_ARCH == MG_ARCH_PICOSDK
  23582. while (len--) *p++ = (unsigned char) (get_rand_32() & 255);
  23583. success = true;
  23584. #elif MG_ARCH == MG_ARCH_ZEPHYR
  23585. #if MG_TLS == MG_TLS_BUILTIN || \
  23586. (MG_TLS == MG_TLS_MBED && (!defined(MBEDTLS_VERSION_NUMBER) || \
  23587. MBEDTLS_VERSION_NUMBER < 0x04000000))
  23588. return (sys_csrand_get(buf, len) == 0); // do not fallback on reseed error
  23589. #else
  23590. sys_rand_get(buf, len);
  23591. success = true;
  23592. #endif
  23593. #elif MG_ARCH == MG_ARCH_WIN32
  23594. #if defined(_MSC_VER) && _MSC_VER < 1700
  23595. static bool initialised = false;
  23596. static HCRYPTPROV hProv;
  23597. // CryptGenRandom() implementation earlier than 2008 is weak, see
  23598. // https://en.wikipedia.org/wiki/CryptGenRandom
  23599. if (!initialised) {
  23600. initialised = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
  23601. CRYPT_VERIFYCONTEXT);
  23602. }
  23603. if (initialised) success = CryptGenRandom(hProv, len, p);
  23604. #else
  23605. size_t i;
  23606. for (i = 0; i < len; i++) {
  23607. unsigned int rand_v;
  23608. if (rand_s(&rand_v) == 0) {
  23609. p[i] = (unsigned char) (rand_v & 255);
  23610. } else {
  23611. break;
  23612. }
  23613. }
  23614. success = (i == len);
  23615. #endif
  23616. #elif MG_ARCH == MG_ARCH_UNIX
  23617. FILE *fp = fopen("/dev/urandom", "rb");
  23618. if (fp != NULL) {
  23619. if (fread(buf, 1, len, fp) == len) success = true;
  23620. fclose(fp);
  23621. }
  23622. #endif
  23623. // If everything above did not work, fallback to a pseudo random generator
  23624. if (success == false) {
  23625. MG_ERROR(("Weak RNG: using rand()"));
  23626. while (len--) *p++ = (unsigned char) (rand() & 255);
  23627. }
  23628. return success;
  23629. }
  23630. #endif
  23631. char *mg_random_str(char *buf, size_t len) {
  23632. size_t i;
  23633. mg_random(buf, len);
  23634. for (i = 0; i < len; i++) {
  23635. uint8_t c = ((uint8_t *) buf)[i] % 62U;
  23636. buf[i] = i == len - 1 ? (char) '\0' // 0-terminate last byte
  23637. : c < 26 ? (char) ('a' + c) // lowercase
  23638. : c < 52 ? (char) ('A' + c - 26) // uppercase
  23639. : (char) ('0' + c - 52); // numeric
  23640. }
  23641. return buf;
  23642. }
  23643. uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len) {
  23644. static const uint32_t crclut[16] = {
  23645. // table for polynomial 0xEDB88320 (reflected)
  23646. 0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC, 0x76DC4190, 0x6B6B51F4,
  23647. 0x4DB26158, 0x5005713C, 0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C,
  23648. 0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C};
  23649. crc = ~crc;
  23650. while (len--) {
  23651. uint8_t b = *(uint8_t *) buf++;
  23652. crc = crclut[(crc ^ b) & 0x0F] ^ (crc >> 4);
  23653. crc = crclut[(crc ^ (b >> 4)) & 0x0F] ^ (crc >> 4);
  23654. }
  23655. return ~crc;
  23656. }
  23657. uint16_t mg_crc16(uint16_t crc, const char *buf, size_t len) {
  23658. static const uint16_t crclut[16] = {
  23659. // table for polynomial 0x8408 (reflected)
  23660. 0x0000, 0x1081, 0x2102, 0x3183, 0x4204, 0x5285, 0x6306, 0x7387,
  23661. 0x8408, 0x9489, 0xA50A, 0xB58B, 0xC60C, 0xD68D, 0xE70E, 0xF78F};
  23662. unsigned int c = (unsigned int) ~crc & 0xffff;
  23663. while (len--) {
  23664. uint8_t b = *(uint8_t *) buf++;
  23665. c = crclut[(c ^ b) & 0x0F] ^ (c >> 4);
  23666. c = crclut[(c ^ (b >> 4)) & 0x0F] ^ (c >> 4);
  23667. }
  23668. return (uint16_t) ~c;
  23669. }
  23670. static int isbyte(int n) {
  23671. return n >= 0 && n <= 255;
  23672. }
  23673. static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
  23674. int n, a, b, c, d, slash = 32, len = 0;
  23675. if ((sscanf(spec, "%d.%d.%d.%d/%d%n", &a, &b, &c, &d, &slash, &n) == 5 ||
  23676. sscanf(spec, "%d.%d.%d.%d%n", &a, &b, &c, &d, &n) == 4) &&
  23677. isbyte(a) && isbyte(b) && isbyte(c) && isbyte(d) && slash >= 0 &&
  23678. slash < 33) {
  23679. len = n;
  23680. *net = ((uint32_t) a << 24) | ((uint32_t) b << 16) | ((uint32_t) c << 8) |
  23681. (uint32_t) d;
  23682. *mask = slash ? (uint32_t) (0xffffffffU << (32 - slash)) : (uint32_t) 0;
  23683. }
  23684. return len;
  23685. }
  23686. int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) {
  23687. struct mg_str entry;
  23688. int allowed = acl.len == 0 ? '+' : '-'; // If any ACL is set, deny by default
  23689. uint32_t remote_ip4;
  23690. if (remote_ip->is_ip6) {
  23691. return -1; // TODO(): handle IPv6 ACL and addresses
  23692. } else { // IPv4
  23693. memcpy((void *) &remote_ip4, remote_ip->addr.ip, sizeof(remote_ip4));
  23694. while (mg_span(acl, &entry, &acl, ',')) {
  23695. uint32_t net, mask;
  23696. if (entry.buf[0] != '+' && entry.buf[0] != '-') return -1;
  23697. if (parse_net(&entry.buf[1], &net, &mask) == 0) return -2;
  23698. if ((mg_ntohl(remote_ip4) & mask) == net) allowed = entry.buf[0];
  23699. }
  23700. }
  23701. return allowed == '+';
  23702. }
  23703. bool mg_path_is_sane(const struct mg_str path) {
  23704. const char *s = path.buf;
  23705. size_t n = path.len;
  23706. if (n == 0 || path.buf[0] == '\0') return true;
  23707. if (s[0] == '~') return false; // Starts with ~
  23708. if (s[0] == '.' && n > 1 && s[1] == '.')
  23709. return false; // Starts with ..
  23710. for (; n > 0 && s[0] != '\0'; s++, n--) {
  23711. if ((s[0] == '/' || s[0] == '\\') && n >= 2 && s[1] == '.' && n > 2 &&
  23712. s[2] == '.')
  23713. return false; // Subdir starts with ..
  23714. }
  23715. if (n > 0) return false; // embedded nul (terminator not counted in len)
  23716. return true;
  23717. }
  23718. #if MG_ENABLE_CUSTOM_MILLIS
  23719. #else
  23720. uint64_t mg_millis(void) {
  23721. #if MG_ARCH == MG_ARCH_ESP8266 || MG_ARCH == MG_ARCH_ESP32 || MG_ENABLE_FREERTOS
  23722. return xTaskGetTickCount() * portTICK_PERIOD_MS;
  23723. #elif MG_ARCH == MG_ARCH_THREADX
  23724. return tx_time_get() * (1000 /* MS per SEC */ / TX_TIMER_TICKS_PER_SECOND);
  23725. #elif MG_ARCH == MG_ARCH_TIRTOS
  23726. return (uint64_t) Clock_getTicks();
  23727. #elif MG_ARCH == MG_ARCH_ZEPHYR
  23728. return (uint64_t) k_uptime_get();
  23729. #elif MG_ARCH == MG_ARCH_CMSIS_RTOS1
  23730. return (uint64_t) rt_time_get();
  23731. #elif MG_ARCH == MG_ARCH_CMSIS_RTOS2
  23732. return (uint64_t) ((osKernelGetTickCount() * 1000) / osKernelGetTickFreq());
  23733. #elif MG_ARCH == MG_ARCH_RTTHREAD
  23734. return (uint64_t) ((rt_tick_get() * 1000) / RT_TICK_PER_SECOND);
  23735. #elif MG_ARCH == MG_ARCH_WIN32
  23736. return GetTickCount();
  23737. #elif MG_ARCH == MG_ARCH_PICOSDK
  23738. return time_us_64() / 1000;
  23739. #elif MG_ARCH == MG_ARCH_CUBE
  23740. return (uint64_t) HAL_GetTick();
  23741. #elif MG_ARCH == MG_ARCH_UNIX && defined(__APPLE__)
  23742. // Apple CLOCK_MONOTONIC_RAW is equivalent to CLOCK_BOOTTIME on linux
  23743. // Apple CLOCK_UPTIME_RAW is equivalent to CLOCK_MONOTONIC_RAW on linux
  23744. return clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1000000;
  23745. #elif MG_ARCH == MG_ARCH_UNIX
  23746. struct timespec ts = {0, 0};
  23747. // See #1615 - prefer monotonic clock
  23748. #if defined(CLOCK_MONOTONIC_RAW)
  23749. // Raw hardware-based time that is not subject to NTP adjustment
  23750. clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
  23751. #elif defined(CLOCK_MONOTONIC)
  23752. // Affected by the incremental adjustments performed by adjtime and NTP
  23753. clock_gettime(CLOCK_MONOTONIC, &ts);
  23754. #else
  23755. // Affected by discontinuous jumps in the system time and by the incremental
  23756. // adjustments performed by adjtime and NTP
  23757. clock_gettime(CLOCK_REALTIME, &ts);
  23758. #endif
  23759. return ((uint64_t) ts.tv_sec * 1000 + (uint64_t) ts.tv_nsec / 1000000);
  23760. #elif defined(ARDUINO)
  23761. return (uint64_t) millis();
  23762. #else
  23763. return (uint64_t) (time(NULL) * 1000);
  23764. #endif
  23765. }
  23766. #endif
  23767. // network format equates big endian order
  23768. uint16_t mg_ntohs(uint16_t net) {
  23769. return MG_LOAD_BE16(&net);
  23770. }
  23771. uint32_t mg_ntohl(uint32_t net) {
  23772. return MG_LOAD_BE32(&net);
  23773. }
  23774. uint64_t mg_ntohll(uint64_t net) {
  23775. return MG_LOAD_BE64(&net);
  23776. }
  23777. void mg_delayms(unsigned int ms) {
  23778. uint64_t to = mg_millis() + ms + 1;
  23779. while (mg_millis() < to) (void) 0;
  23780. }
  23781. #if MG_ENABLE_CUSTOM_CALLOC
  23782. #else
  23783. void *mg_calloc(size_t count, size_t size) {
  23784. return calloc(count, size);
  23785. }
  23786. void mg_free(void *ptr) {
  23787. free(ptr);
  23788. }
  23789. #endif
  23790. #ifdef MG_ENABLE_LINES
  23791. #line 1 "src/wifi_dummy.c"
  23792. #endif
  23793. #if (!defined(MG_ENABLE_DRIVER_PICO_W) || !MG_ENABLE_DRIVER_PICO_W) && \
  23794. (!defined(MG_ENABLE_DRIVER_CYW) || !MG_ENABLE_DRIVER_CYW) && \
  23795. (!defined(MG_ENABLE_DRIVER_CYW_SDIO) || !MG_ENABLE_DRIVER_CYW_SDIO) && \
  23796. (!defined(MG_ENABLE_DRIVER_NXP_WIFI) || !MG_ENABLE_DRIVER_NXP_WIFI) && \
  23797. (!defined(MG_ENABLE_DRIVER_ST67W6) || !MG_ENABLE_DRIVER_ST67W6)
  23798. bool mg_wifi_scan(void) {
  23799. MG_ERROR(("No Wi-Fi driver enabled"));
  23800. return false;
  23801. }
  23802. bool mg_wifi_connect(struct mg_wifi_data *wifi) {
  23803. (void) wifi;
  23804. return mg_wifi_scan();
  23805. }
  23806. bool mg_wifi_disconnect(void) {
  23807. return mg_wifi_scan();
  23808. }
  23809. bool mg_wifi_ap_start(struct mg_wifi_data *wifi) {
  23810. (void) wifi;
  23811. return mg_wifi_scan();
  23812. }
  23813. bool mg_wifi_ap_stop(void) {
  23814. return mg_wifi_scan();
  23815. }
  23816. #endif
  23817. #ifdef MG_ENABLE_LINES
  23818. #line 1 "src/ws.c"
  23819. #endif
  23820. struct ws_msg {
  23821. uint8_t flags;
  23822. size_t header_len;
  23823. size_t data_len;
  23824. };
  23825. size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
  23826. va_list *ap) {
  23827. size_t len = c->send.len;
  23828. size_t n = mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
  23829. mg_ws_wrap(c, c->send.len - len, op);
  23830. return n;
  23831. }
  23832. size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...) {
  23833. size_t len = 0;
  23834. va_list ap;
  23835. va_start(ap, fmt);
  23836. len = mg_ws_vprintf(c, op, fmt, &ap);
  23837. va_end(ap);
  23838. return len;
  23839. }
  23840. static void ws_handshake(struct mg_connection *c, const struct mg_str *wskey,
  23841. const struct mg_str *wsproto, const char *fmt,
  23842. va_list *ap) {
  23843. const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
  23844. unsigned char sha[20], b64_sha[30];
  23845. mg_sha1_ctx sha_ctx;
  23846. mg_sha1_init(&sha_ctx);
  23847. mg_sha1_update(&sha_ctx, (unsigned char *) wskey->buf, wskey->len);
  23848. mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
  23849. mg_sha1_final(sha, &sha_ctx);
  23850. mg_base64_encode(sha, sizeof(sha), (char *) b64_sha, sizeof(b64_sha));
  23851. mg_xprintf(mg_pfn_iobuf, &c->send,
  23852. "HTTP/1.1 101 Switching Protocols\r\n"
  23853. "Upgrade: websocket\r\n"
  23854. "Connection: Upgrade\r\n"
  23855. "Sec-WebSocket-Accept: %s\r\n",
  23856. b64_sha);
  23857. if (fmt != NULL) mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
  23858. if (wsproto != NULL) {
  23859. mg_printf(c, "Sec-WebSocket-Protocol: %.*s\r\n", (int) wsproto->len,
  23860. wsproto->buf);
  23861. }
  23862. if (!mg_send(c, "\r\n", 2)) mg_error(c, "OOM");
  23863. }
  23864. static uint32_t be32(const uint8_t *p) {
  23865. return (((uint32_t) p[3]) << 0) | (((uint32_t) p[2]) << 8) |
  23866. (((uint32_t) p[1]) << 16) | (((uint32_t) p[0]) << 24);
  23867. }
  23868. static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
  23869. size_t i, n = 0, mask_len = 0;
  23870. memset(msg, 0, sizeof(*msg));
  23871. if (len >= 2) {
  23872. n = buf[1] & 0x7f; // Frame length
  23873. mask_len = buf[1] & 128 ? 4 : 0; // last bit is a mask bit
  23874. msg->flags = buf[0];
  23875. if (n < 126 && len >= mask_len) {
  23876. msg->data_len = n;
  23877. msg->header_len = 2 + mask_len;
  23878. } else if (n == 126 && len >= 4 + mask_len) {
  23879. msg->header_len = 4 + mask_len;
  23880. msg->data_len = (((size_t) buf[2]) << 8) | buf[3];
  23881. } else if (len >= 10 + mask_len) {
  23882. msg->header_len = 10 + mask_len;
  23883. msg->data_len =
  23884. (size_t) (((uint64_t) be32(buf + 2) << 32) + be32(buf + 6));
  23885. }
  23886. }
  23887. // Sanity check, and integer overflow protection for the boundary check below
  23888. // data_len should not be larger than 1 Gb
  23889. if (msg->data_len > 1024 * 1024 * 1024) return 0;
  23890. if (msg->header_len + msg->data_len > len) return 0;
  23891. if (mask_len > 0) {
  23892. uint8_t *p = buf + msg->header_len, *m = p - mask_len;
  23893. for (i = 0; i < msg->data_len; i++) p[i] ^= m[i & 3];
  23894. }
  23895. return msg->header_len + msg->data_len;
  23896. }
  23897. static size_t mkhdr(size_t len, int op, bool is_client, uint8_t *buf) {
  23898. size_t n = 0;
  23899. buf[0] = (uint8_t) (op | 128);
  23900. if (len < 126) {
  23901. buf[1] = (unsigned char) len;
  23902. n = 2;
  23903. } else if (len < 65536) {
  23904. uint16_t tmp = mg_htons((uint16_t) len);
  23905. buf[1] = 126;
  23906. memcpy(&buf[2], &tmp, sizeof(tmp));
  23907. n = 4;
  23908. } else {
  23909. uint32_t tmp;
  23910. buf[1] = 127;
  23911. tmp = mg_htonl((uint32_t) (((uint64_t) len) >> 32));
  23912. memcpy(&buf[2], &tmp, sizeof(tmp));
  23913. tmp = mg_htonl((uint32_t) (len & 0xffffffffU));
  23914. memcpy(&buf[6], &tmp, sizeof(tmp));
  23915. n = 10;
  23916. }
  23917. if (is_client) {
  23918. buf[1] |= 1 << 7; // Set masking flag
  23919. mg_random(&buf[n], 4);
  23920. n += 4;
  23921. }
  23922. return n;
  23923. }
  23924. static void mg_ws_mask(struct mg_connection *c, size_t len) {
  23925. if (c->is_client && c->send.buf != NULL) {
  23926. size_t i;
  23927. uint8_t *p = c->send.buf + c->send.len - len, *mask = p - 4;
  23928. for (i = 0; i < len; i++) p[i] ^= mask[i & 3];
  23929. }
  23930. }
  23931. size_t mg_ws_send(struct mg_connection *c, const void *buf, size_t len,
  23932. int op) {
  23933. uint8_t header[14];
  23934. size_t header_len = mkhdr(len, op, c->is_client, header);
  23935. if (!mg_send(c, header, header_len)) return 0;
  23936. if (!mg_send(c, buf, len)) return header_len;
  23937. MG_VERBOSE(("WS out: %d [%.*s]", (int) len, (int) len, buf));
  23938. mg_ws_mask(c, len);
  23939. return header_len + len;
  23940. }
  23941. static bool mg_ws_client_handshake(struct mg_connection *c) {
  23942. int n = mg_http_get_request_len(c->recv.buf, c->recv.len);
  23943. if (n < 0) {
  23944. mg_error(c, "not http"); // Some just, not an HTTP request
  23945. } else if (n > 0) {
  23946. if (n < 15 || memcmp(c->recv.buf + 9, "101", 3) != 0) {
  23947. mg_error(c, "ws handshake error");
  23948. } else {
  23949. struct mg_http_message hm;
  23950. if (mg_http_parse((char *) c->recv.buf, c->recv.len, &hm)) {
  23951. c->is_websocket = 1;
  23952. mg_call(c, MG_EV_WS_OPEN, &hm);
  23953. } else {
  23954. mg_error(c, "ws handshake error");
  23955. }
  23956. }
  23957. mg_iobuf_del(&c->recv, 0, (size_t) n);
  23958. } else {
  23959. return true; // Request is not yet received, quit event handler
  23960. }
  23961. return false; // Continue event handler
  23962. }
  23963. static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data) {
  23964. struct ws_msg msg;
  23965. size_t ofs = (size_t) c->pfn_data;
  23966. // assert(ofs < c->recv.len);
  23967. if (ev == MG_EV_READ) {
  23968. if (c->is_client && !c->is_websocket && mg_ws_client_handshake(c)) return;
  23969. while (ws_process(c->recv.buf + ofs, c->recv.len - ofs, &msg) > 0) {
  23970. char *s = (char *) c->recv.buf + ofs + msg.header_len;
  23971. struct mg_ws_message m;
  23972. size_t len;
  23973. uint8_t final, op;
  23974. m.data.buf = s, m.data.len = msg.data_len, m.flags = msg.flags;
  23975. len = msg.header_len + msg.data_len;
  23976. final = msg.flags & 128;
  23977. op = msg.flags & 15;
  23978. // MG_VERBOSE ("fin %d op %d len %d [%.*s]", final, op,
  23979. // (int) m.data.len, (int) m.data.len, m.data.buf));
  23980. switch (op) {
  23981. case WEBSOCKET_OP_CONTINUE:
  23982. mg_call(c, MG_EV_WS_CTL, &m);
  23983. break;
  23984. case WEBSOCKET_OP_PING:
  23985. MG_DEBUG(("%s", "WS PONG"));
  23986. mg_ws_send(c, s, msg.data_len, WEBSOCKET_OP_PONG);
  23987. mg_call(c, MG_EV_WS_CTL, &m);
  23988. break;
  23989. case WEBSOCKET_OP_PONG:
  23990. mg_call(c, MG_EV_WS_CTL, &m);
  23991. break;
  23992. case WEBSOCKET_OP_TEXT:
  23993. case WEBSOCKET_OP_BINARY:
  23994. if (final) mg_call(c, MG_EV_WS_MSG, &m);
  23995. break;
  23996. case WEBSOCKET_OP_CLOSE:
  23997. MG_DEBUG(("%lu WS CLOSE", c->id));
  23998. mg_call(c, MG_EV_WS_CTL, &m);
  23999. // Echo the payload of the received CLOSE message back to the sender
  24000. mg_ws_send(c, m.data.buf, m.data.len, WEBSOCKET_OP_CLOSE);
  24001. c->is_draining = 1;
  24002. break;
  24003. default:
  24004. // Per RFC6455, close conn when an unknown op is recvd
  24005. mg_error(c, "unknown WS op %d", op);
  24006. break;
  24007. }
  24008. // Handle fragmented frames: strip header, keep in c->recv
  24009. if (final == 0 || op == 0) {
  24010. if (op) ofs++, len--, msg.header_len--; // First frame
  24011. mg_iobuf_del(&c->recv, ofs, msg.header_len); // Strip header
  24012. len -= msg.header_len;
  24013. ofs += len;
  24014. c->pfn_data = (void *) ofs;
  24015. // MG_INFO(("FRAG %d [%.*s]", (int) ofs, (int) ofs, c->recv.buf));
  24016. }
  24017. // Remove non-fragmented frame
  24018. if (final && op) mg_iobuf_del(&c->recv, ofs, len);
  24019. // Last chunk of the fragmented frame
  24020. if (final && !op && (ofs > 0)) {
  24021. m.flags = c->recv.buf[0];
  24022. m.data = mg_str_n((char *) &c->recv.buf[1], (size_t) (ofs - 1));
  24023. mg_call(c, MG_EV_WS_MSG, &m);
  24024. mg_iobuf_del(&c->recv, 0, ofs);
  24025. ofs = 0;
  24026. c->pfn_data = NULL;
  24027. }
  24028. }
  24029. }
  24030. (void) ev_data;
  24031. }
  24032. struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
  24033. mg_event_handler_t fn, void *fn_data,
  24034. const char *fmt, ...) {
  24035. struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
  24036. if (c != NULL) {
  24037. char nonce[16], key[30];
  24038. struct mg_str host = mg_url_host(url);
  24039. mg_random(nonce, sizeof(nonce));
  24040. mg_base64_encode((unsigned char *) nonce, sizeof(nonce), key, sizeof(key));
  24041. mg_xprintf(mg_pfn_iobuf, &c->send,
  24042. "GET %s HTTP/1.1\r\n"
  24043. "Upgrade: websocket\r\n"
  24044. "Host: %.*s\r\n"
  24045. "Connection: Upgrade\r\n"
  24046. "Sec-WebSocket-Version: 13\r\n"
  24047. "Sec-WebSocket-Key: %s\r\n",
  24048. mg_url_uri(url), (int) host.len, host.buf, key);
  24049. if (fmt != NULL) {
  24050. va_list ap;
  24051. va_start(ap, fmt);
  24052. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
  24053. va_end(ap);
  24054. }
  24055. mg_xprintf(mg_pfn_iobuf, &c->send, "\r\n");
  24056. c->pfn = mg_ws_cb;
  24057. c->pfn_data = NULL;
  24058. }
  24059. return c;
  24060. }
  24061. void mg_ws_upgrade(struct mg_connection *c, struct mg_http_message *hm,
  24062. const char *fmt, ...) {
  24063. struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key");
  24064. c->pfn = mg_ws_cb;
  24065. c->pfn_data = NULL;
  24066. if (wskey == NULL) {
  24067. mg_http_reply(c, 426, "", "WS upgrade expected\n");
  24068. c->is_draining = 1;
  24069. } else {
  24070. struct mg_str *wsproto = mg_http_get_header(hm, "Sec-WebSocket-Protocol");
  24071. va_list ap;
  24072. va_start(ap, fmt);
  24073. ws_handshake(c, wskey, wsproto, fmt, &ap);
  24074. va_end(ap);
  24075. c->is_websocket = 1;
  24076. c->is_resp = 0;
  24077. mg_call(c, MG_EV_WS_OPEN, hm);
  24078. }
  24079. }
  24080. size_t mg_ws_wrap(struct mg_connection *c, size_t len, int op) {
  24081. uint8_t header[14], *p;
  24082. size_t header_len = mkhdr(len, op, c->is_client, header);
  24083. // NOTE: order of operations is important!
  24084. if (mg_iobuf_add(&c->send, c->send.len, NULL, header_len) != 0) {
  24085. p = &c->send.buf[c->send.len - len]; // p points to data
  24086. memmove(p, p - header_len, len); // Shift data
  24087. memcpy(p - header_len, header, header_len); // Prepend header
  24088. mg_ws_mask(c, len); // Mask data
  24089. } // returning 0 means an OOM condition (iobuf couldn't resize), yet this is
  24090. return c->send.len; // so far recoverable, let the caller decide
  24091. }
  24092. #ifdef MG_ENABLE_LINES
  24093. #line 1 "src/drivers/at_cmd.c"
  24094. #endif
  24095. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_ATCMD) && MG_ENABLE_DRIVER_ATCMD
  24096. #define MG_HDLC_FLAG 0x7e // HDLC frame delimiter
  24097. #define MG_HDLC_ESC 0x7d // HDLC escape byte for byte stuffing
  24098. #define MG_ATCMD_AT_TIMEOUT 2000
  24099. static size_t print_atcmd(void (*out)(char, void *), void *arg, va_list *ap) {
  24100. struct mg_str s = va_arg(*ap, struct mg_str);
  24101. size_t i;
  24102. for (i = 0; i < s.len; i++)
  24103. out((char) (s.buf[i] < 0x20 ? '.' : s.buf[i]), arg);
  24104. return s.len;
  24105. }
  24106. static void mg_atcmd_reset(struct mg_tcpip_driver_atcmd_data *dd) {
  24107. dd->script_index = 0;
  24108. dd->deadline = 0;
  24109. if (dd->reset) dd->reset(dd->usart);
  24110. }
  24111. static bool mg_atcmd_handle(struct mg_tcpip_if *ifp) {
  24112. struct mg_tcpip_driver_atcmd_data *dd = (struct mg_tcpip_driver_atcmd_data *) ifp->driver_data;
  24113. if (dd->script == NULL || dd->script_index < 0) return true;
  24114. if (dd->deadline == 0) dd->deadline = mg_millis() + MG_ATCMD_AT_TIMEOUT;
  24115. for (;;) {
  24116. if (dd->script_index % 2 == 0) { // send AT command
  24117. const char *cmd = dd->script[dd->script_index];
  24118. MG_DEBUG(("send AT[%d]: %M", dd->script_index, print_atcmd, mg_str(cmd)));
  24119. while (*cmd != '\0') dd->tx(dd->usart, (uint8_t) *cmd++);
  24120. dd->script_index++;
  24121. ifp->recv_queue.head = 0;
  24122. } else { // check AT command response
  24123. const char *expect = dd->script[dd->script_index];
  24124. struct mg_queue *q = &ifp->recv_queue;
  24125. for (;;) {
  24126. int c;
  24127. bool is_timeout = dd->deadline > 0 && mg_millis() > dd->deadline;
  24128. bool is_overflow = q->head >= q->size - 1;
  24129. if (is_timeout || is_overflow) {
  24130. MG_ERROR(("AT error: %s, retrying...", is_timeout ? "timeout" : "overflow"));
  24131. mg_atcmd_reset(dd);
  24132. return false; // FAIL
  24133. }
  24134. if ((c = dd->rx(dd->usart)) < 0) return false; // no data
  24135. q->buf[q->head++] = (char) c;
  24136. if (mg_match(mg_str_n(q->buf, q->head), mg_str(expect), NULL)) {
  24137. MG_DEBUG(("recv AT[%d]: %M", dd->script_index, print_atcmd,
  24138. mg_str_n(q->buf, q->head)));
  24139. dd->script_index++;
  24140. q->head = 0;
  24141. break;
  24142. }
  24143. }
  24144. }
  24145. if (dd->script[dd->script_index] == NULL) {
  24146. MG_DEBUG(("finished AT script"));
  24147. dd->script_index = -1;
  24148. return true;
  24149. }
  24150. }
  24151. }
  24152. static void byte_stuff(struct mg_tcpip_driver_atcmd_data *dd, uint8_t b);
  24153. static bool byte_unstuff(struct mg_tcpip_driver_atcmd_data *dd, uint8_t *p);
  24154. static size_t mg_atcmd_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
  24155. struct mg_tcpip_driver_atcmd_data *dd = (struct mg_tcpip_driver_atcmd_data *) ifp->driver_data;
  24156. struct mg_queue *q = &ifp->recv_queue;
  24157. if (!dd->link) return 0;
  24158. while (q->head < q->size) { // read as many bytes as possible
  24159. uint8_t b;
  24160. int c = dd->rx(dd->usart);
  24161. if (c < 0) return 0; // no more bytes, exit
  24162. b = (uint8_t) c;
  24163. if (b == MG_HDLC_FLAG) {
  24164. if (q->head == 0) { // first flag: skip
  24165. dd->unstuffing = false;
  24166. continue;
  24167. } else { // last flag: end of frame, exit loop
  24168. break;
  24169. }
  24170. }
  24171. if (!dd->no_byte_stuff && !byte_unstuff(dd, &b)) continue;
  24172. q->buf[q->head++] = (char) b;
  24173. }
  24174. len = (q->head <= len) ? q->head : 0;
  24175. memmove(buf, q->buf, len);
  24176. q->head = 0;
  24177. return len;
  24178. }
  24179. static size_t mg_atcmd_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
  24180. struct mg_tcpip_driver_atcmd_data *dd = (struct mg_tcpip_driver_atcmd_data *) ifp->driver_data;
  24181. uint8_t *p = (uint8_t *) buf;
  24182. size_t n = len;
  24183. if (!dd->link) return 0;
  24184. dd->tx(dd->usart, MG_HDLC_FLAG);
  24185. while (n--) {
  24186. if (dd->no_byte_stuff) {
  24187. dd->tx(dd->usart, *p++);
  24188. } else {
  24189. byte_stuff(dd, *p++);
  24190. }
  24191. }
  24192. dd->tx(dd->usart, MG_HDLC_FLAG);
  24193. return len;
  24194. }
  24195. static bool mg_atcmd_init(struct mg_tcpip_if *ifp) {
  24196. ifp->recv_queue.size = 1506; // PPP MTU=1500 + header + HDLC w/ no flags
  24197. return true;
  24198. }
  24199. static bool mg_atcmd_poll(struct mg_tcpip_if *ifp, bool s1) {
  24200. struct mg_tcpip_driver_atcmd_data *dd = (struct mg_tcpip_driver_atcmd_data *) ifp->driver_data;
  24201. dd->link = mg_atcmd_handle(ifp);
  24202. return s1 ? dd->link :false;
  24203. }
  24204. struct mg_tcpip_driver mg_tcpip_driver_atcmd = {mg_atcmd_init, mg_atcmd_tx, mg_atcmd_rx, mg_atcmd_poll};
  24205. static void byte_stuff(struct mg_tcpip_driver_atcmd_data *dd, uint8_t b) {
  24206. if ((b < 0x20) || (b == MG_HDLC_ESC) || (b == MG_HDLC_FLAG)) {
  24207. dd->tx(dd->usart, MG_HDLC_ESC);
  24208. dd->tx(dd->usart, (uint8_t) (b ^ 0x20));
  24209. } else {
  24210. dd->tx(dd->usart, b);
  24211. }
  24212. }
  24213. static bool byte_unstuff(struct mg_tcpip_driver_atcmd_data *dd, uint8_t *p) {
  24214. if (!dd->unstuffing) {
  24215. if (*p == MG_HDLC_ESC) {
  24216. dd->unstuffing = true;
  24217. return false;
  24218. } else {
  24219. return true;
  24220. }
  24221. }
  24222. dd->unstuffing = false;
  24223. *p ^= 0x20;
  24224. return true;
  24225. }
  24226. #endif
  24227. #ifdef MG_ENABLE_LINES
  24228. #line 1 "src/drivers/cmsis.c"
  24229. #endif
  24230. // https://arm-software.github.io/CMSIS_5/Driver/html/index.html
  24231. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_CMSIS) && MG_ENABLE_DRIVER_CMSIS
  24232. extern ARM_DRIVER_ETH_MAC Driver_ETH_MAC0;
  24233. extern ARM_DRIVER_ETH_PHY Driver_ETH_PHY0;
  24234. static struct mg_tcpip_if *s_ifp;
  24235. static void mac_cb(uint32_t);
  24236. static bool cmsis_init(struct mg_tcpip_if *);
  24237. static bool cmsis_poll(struct mg_tcpip_if *, bool);
  24238. static size_t cmsis_tx(const void *, size_t, struct mg_tcpip_if *);
  24239. static size_t cmsis_rx(void *, size_t, struct mg_tcpip_if *);
  24240. struct mg_tcpip_driver mg_tcpip_driver_cmsis = {cmsis_init, cmsis_tx, NULL,
  24241. cmsis_poll};
  24242. static bool cmsis_init(struct mg_tcpip_if *ifp) {
  24243. ARM_ETH_MAC_ADDR addr;
  24244. s_ifp = ifp;
  24245. ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
  24246. ARM_DRIVER_ETH_PHY *phy = &Driver_ETH_PHY0;
  24247. ARM_ETH_MAC_CAPABILITIES cap = mac->GetCapabilities();
  24248. if (mac->Initialize(mac_cb) != ARM_DRIVER_OK) return false;
  24249. if (phy->Initialize(mac->PHY_Read, mac->PHY_Write) != ARM_DRIVER_OK)
  24250. return false;
  24251. if (cap.event_rx_frame == 0) // polled mode driver
  24252. mg_tcpip_driver_cmsis.rx = cmsis_rx;
  24253. mac->PowerControl(ARM_POWER_FULL);
  24254. if (cap.mac_address) { // driver provides MAC address
  24255. mac->GetMacAddress(&addr);
  24256. memcpy(ifp->mac, &addr, sizeof(addr));
  24257. } else { // we provide MAC address
  24258. memcpy(&addr, ifp->mac, sizeof(addr));
  24259. mac->SetMacAddress(&addr);
  24260. }
  24261. phy->PowerControl(ARM_POWER_FULL);
  24262. phy->SetInterface(cap.media_interface);
  24263. phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE);
  24264. return true;
  24265. }
  24266. static size_t cmsis_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
  24267. ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
  24268. if (mac->SendFrame(buf, (uint32_t) len, 0) != ARM_DRIVER_OK) {
  24269. ifp->nerr++;
  24270. return 0;
  24271. }
  24272. ifp->nsent++;
  24273. return len;
  24274. }
  24275. static void cmsis_update_hash_table(struct mg_tcpip_if *ifp) {
  24276. // TODO(): read database, rebuild hash table
  24277. ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
  24278. ARM_ETH_MAC_ADDR addr;
  24279. memcpy(&addr, mcast_addr, sizeof(addr));
  24280. mac->SetAddressFilter(&addr, 1);
  24281. (void) ifp;
  24282. }
  24283. static bool cmsis_poll(struct mg_tcpip_if *ifp, bool s1) {
  24284. if (ifp->update_mac_hash_table) {
  24285. cmsis_update_hash_table(ifp);
  24286. ifp->update_mac_hash_table = false;
  24287. }
  24288. if (!s1) return false;
  24289. ARM_DRIVER_ETH_PHY *phy = &Driver_ETH_PHY0;
  24290. ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
  24291. bool up = (phy->GetLinkState() == ARM_ETH_LINK_UP) ? 1 : 0; // link state
  24292. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // just went up
  24293. ARM_ETH_LINK_INFO st = phy->GetLinkInfo();
  24294. mac->Control(ARM_ETH_MAC_CONFIGURE,
  24295. (st.speed << ARM_ETH_MAC_SPEED_Pos) |
  24296. (st.duplex << ARM_ETH_MAC_DUPLEX_Pos) |
  24297. ARM_ETH_MAC_ADDRESS_BROADCAST);
  24298. MG_DEBUG(("Link is %uM %s-duplex",
  24299. (st.speed == 2) ? 1000
  24300. : st.speed ? 100
  24301. : 10,
  24302. st.duplex ? "full" : "half"));
  24303. mac->Control(ARM_ETH_MAC_CONTROL_TX, 1);
  24304. mac->Control(ARM_ETH_MAC_CONTROL_RX, 1);
  24305. } else if ((ifp->state != MG_TCPIP_STATE_DOWN) && !up) { // just went down
  24306. mac->Control(ARM_ETH_MAC_FLUSH,
  24307. ARM_ETH_MAC_FLUSH_TX | ARM_ETH_MAC_FLUSH_RX);
  24308. mac->Control(ARM_ETH_MAC_CONTROL_TX, 0);
  24309. mac->Control(ARM_ETH_MAC_CONTROL_RX, 0);
  24310. }
  24311. return up;
  24312. }
  24313. static void mac_cb(uint32_t ev) {
  24314. if ((ev & ARM_ETH_MAC_EVENT_RX_FRAME) == 0) return;
  24315. ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
  24316. uint32_t len = mac->GetRxFrameSize(); // CRC already stripped
  24317. if (len >= 60 && len <= 1518) { // proper frame
  24318. char *p;
  24319. if (mg_queue_book(&s_ifp->recv_queue, &p, len) >= len) { // have room
  24320. if ((len = mac->ReadFrame((uint8_t *) p, len)) > 0) { // copy succeeds
  24321. mg_queue_add(&s_ifp->recv_queue, len);
  24322. s_ifp->nrecv++;
  24323. }
  24324. return;
  24325. }
  24326. s_ifp->ndrop++;
  24327. }
  24328. mac->ReadFrame(NULL, 0); // otherwise, discard
  24329. }
  24330. static size_t cmsis_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
  24331. ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
  24332. uint32_t len = mac->GetRxFrameSize(); // CRC already stripped
  24333. if (len >= 60 && len <= 1518 &&
  24334. ((len = mac->ReadFrame(buf, (uint32_t) buflen)) > 0))
  24335. return len;
  24336. if (len > 0) mac->ReadFrame(NULL, 0); // discard bad frames
  24337. (void) ifp;
  24338. return 0;
  24339. }
  24340. #endif
  24341. #ifdef MG_ENABLE_LINES
  24342. #line 1 "src/drivers/cyw.c"
  24343. #endif
  24344. #if MG_ENABLE_TCPIP && \
  24345. ((defined(MG_ENABLE_DRIVER_CYW) && MG_ENABLE_DRIVER_CYW) || \
  24346. (defined(MG_ENABLE_DRIVER_CYW_SDIO) && MG_ENABLE_DRIVER_CYW_SDIO))
  24347. #ifndef MG_ENABLE_DRIVER_CYW
  24348. #define MG_ENABLE_DRIVER_CYW 0
  24349. #endif
  24350. #ifndef MG_ENABLE_DRIVER_CYW_SDIO
  24351. #define MG_ENABLE_DRIVER_CYW_SDIO 0
  24352. #endif
  24353. static struct mg_tcpip_if *s_ifp;
  24354. static uint32_t s_ip, s_mask;
  24355. static bool s_link, s_auth, s_join;
  24356. static void wifi_cb(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
  24357. struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_data *) ifp->driver_data)->wifi;
  24358. if (wifi->apmode && ev == MG_TCPIP_EV_STATE_CHANGE && *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) {
  24359. MG_DEBUG(("Access Point started"));
  24360. s_ip = ifp->ip, ifp->ip = wifi->apip;
  24361. s_mask = ifp->mask, ifp->mask = wifi->apmask;
  24362. ifp->enable_dhcp_client = false;
  24363. ifp->enable_dhcp_server = true;
  24364. }
  24365. }
  24366. static bool cyw_init(uint8_t *mac);
  24367. static void cyw_poll(void);
  24368. static bool mg_tcpip_driver_cyw_init(struct mg_tcpip_if *ifp) {
  24369. struct mg_tcpip_driver_cyw_data *d =
  24370. (struct mg_tcpip_driver_cyw_data *) ifp->driver_data;
  24371. struct mg_wifi_data *wifi = &d->wifi;
  24372. if (MG_BIG_ENDIAN) {
  24373. MG_ERROR(("Big-endian host"));
  24374. return false;
  24375. }
  24376. s_ifp = ifp;
  24377. s_ip = ifp->ip;
  24378. s_mask = ifp->mask;
  24379. s_link = s_auth = s_join = false;
  24380. ifp->pfn = wifi_cb;
  24381. if (!cyw_init(ifp->mac)) return false;
  24382. if (wifi->apmode) {
  24383. return mg_wifi_ap_start(wifi);
  24384. } else if (wifi->ssid != NULL && wifi->pass != NULL) {
  24385. return mg_wifi_connect(wifi);
  24386. }
  24387. return true;
  24388. }
  24389. static size_t mg_cyw_tx(unsigned int ifc, void *data, size_t len);
  24390. size_t mg_tcpip_driver_cyw_output(const void *buf, size_t len,
  24391. struct mg_tcpip_if *ifp) {
  24392. struct mg_tcpip_driver_cyw_data *d =
  24393. (struct mg_tcpip_driver_cyw_data *) ifp->driver_data;
  24394. return mg_cyw_tx(d->wifi.apmode ? 1 : 0, (void *) buf, len) >= len ? len : 0;
  24395. }
  24396. static bool mg_tcpip_driver_cyw_poll(struct mg_tcpip_if *ifp, bool s1) {
  24397. cyw_poll();
  24398. if (!s1) return false;
  24399. struct mg_tcpip_driver_cyw_data *d =
  24400. (struct mg_tcpip_driver_cyw_data *) ifp->driver_data;
  24401. return d->wifi.apmode ? s_link : s_link && s_auth && s_join;
  24402. }
  24403. struct mg_tcpip_driver mg_tcpip_driver_cyw = {mg_tcpip_driver_cyw_init,
  24404. mg_tcpip_driver_cyw_output, NULL,
  24405. mg_tcpip_driver_cyw_poll};
  24406. // - DS:
  24407. // https://www.mouser.com/datasheet/2/196/Infineon_CYW43439_DataSheet_v03_00_EN-3074791.pdf
  24408. // - WHD: https://github.com/Infineon/wifi-host-driver
  24409. //
  24410. // | e <-- event data
  24411. // |-----
  24412. // net | vnd <-- network (TCP/IP) | vendor header (Broadcom (bcm))
  24413. // -----|-----
  24414. // IOCTL | ETH | ETH <-- IOCTL/IOVAR: chip control | ETH: Ethernet header
  24415. // -------|-----|-----
  24416. // CDC | BDC | BDC
  24417. // ------- ----- -----
  24418. // SDPCM <-- includes SDIO bus arbitration, not used in SPI
  24419. // -------------------
  24420. // SPI | SDIO <-- padded to 32-bit | 64-bytes
  24421. //
  24422. // - SDPCM has 3 channels (control, data, and asynchronous data)
  24423. // - SPI has 4 "functions", F0 to F3, to access different blocks in the chip,
  24424. // like the SPI/SDIO controller, chip backplane, and 2 DMA I/Os; these are
  24425. // usually handled by SDPCM but we need to explicitly access the I/O controller
  24426. // and chip backplane during initialization
  24427. // - SDIO has 3 functions (proper SDIO terminology), F0 to F2, coincident with
  24428. // those for SPI, accessed through standard SDIO practices. There is no F3.
  24429. // Processor core firmware is loaded to TCM RAM, along with module-dependent
  24430. // (hardware design) NVRAM data, via the chip backplane access through the bus
  24431. // Once the chip has been initialized, information regarding regulatory
  24432. // constraints (CLM blob, “Country Locale Matrix”), is loaded as an IOVAR. This
  24433. // is tied to the module being certified, hence it is also module-dependent.
  24434. // - Result: chip firmware + module NVRAM data + module CLM blob
  24435. #pragma pack(push, 1)
  24436. // all little endian
  24437. struct cdc_hdr {
  24438. uint32_t cmd; // ioctl command value
  24439. uint16_t olen; // output buflen
  24440. uint16_t ilen; // input buflen (excludes header)
  24441. uint32_t flags;
  24442. uint32_t status;
  24443. };
  24444. struct bdc_hdr {
  24445. uint8_t flags; // Flags
  24446. uint8_t priority; // 802.1d Priority (low 3 bits)
  24447. uint8_t flags2;
  24448. uint8_t data_offset; // Offset from end of BDC header to packet data, in
  24449. // 4-uint8_t words. Leaves room for optional headers.
  24450. };
  24451. struct sdpcm_sw_hdr {
  24452. uint8_t sequence; // Sequence number of pkt
  24453. uint8_t channel_and_flags; // IOCTL/IOVAR or User Data or Event
  24454. uint8_t next_length;
  24455. uint8_t header_length; // Offset to BDC or CDC header
  24456. uint8_t wireless_flow_control;
  24457. uint8_t bus_data_credit; // Credit from WLAN Chip
  24458. uint8_t _reserved[2];
  24459. };
  24460. struct sdpcm_hdr {
  24461. uint16_t len;
  24462. uint16_t _len; // ~len
  24463. struct sdpcm_sw_hdr sw_hdr;
  24464. };
  24465. struct data_hdr {
  24466. struct sdpcm_hdr sdpcm;
  24467. uint8_t pad[2];
  24468. struct bdc_hdr bdc;
  24469. };
  24470. // gSPI, CYW43439 DS 4.2.1 Fig.12, 2-bit field
  24471. #define CYW_SPID_FUNC_BUS 0 // F0
  24472. #define CYW_SPID_FUNC_CHIP 1 // F1
  24473. #define CYW_SPID_FUNC_WLAN 2 // F2
  24474. // SDIO functions, 3-bit field; CYW4343W and CYW43439 DS 4.1
  24475. #define CYW_SDIO_FUNC_BUS 0 // F0
  24476. #define CYW_SDIO_FUNC_CHIP 1 // F1
  24477. #define CYW_SDIO_FUNC_WLAN 2 // F2
  24478. #define CYW_SDPCM_CTRL_HDR 0
  24479. #define CYW_SDPCM_ASYNC_HDR 1
  24480. #define CYW_SDPCM_DATA_HDR 2
  24481. #pragma pack(pop)
  24482. static uint8_t s_tx_seqno;
  24483. static uint32_t txdata[2048 / 4], resp[2048 / 4];
  24484. static void cyw_handle_cdc(struct cdc_hdr *cdc, size_t len);
  24485. static void cyw_handle_bdc(struct bdc_hdr *bdc, size_t len);
  24486. static void cyw_handle_bdc_evnt(struct bdc_hdr *bdc, size_t len);
  24487. static size_t cyw_bus_specific_poll(uint32_t *dest);
  24488. static void cyw_update_hash_table(void);
  24489. // High-level comm stuff
  24490. static void cyw_poll(void) {
  24491. struct sdpcm_hdr *sdpcm = (struct sdpcm_hdr *) resp;
  24492. unsigned int channel;
  24493. if (s_ifp->update_mac_hash_table) {
  24494. // first call to _poll() is after _init(), so this is safe
  24495. cyw_update_hash_table();
  24496. s_ifp->update_mac_hash_table = false;
  24497. }
  24498. if (cyw_bus_specific_poll(resp) == 0) return;
  24499. if ((sdpcm->len ^ sdpcm->_len) != 0xffff || sdpcm->len < sizeof(*sdpcm) ||
  24500. sdpcm->len > 2048 - sizeof(*sdpcm))
  24501. return;
  24502. channel = sdpcm->sw_hdr.channel_and_flags & 0x0F;
  24503. if (channel == CYW_SDPCM_CTRL_HDR) {
  24504. if (sdpcm->len >= sizeof(*sdpcm) + sizeof(struct cdc_hdr)) {
  24505. struct cdc_hdr *cdc =
  24506. (struct cdc_hdr *) ((size_t) sdpcm + sdpcm->sw_hdr.header_length);
  24507. size_t len = sdpcm->len - sdpcm->sw_hdr.header_length;
  24508. cyw_handle_cdc(cdc, len);
  24509. }
  24510. } else if (channel == CYW_SDPCM_DATA_HDR) {
  24511. if (sdpcm->len >= sizeof(*sdpcm) + sizeof(struct bdc_hdr)) {
  24512. struct bdc_hdr *bdc =
  24513. (struct bdc_hdr *) ((size_t) sdpcm + sdpcm->sw_hdr.header_length);
  24514. size_t len = sdpcm->len - sdpcm->sw_hdr.header_length;
  24515. cyw_handle_bdc(bdc, len);
  24516. }
  24517. } else if (channel == CYW_SDPCM_ASYNC_HDR) {
  24518. struct bdc_hdr *bdc =
  24519. (struct bdc_hdr *) ((size_t) sdpcm + sdpcm->sw_hdr.header_length);
  24520. size_t len_ = sdpcm->len - sdpcm->sw_hdr.header_length;
  24521. cyw_handle_bdc_evnt(bdc, len_);
  24522. } // else silently discard
  24523. }
  24524. // WLAN frame reception
  24525. static void cyw_handle_bdc(struct bdc_hdr *bdc, size_t len) {
  24526. uint8_t *payload = (uint8_t *) &bdc[bdc->data_offset + 1];
  24527. mg_tcpip_qwrite(payload, len - (payload - (uint8_t *) bdc), s_ifp);
  24528. }
  24529. static size_t cyw_bus_specific_tx(uint32_t *data, uint16_t len);
  24530. // WLAN frame transmission
  24531. static size_t mg_cyw_tx(unsigned int ifc, void *data, size_t len) {
  24532. struct data_hdr *hdr = (struct data_hdr *) txdata;
  24533. uint16_t txlen = (uint16_t) (len + sizeof(*hdr));
  24534. memset(txdata, 0, sizeof(*hdr));
  24535. memcpy((uint8_t *) txdata + sizeof(*hdr), data, len);
  24536. // TODO(): hdr->bdc.priority = map IP to TOS if supporting QoS/ToS
  24537. hdr->bdc.flags = 2 << 4; // BDC version 2
  24538. hdr->bdc.flags2 = (uint8_t) ifc; // 0 -> STA, 1 -> AP
  24539. // hdr->bdc.data_offset = 0; // actually zeroed above
  24540. hdr->sdpcm.len = txlen;
  24541. hdr->sdpcm._len = (uint16_t) ~txlen;
  24542. hdr->sdpcm.sw_hdr.sequence = ++s_tx_seqno;
  24543. hdr->sdpcm.sw_hdr.channel_and_flags = CYW_SDPCM_DATA_HDR,
  24544. hdr->sdpcm.sw_hdr.header_length = offsetof(struct data_hdr, bdc);
  24545. return cyw_bus_specific_tx(txdata, txlen);
  24546. }
  24547. // WLAN event handling
  24548. #pragma pack(push, 1)
  24549. // all in network order
  24550. struct eth_hdr { // TODO(scaprile) reuse 'eth' in net_builtin.c
  24551. uint8_t dest[6];
  24552. uint8_t src[6];
  24553. uint16_t type;
  24554. };
  24555. struct bcm_vendor_hdr {
  24556. uint16_t subtype; // vendor specific: 0x8001
  24557. uint16_t length; // bytes following this field
  24558. uint8_t version; // 0
  24559. uint8_t oui[3]; // vendor specific: 0x00 0x10 0x18
  24560. uint16_t usr_subtype;
  24561. };
  24562. struct bcm_evnt_hdr {
  24563. uint16_t version; // 1: fields up to ifname; 2: as shown
  24564. uint16_t flags;
  24565. uint32_t event_type;
  24566. uint32_t status;
  24567. uint32_t reason;
  24568. uint32_t auth_type;
  24569. uint32_t datalen;
  24570. uint8_t addr[6]; // Station address (if applicable)
  24571. char ifname[16];
  24572. uint8_t ifidx;
  24573. uint8_t bss_cfg_idx;
  24574. };
  24575. struct evnt_msg {
  24576. struct eth_hdr eth;
  24577. // struct vendor_hdr; but we only handle Broadcom (Wi-Fi processor) events
  24578. struct bcm_vendor_hdr bcm;
  24579. struct bcm_evnt_hdr event;
  24580. };
  24581. #pragma pack(pop)
  24582. struct scan_result;
  24583. static void cyw_handle_scan_result(uint32_t status, struct scan_result *data,
  24584. size_t len);
  24585. // Do not call any IOCTL functions here, otherwise revise cyw_ioctl_wait()
  24586. static void cyw_handle_bdc_evnt(struct bdc_hdr *bdc, size_t len) {
  24587. struct evnt_msg *msg = (struct evnt_msg *) &bdc[bdc->data_offset + 1];
  24588. MG_VERBOSE(("%u bytes event", len));
  24589. if (mg_log_level >= MG_LL_VERBOSE) mg_hexdump((void *) bdc, len);
  24590. if (mg_ntohs(msg->eth.type) != 0x886C || msg->bcm.oui[0] != 0x00 ||
  24591. msg->bcm.oui[1] != 0x10 || msg->bcm.oui[2] != 0x18)
  24592. return; // discard if not Broadcom
  24593. if (mg_ntohl(msg->event.datalen) <=
  24594. len - ((uint8_t *) msg - (uint8_t *) bdc)) {
  24595. uint32_t event_type = mg_ntohl(msg->event.event_type);
  24596. uint32_t status = mg_ntohl(msg->event.status);
  24597. uint32_t reason = mg_ntohl(msg->event.reason);
  24598. uint16_t flags = mg_ntohs(msg->event.flags);
  24599. MG_VERBOSE(("BCM evt %lu %lu %lu %p", event_type, status, reason, flags));
  24600. if (event_type == 16 && status == 0) { // Link
  24601. s_link = flags & 1;
  24602. } else if (event_type == 46 && s_link) { // PSK sup with link up
  24603. if (status == 6) { // Keyed
  24604. } else if ((status == 4 || status == 8 || status == 10) &&
  24605. reason == 15) { // Wait M1/M3/G1
  24606. MG_ERROR(("AUTH TIMEOUT"));
  24607. s_auth = false;
  24608. } else {
  24609. MG_ERROR(("AUTH FAILED"));
  24610. s_auth = false;
  24611. }
  24612. } else if (event_type == 3 && status != 6) { // Auth (not unsolicited)
  24613. if (status == 0) { // Success
  24614. s_auth = true;
  24615. } else {
  24616. MG_ERROR(("AUTH TIMEOUT"));
  24617. s_auth = false;
  24618. }
  24619. } else if (event_type == 1) { // Join
  24620. if (status == 0) { // Success
  24621. s_join = true;
  24622. } else {
  24623. MG_ERROR(("%s", status == 3 /* No networks */ ? "SSID NOT FOUND"
  24624. : "JOIN FAILED"));
  24625. s_join = false;
  24626. mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_CONNECT_ERR, &status);
  24627. }
  24628. } else if (event_type == 12 || event_type == 5) { // Disassoc, Deauth
  24629. s_auth = false;
  24630. } else if (event_type == 69) { // Scan result
  24631. struct scan_result *data = (struct scan_result *) (&msg->event + 1);
  24632. size_t dlen = mg_ntohl(msg->event.datalen);
  24633. if (dlen > len - ((uint8_t *) data - (uint8_t *) bdc)) return;
  24634. cyw_handle_scan_result(status, data, dlen);
  24635. }
  24636. } // else silently discard
  24637. }
  24638. static bool cyw_ioctl_get_(unsigned int ifc, unsigned int cmd, void *data,
  24639. size_t len);
  24640. static bool cyw_ioctl_set_(unsigned int ifc, unsigned int cmd, void *data,
  24641. size_t len);
  24642. static bool cyw_ioctl_iovar_get_(unsigned int ifc, char *var, void *data,
  24643. size_t len);
  24644. static bool cyw_ioctl_iovar_set_(unsigned int ifc, char *var, void *data,
  24645. size_t len);
  24646. // clang-format off
  24647. // convenience: ioctl funcs on default ifc (0), as only AP needs ifc 1
  24648. __attribute__((unused)) static bool cyw_ioctl_get(unsigned int cmd, void *data, size_t len) { return cyw_ioctl_get_(0, cmd, data, len); }
  24649. static bool cyw_ioctl_set(unsigned int cmd, void *data, size_t len) { return cyw_ioctl_set_(0, cmd, data, len); }
  24650. static bool cyw_ioctl_iovar_get(char *var, void *data, size_t len) { return cyw_ioctl_iovar_get_(0, var, data, len); }
  24651. static bool cyw_ioctl_iovar_set(char *var, void *data, size_t len) { return cyw_ioctl_iovar_set_(0, var, data, len); }
  24652. // clang-format on
  24653. // Wi-Fi network stuff
  24654. // clang-format off
  24655. static bool cyw_wifi_connect(char *ssid, char *pass) {
  24656. uint32_t sup_wpa[2] = {0, 1}; // bss index 0 = STA, not open
  24657. static const uint32_t eapver[2] = {0, (uint32_t) -1}, // accept AP version
  24658. tmo[2] = {0, 2500};
  24659. uint32_t data[64/4 + 1]; // max pass length: 64 for WPA, 128 for WPA3 SAE
  24660. uint16_t *da = (uint16_t *) data;
  24661. unsigned int len;
  24662. uint32_t val;
  24663. val = 4; // security type: 0 for none, 2 for WPA, 4 for WPA2/WPA3, 6 for mixed WPA/WPA2
  24664. // sup_wpa[1] = 0 if not using security
  24665. if (!(cyw_ioctl_set(134 /* SET_WSEC */, (uint8_t *)&val, sizeof(val))
  24666. && cyw_ioctl_iovar_set("bsscfg:sup_wpa", (void *)sup_wpa, sizeof(sup_wpa))
  24667. && cyw_ioctl_iovar_set("bsscfg:sup_wpa2_eapver", (void *)eapver, sizeof(eapver))
  24668. && cyw_ioctl_iovar_set("bsscfg:sup_wpa_tmo", (void *)tmo, sizeof(tmo)))
  24669. ) return false;
  24670. mg_delayms(2); // allow radio firmware to be ready
  24671. // skip if not using auth
  24672. memset(data, 0, sizeof(data));
  24673. len = strlen(pass);
  24674. da[0] = (uint16_t) len;
  24675. da[1] = 1; // indicates wireless security key, skip for WPA3 SAE
  24676. memcpy((uint8_t *)data + 2 * sizeof(uint16_t), pass, len); // skip for WPA3 SAE
  24677. if (!cyw_ioctl_set(268 /* SET_WSEC_PMK */, data, sizeof(data))) return false; // skip for WPA3 SAE, sizeof/2 if supporting SAE but using WPA
  24678. // for WPA3 SAE: memcpy((uint8_t *)data + sizeof(uint16_t), pass, len); cyw_ioctl_iovar_set("sae_password", data, sizeof(data));
  24679. // resume if not using auth
  24680. val = 1; if (!cyw_ioctl_set(20 /* SET_INFRA */, (uint8_t *)&val, sizeof(val))) return false;
  24681. val = 0; // auth type: 0 for open, 3 for SAE
  24682. if (!cyw_ioctl_set(22 /* SET_AUTH */, (uint8_t *)&val, sizeof(val))) return false;
  24683. val = 1; // MFP capable: 1 for yes, 0 for no; recommended to be set for WPA2+ (2 for 'required', WPA3)
  24684. cyw_ioctl_iovar_set("mfp", (uint8_t *)&val, sizeof(val)); // Old chipsets do not support MFP
  24685. val = 0x80; // auth type: 0 for none, 4 for WPA PSK, 0x80 for WPA2 PSK, 0x40000 for WPA3 SAE PSK
  24686. if (!cyw_ioctl_set(165 /* SET_WPA_AUTH */, (uint8_t *)&val, sizeof(val))) return false;
  24687. len = strlen(ssid);
  24688. data[0] = (uint32_t) len;
  24689. memcpy((uint8_t *)&data[1], ssid, len);
  24690. if (!cyw_ioctl_set(26 /* SET_SSID */, data, len + sizeof(uint32_t))) return false;
  24691. return true;
  24692. }
  24693. static bool cyw_wifi_disconnect(void) {
  24694. return cyw_ioctl_set(52 /* DISASSOC */, NULL, 0);
  24695. }
  24696. // For AP functions, we use explicit ifc selection; both for clarity and maintenance, as some actions are performed on ifc 0, with or without a bss_index, and others are performed on ifc 1
  24697. static bool cyw_wifi_ap_start(char *ssid, char *pass, unsigned int channel) {
  24698. uint32_t data[64/4 + 2]; // max pass length: 64 for WPA, 128 for WPA3 SAE
  24699. uint16_t *da = (uint16_t *) data;
  24700. unsigned int len;
  24701. uint32_t val;
  24702. // CHIP DEPENDENCY
  24703. // RPi set the AMPDU parameter for AP (window size = 2) *****************
  24704. // val = 2 ; cyw_ioctl_iovar_set_(0, "ampdu_ba_wsize", (uint8_t *)&val, sizeof(val));
  24705. // some chips might require to turn APSTA off and issue a SET_AP IOCTL
  24706. len = strlen(ssid);
  24707. data[0] = 1; // bss index 1 = AP
  24708. data[1] = (uint32_t) len;
  24709. memcpy((uint8_t *)&data[2], ssid, len);
  24710. // TODO(scaprile): this takes some time to process, or requires a delay before doing it
  24711. if (!cyw_ioctl_iovar_set_(0, "bsscfg:ssid", (uint8_t *)&data, len + 2 * sizeof(uint32_t))) return false;
  24712. // TODO(scaprile): but sometimes this one takes some time to process
  24713. val = (uint32_t) channel; if (!cyw_ioctl_set_(0, 30 /* SET_CHANNEL */, (uint8_t *)&val, sizeof(val))) return false;
  24714. data[0] = 1; // bss index 1 = AP
  24715. data[1] = 0x00400004; // security type: 0 for none, 0x00200002 for WPA, 0x00400004 for WPA2, 0x01000004 for WPA3, 0x01400004 for mixed WPA2/WPA3, 0x00400006 for mixed WPA/WPA2
  24716. // NOTE(): WHD writes & 0xFF if WPS is not enabled (?)
  24717. if (!cyw_ioctl_iovar_set_(0, "bsscfg:wsec", (uint8_t *)&data, 2 * sizeof(uint32_t))) return false;
  24718. val = 1; // MFP capable: 1 for yes, 0 for no; recommended to be set for WPA2+ (2 for 'required', WPA3)
  24719. cyw_ioctl_iovar_set_(1, "mfp", (uint8_t *)&val, sizeof(val)); // Old chipsets do not support MFP
  24720. mg_delayms(2); // allow radio firmware to be ready
  24721. // skip if not using auth
  24722. // WPA, WPA2, mixed WPA/WPA2, mixed WPA2/WPA3
  24723. // NOTE(): WHD does not set SAE password for shared WPA2/WPA3, same do we
  24724. memset(data, 0, sizeof(data));
  24725. len = strlen(pass);
  24726. da[0] = (uint16_t) len; // skip for WPA3 SAE (43430 does NOT support WPA3 in AP)
  24727. da[1] = 1; // indicates wireless security key, skip for WPA3 SAE
  24728. memcpy((uint8_t *)data + 2 * sizeof(uint16_t), pass, len); // skip for WPA3 SAE
  24729. if (!cyw_ioctl_set_(1, 268 /* SET_WSEC_PMK */, data, sizeof(data))) return false; // skip for WPA3 SAE, sizeof/2 if supporting SAE but using WPA
  24730. /* for WPA3 SAE:
  24731. memcpy((uint8_t *)data + sizeof(uint16_t), pass, len);
  24732. cyw_ioctl_iovar_set_(1, "sae_password", data, sizeof(data)); */
  24733. /* for WPA3 or mixed WPA2/WPA3:
  24734. val = 5 ; cyw_ioctl_iovar_set_(1, "sae_max_pwe_loop", (uint8_t *)&val, sizeof(val)); // Some chipsets do not support this */
  24735. // resume if not using auth
  24736. data[0] = 1; // bss index 1 = AP
  24737. data[1] = 0x80; // auth type: 0 for none, 4 for WPA PSK, 0x80 for WPA2 PSK, 0x40000 for WPA3 SAE PSK; ored if mixed
  24738. if (!cyw_ioctl_iovar_set_(0, "bsscfg:wpa_auth", (uint8_t *)&data, 2 * sizeof(uint32_t))) return false;
  24739. val = 1 /* auto */; if (!cyw_ioctl_set_(1, 110 /* SET_GMODE */, (uint8_t *)&val, sizeof(val))) return false;
  24740. // Set multicast tx rate to 11Mbps, may fail in some chipsets, we are enforcing it
  24741. val = 11000000 / 500000; if (!cyw_ioctl_iovar_set_(1, "2g_mrate", (uint8_t *)&val, sizeof(val))) return false;
  24742. val = 1; if (!cyw_ioctl_set_(1, 78 /* SET_DTIMPRD */, (uint8_t *)&val, sizeof(val))) return false;
  24743. data[0] = 1; // bss index 1 = AP
  24744. data[1] = 1; // UP
  24745. // TODO(scaprile): this takes a long time to process
  24746. if (!cyw_ioctl_iovar_set_(0, "bss", (uint8_t *)&data, 2 * sizeof(uint32_t))) return false;
  24747. return true;
  24748. }
  24749. static bool cyw_wifi_ap_stop(void) {
  24750. uint32_t data[2];
  24751. data[0] = 1; // bss index 1 = AP
  24752. data[1] = 0; // DOWN
  24753. if (!cyw_ioctl_iovar_set_(0, "bss", (uint8_t *)&data, 2 * sizeof(uint32_t))) return false;
  24754. // DO WE NEED TO CLEAR CHANNEL ???
  24755. // CHIP DEPENDENCY
  24756. //val = 8 ; cyw_ioctl_iovar_set_(0, "ampdu_ba_wsize", (uint8_t *)&val, sizeof(val));
  24757. return true;
  24758. }
  24759. // WLAN scan handling
  24760. #pragma pack(push, 1)
  24761. // in little endian
  24762. struct wifi_scan_opt {
  24763. uint32_t version;
  24764. uint16_t action;
  24765. uint16_t _;
  24766. uint32_t ssid_len;
  24767. uint8_t ssid[32];
  24768. uint8_t bssid[6];
  24769. int8_t bss_type;
  24770. int8_t scan_type;
  24771. int32_t nprobes;
  24772. int32_t active_time;
  24773. int32_t passive_time;
  24774. int32_t home_time;
  24775. int32_t channel_num;
  24776. uint16_t channel_list[1];
  24777. };
  24778. #pragma pack(pop)
  24779. static bool cyw_wifi_scan(void) {
  24780. struct wifi_scan_opt opts;
  24781. memset(&opts, 0, sizeof(opts));
  24782. opts.version = 1;
  24783. opts.action = 1; // start
  24784. opts._ = 0;
  24785. memset(opts.bssid, 0xff, sizeof(opts.bssid));
  24786. opts.bss_type = 2; // any
  24787. opts.nprobes = -1;
  24788. opts.active_time = -1;
  24789. opts.passive_time = -1;
  24790. opts.home_time = -1;
  24791. opts.channel_num = 0;
  24792. opts.channel_list[0] = 0;
  24793. return cyw_ioctl_iovar_set("escan", (uint8_t *)&opts, sizeof(opts));
  24794. }
  24795. #pragma pack(push, 1)
  24796. // in little endian
  24797. struct scan_bss {
  24798. uint32_t version; // version field
  24799. uint32_t length; // byte length of data in this record, starting at version and including IEs
  24800. uint8_t BSSID[6]; // Unique 6-byte MAC address
  24801. uint16_t beacon_period; // Interval between two consecutive beacon frames. Units are Kusec
  24802. uint16_t capability; // Capability information
  24803. uint8_t SSID_len; // SSID length
  24804. uint8_t SSID[32]; // Array to store SSID
  24805. uint8_t reserved1[1]; // Reserved(padding)
  24806. uint32_t rateset_count; // Count of rates in this set
  24807. uint8_t rateset_rates[16]; // rates in 500kbps units, higher bit set if basic
  24808. uint16_t chanspec; // Channel specification for basic service set
  24809. uint16_t atim_window; // Announcement traffic indication message window size. Units are Kusec
  24810. uint8_t dtim_period; // Delivery traffic indication message period
  24811. uint8_t reserved2[1]; // Reserved(padding)
  24812. int16_t RSSI; // receive signal strength (in dBm)
  24813. int8_t phy_noise; // noise (in dBm)
  24814. uint8_t n_cap; // BSS is 802.11n Capable
  24815. uint8_t reserved3[2]; // Reserved(padding)
  24816. uint32_t nbss_cap; // 802.11n BSS Capabilities (based on HT_CAP_*)
  24817. uint8_t ctl_ch; // 802.11n BSS control channel number
  24818. uint8_t reserved4[3]; // Reserved(padding)
  24819. uint32_t reserved32[1]; // Reserved for expansion of BSS properties
  24820. uint8_t flags; // flags
  24821. uint8_t vht_cap; // BSS is vht capable
  24822. uint8_t reserved5[2]; // Reserved(padding)
  24823. uint8_t basic_mcs[16]; // 802.11N BSS required MCS set
  24824. uint16_t ie_offset; // offset at which IEs start, from beginning
  24825. uint16_t reserved16[1]; // Reserved(padding)
  24826. uint32_t ie_length; // byte length of Information Elements
  24827. int16_t SNR; // Average SNR during frame reception
  24828. };
  24829. struct scan_result {
  24830. uint32_t buflen;
  24831. uint32_t version;
  24832. uint16_t sync_id;
  24833. uint16_t bss_count;
  24834. struct scan_bss bss[1];
  24835. };
  24836. #pragma pack(pop)
  24837. // CHIP DEPENDENCY
  24838. #define CYW_BSS_BANDMASK 0xc000
  24839. #define CYW_BSS_BAND2G 0
  24840. //
  24841. static void cyw_handle_scan_result(uint32_t status, struct scan_result *data, size_t len) {
  24842. MG_VERBOSE(("scan event, status: %ld", status));
  24843. if (status == 0) { // SUCCESS
  24844. MG_VERBOSE(("scan complete"));
  24845. mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_SCAN_END, NULL);
  24846. } else if (status == 8) { // PARTIAL
  24847. struct mg_wifi_scan_bss_data bss;
  24848. struct scan_bss *sbss = data->bss;
  24849. unsigned int band = sbss->chanspec & CYW_BSS_BANDMASK;
  24850. if (data->version != 109 || data->bss_count != 1) {
  24851. MG_ERROR(("Unsupported: %lu %u", data->version, data->bss_count));
  24852. return;
  24853. }
  24854. if (sbss->length > len - offsetof(struct scan_result, bss) || sbss->SSID_len > sizeof(sbss->SSID) || sbss->ie_offset < sizeof(*sbss) || sbss->ie_offset > (sizeof(*sbss) + sbss->ie_length) || sbss->ie_offset + sbss->ie_length > sbss->length)
  24855. return; // silently discard malformed data
  24856. if (!(sbss->flags & MG_BIT(2))) return; // RSSI_ONCHANNEL, ignore off-channel results
  24857. bss.SSID = mg_str_n((char *)sbss->SSID, sbss->SSID_len);
  24858. bss.BSSID = (char *)sbss->BSSID;
  24859. bss.RSSI = (int8_t)sbss->RSSI;
  24860. bss.has_n = sbss->n_cap != 0;
  24861. bss.channel = bss.has_n ? sbss->ctl_ch : (uint8_t)(sbss->chanspec & 0xff); // n 40MHz vs a/b/g and 20MHz
  24862. bss.band = band & CYW_BSS_BAND2G ? MG_WIFI_BAND_2G : MG_WIFI_BAND_5G;
  24863. bss.security = (sbss->capability & MG_BIT(4) /* CAP_PRIVACY */) ? MG_WIFI_SECURITY_WEP : MG_WIFI_SECURITY_OPEN;
  24864. { // travel IEs (Information Elements) in search of security definitions
  24865. const uint8_t wot1[4] = {0x00, 0x50, 0xf2, 0x01}; // WPA_OUI_TYPE1
  24866. uint8_t *ie = (uint8_t *)sbss + sbss->ie_offset;
  24867. int bytes = (int) sbss->ie_length;
  24868. while (bytes > 0 && ie[1] + 2 < bytes) { // ie[0] -> type, ie[1] -> bytes from ie[2]
  24869. if (ie[0] == 48 /* IE_ID_RSN */) bss.security |= MG_WIFI_SECURITY_WPA2;
  24870. if (ie[0] == 221 /* IE_ID_VENDOR_SPECIFIC */ && memcmp(&ie[2], wot1, 4) == 0)
  24871. bss.security |= MG_WIFI_SECURITY_WPA;
  24872. ie += ie[1] + 2;
  24873. bytes -= ie[1] + 2;
  24874. }
  24875. }
  24876. MG_VERBOSE(("BSS: %.*s (%u) (%M) %d dBm %u", bss.SSID.len, bss.SSID.buf, bss.channel, mg_print_mac, bss.BSSID, (int) bss.RSSI, bss.security));
  24877. mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_SCAN_RESULT, &bss);
  24878. } else {
  24879. MG_ERROR(("scan error"));
  24880. }
  24881. }
  24882. // clang-format on
  24883. // IOCTL stuff. All values read and written are in little endian format
  24884. static uint16_t s_ioctl_reqid;
  24885. // CDC handler for waiting loop
  24886. static uint8_t *s_ioctl_resp;
  24887. static bool s_ioctl_err;
  24888. static void cyw_handle_cdc(struct cdc_hdr *cdc, size_t len) {
  24889. uint8_t *r = (uint8_t *) cdc + sizeof(*cdc);
  24890. MG_VERBOSE(("%u bytes CDC frame", len));
  24891. if ((cdc->flags >> 16) != s_ioctl_reqid) return;
  24892. if (cdc->flags & 1) {
  24893. MG_ERROR(("IOCTL error: %ld", -cdc->status));
  24894. s_ioctl_err = true;
  24895. return;
  24896. }
  24897. if (mg_log_level >= MG_LL_VERBOSE) mg_hexdump((void *) cdc, len);
  24898. MG_VERBOSE(("IOCTL result: %02x %02x %02x %02x ..", r[0], r[1], r[2], r[3]));
  24899. s_ioctl_resp = r;
  24900. }
  24901. // NOTE(): alt no loop handler dispatching IOCTL response to current handler:
  24902. // static void *s_ioctl_hnd; *s_ioctl_hnd(ioctl, len);
  24903. // app is a state machine calling get/sets and advancing via these callbacks
  24904. #pragma pack(push, 1)
  24905. // all little endian
  24906. struct ctrl_hdr {
  24907. struct sdpcm_hdr sdpcm;
  24908. struct cdc_hdr cdc;
  24909. };
  24910. #pragma pack(pop)
  24911. // IOCTL command send
  24912. static void cyw_ioctl_send_cmd(unsigned int ifc, unsigned int cmd, bool set,
  24913. size_t len) {
  24914. struct ctrl_hdr *hdr = (struct ctrl_hdr *) txdata;
  24915. uint16_t txlen = (uint16_t) (len + sizeof(*hdr));
  24916. memset(txdata, 0, sizeof(*hdr));
  24917. hdr->cdc.cmd = cmd;
  24918. hdr->cdc.olen = (uint16_t) len;
  24919. // hdr->cdc.ilen = 0; // actually zeroed above
  24920. hdr->cdc.flags = ((uint32_t) ++s_ioctl_reqid << 16) | ((ifc & 0xf) << 12) |
  24921. (set ? MG_BIT(1) : 0);
  24922. hdr->sdpcm.len = txlen;
  24923. hdr->sdpcm._len = (uint16_t) ~txlen;
  24924. hdr->sdpcm.sw_hdr.sequence = ++s_tx_seqno;
  24925. hdr->sdpcm.sw_hdr.channel_and_flags = CYW_SDPCM_CTRL_HDR;
  24926. hdr->sdpcm.sw_hdr.header_length = offsetof(struct ctrl_hdr, cdc);
  24927. cyw_bus_specific_tx(txdata, txlen);
  24928. }
  24929. // just send respective commands, response handled via CDC handler
  24930. static void cyw_ioctl_send_get(unsigned int ifc, unsigned int cmd) {
  24931. cyw_ioctl_send_cmd(ifc, cmd, false, 0);
  24932. }
  24933. static void cyw_ioctl_send_set(unsigned int ifc, unsigned int cmd, void *data,
  24934. size_t len) {
  24935. if (data != NULL && len > 0)
  24936. memcpy((uint8_t *) txdata + sizeof(struct ctrl_hdr), data, len);
  24937. cyw_ioctl_send_cmd(ifc, cmd, true, (uint16_t) len);
  24938. }
  24939. static void cyw_ioctl_send_iovar_get(unsigned int ifc, char *var, size_t len) {
  24940. unsigned int namelen = strlen(var) + 1; // include '\0'
  24941. // cmd = GET IOVAR, "set" the name...
  24942. cyw_ioctl_send_set(ifc, 262, var, len > namelen ? len : namelen);
  24943. }
  24944. static void cyw_ioctl_send_iovar_set2(unsigned int ifc, char *var, void *data1,
  24945. size_t len1, void *data2, size_t len2) {
  24946. struct ctrl_hdr *hdr = (struct ctrl_hdr *) txdata;
  24947. unsigned int namelen = strlen(var) + 1; // include '\0'
  24948. uint16_t txlen, payload_len = (uint16_t) (namelen + len1 + len2);
  24949. memcpy((uint8_t *) txdata + sizeof(*hdr), var, namelen);
  24950. memcpy((uint8_t *) txdata + namelen + sizeof(*hdr), data1, len1);
  24951. if (data2 != NULL)
  24952. memcpy((uint8_t *) txdata + namelen + sizeof(*hdr) + len1, data2, len2);
  24953. txlen = (uint16_t) (payload_len + sizeof(*hdr));
  24954. cyw_ioctl_send_cmd(ifc, 263, true, txlen); // cmd = SET IOVAR
  24955. }
  24956. __attribute__((unused)) static void cyw_ioctl_send_iovar_set(unsigned int ifc,
  24957. char *var,
  24958. void *data,
  24959. size_t len) {
  24960. cyw_ioctl_send_iovar_set2(ifc, var, data, len, NULL, 0);
  24961. }
  24962. static inline bool delayms(unsigned int ms) {
  24963. mg_delayms(ms);
  24964. return true;
  24965. }
  24966. // wait for a response, meanwhile delivering received frames and events
  24967. static bool cyw_ioctl_wait(void) {
  24968. unsigned int times = 100;
  24969. s_ioctl_resp = NULL;
  24970. s_ioctl_err = false;
  24971. do { // IOCTL response processing does not call any other IOCTL function
  24972. cyw_poll(); // otherwise we can't allow them to pile up here
  24973. // network frames will be pushed to the queue so that is safe
  24974. } while (s_ioctl_resp == NULL && !s_ioctl_err && times-- > 0 && delayms(1));
  24975. MG_VERBOSE(("resp: %lp, err: %c, times: %d", s_ioctl_resp,
  24976. s_ioctl_err ? '1' : '0', (int) times));
  24977. return s_ioctl_resp != NULL;
  24978. }
  24979. static bool cyw_ioctl_waitdata(void *data, size_t len) {
  24980. if (!cyw_ioctl_wait()) return false;
  24981. memcpy(data, s_ioctl_resp, len);
  24982. return true;
  24983. }
  24984. // send respective commands, wait for a response or timeout
  24985. static bool cyw_ioctl_get_(unsigned int ifc, unsigned int cmd, void *data,
  24986. size_t len) {
  24987. cyw_ioctl_send_get(ifc, cmd);
  24988. return cyw_ioctl_waitdata(data, len);
  24989. }
  24990. static bool cyw_ioctl_set_(unsigned int ifc, unsigned int cmd, void *data,
  24991. size_t len) {
  24992. cyw_ioctl_send_set(ifc, cmd, data, len);
  24993. return cyw_ioctl_wait();
  24994. }
  24995. static bool cyw_ioctl_iovar_get_(unsigned int ifc, char *var, void *data,
  24996. size_t len) {
  24997. cyw_ioctl_send_iovar_get(ifc, var, len);
  24998. return cyw_ioctl_waitdata(data, len);
  24999. }
  25000. static bool cyw_ioctl_iovar_set2_(unsigned int ifc, char *var, void *data1,
  25001. size_t len1, void *data2, size_t len2) {
  25002. cyw_ioctl_send_iovar_set2(ifc, var, data1, len1, data2, len2);
  25003. return cyw_ioctl_wait();
  25004. }
  25005. static bool cyw_ioctl_iovar_set_(unsigned int ifc, char *var, void *data,
  25006. size_t len) {
  25007. return cyw_ioctl_iovar_set2_(ifc, var, data, len, NULL, 0);
  25008. }
  25009. // CYW43 chipset specifics. All values read and written are in little endian
  25010. // format
  25011. #pragma pack(push, 1)
  25012. // all little endian
  25013. struct cyw_country {
  25014. uint32_t a;
  25015. int32_t rev;
  25016. uint32_t c;
  25017. };
  25018. struct clm_hdr {
  25019. uint16_t flag;
  25020. uint16_t type;
  25021. uint32_t len;
  25022. uint32_t crc;
  25023. };
  25024. #pragma pack(pop)
  25025. // worlwide rev0, TODO(): try rev 17 for 4343W
  25026. static const uint32_t country_code = 'X' + ('X' << 8) + (0 << 16);
  25027. static bool cyw_bus_specific_init();
  25028. static bool cyw_load_clmll(void *data, size_t len);
  25029. static bool cyw_load_clm(struct mg_tcpip_driver_cyw_firmware *fw) {
  25030. return cyw_load_clmll((void *) fw->clm_addr, fw->clm_len);
  25031. }
  25032. // clang-format off
  25033. static bool cyw_init(uint8_t *mac) {
  25034. struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) s_ifp->driver_data;
  25035. uint32_t val = 0;
  25036. if (!cyw_bus_specific_init()) return false;
  25037. if (!cyw_load_clm(d->fw)) return false; // Load CLM blob
  25038. // BT-ENABLED DEPENDENCY
  25039. // set Wi-Fi up
  25040. val = 0 /* disable */; cyw_ioctl_iovar_set("bus:txglom", (uint8_t *)&val, sizeof(val));
  25041. val = 1 /* on */; cyw_ioctl_iovar_set("apsta", (uint8_t *)&val, sizeof(val));
  25042. // CHIP DEPENDENCY
  25043. val = 8 ; cyw_ioctl_iovar_set("ampdu_ba_wsize", (uint8_t *)&val, sizeof(val));
  25044. val = 4 ; cyw_ioctl_iovar_set("ampdu_mpdu", (uint8_t *)&val, sizeof(val));
  25045. val = 0 /* 8K */; cyw_ioctl_iovar_set("ampdu_rx_factor", (uint8_t *)&val, sizeof(val));
  25046. //
  25047. {
  25048. struct cyw_country c;
  25049. unsigned int rev = (unsigned int) (country_code >> 16) & 0xffff;
  25050. c.c = c.a = country_code & 0xffff;
  25051. c.rev = rev == 0 ? -1 : (int32_t) rev; // if rev is 0, set it to -1, the chip will use any NVRAM/OTP configured aggregate or default to rev 0
  25052. cyw_ioctl_iovar_set("country", (void *)&c, sizeof(c));
  25053. } // this takes some time to process
  25054. { // so do some retries while enabling events of interest
  25055. // we care for SET_SSID(0), JOIN(1), AUTH(3), DEAUTH(5), DISASSOC_IND(12), LINK(16), PSK_SUP(46), SCAN_RESULT(69); all < 128
  25056. uint32_t data[128/8/4 + 1];
  25057. data[0] = 0; // bss index: 0 = STA
  25058. memset(&data[1], 0, 128/8); // mark all as not desired
  25059. data[1] = MG_BIT(0) | MG_BIT(1) | MG_BIT(3) | MG_BIT(5) | MG_BIT(12) | MG_BIT(16); // events 0 to 31
  25060. data[2] = MG_BIT(46 - 32); // events 32 to 63
  25061. data[3] = MG_BIT(69 - 64); // events 64 to 95
  25062. unsigned int times = 100;
  25063. while (times --)
  25064. if (cyw_ioctl_iovar_set("bsscfg:event_msgs", (uint8_t *)data, sizeof(data))) break;
  25065. if (times == (unsigned int) ~0) return false;
  25066. }
  25067. val = 0; if (!cyw_ioctl_set(64 /* SET_ANTDIV */, (uint8_t *)&val, sizeof(val))) return false;
  25068. if (!cyw_ioctl_set(2 /* UP, interface up */, NULL, 0)) return false;
  25069. // use PM2 power saving for max throughput
  25070. val = 200 /* ms */; if (!cyw_ioctl_iovar_set("pm2_sleep_ret", (uint8_t *)&val, sizeof(val))) return false;
  25071. // set beacon intervals to reduce power consumption while associated to an AP but idle
  25072. val = 1; if (!cyw_ioctl_iovar_set("bcn_li_bcn", (uint8_t *)&val, sizeof(val))) return false;
  25073. val = 1; if (!cyw_ioctl_iovar_set("bcn_li_dtim", (uint8_t *)&val, sizeof(val))) return false;
  25074. val = 10; if (!cyw_ioctl_iovar_set("assoc_listen", (uint8_t *)&val, sizeof(val))) return false;
  25075. val = 1 /* auto */; if (!cyw_ioctl_set(110 /* SET_GMODE */, (uint8_t *)&val, sizeof(val))) return false;
  25076. val = 0 /* any */; if (!cyw_ioctl_set(142 /* SET_BAND */, (uint8_t *)&val, sizeof(val))) return false;
  25077. if (mg_log_level >= MG_LL_DEBUG) {
  25078. char text[256]; // this is huge, but we're just starting up
  25079. if (cyw_ioctl_iovar_get("ver", (uint8_t *)text, sizeof(text))) {
  25080. unsigned int len = strnlen(text, sizeof(text));
  25081. MG_DEBUG(("Firmware:\n%.*s", len, text));
  25082. }
  25083. text[0] = '\0';
  25084. if (cyw_ioctl_iovar_get("clmver", (uint8_t *)text, sizeof(text)) && text[0] != '\0') {
  25085. unsigned int len = strnlen(text, sizeof(text));
  25086. MG_DEBUG(("CLM:\n%.*s", len, text));
  25087. }
  25088. }
  25089. {
  25090. if(cyw_ioctl_iovar_get("cur_etheraddr", mac, 6)) {
  25091. MG_DEBUG(("MAC: %M", mg_print_mac, mac));
  25092. } else {
  25093. MG_ERROR(("read MAC failed"));
  25094. }
  25095. }
  25096. return true;
  25097. }
  25098. // clang-format on
  25099. static bool cyw_load_fwll(void *fwdata, size_t fwlen, void *nvramdata,
  25100. size_t nvramlen);
  25101. static bool cyw_load_firmware(struct mg_tcpip_driver_cyw_firmware *fw) {
  25102. return cyw_load_fwll((void *) fw->code_addr, fw->code_len,
  25103. (void *) fw->nvram_addr, fw->nvram_len);
  25104. }
  25105. // clang-format off
  25106. static bool cyw_load_clmll(void *data, size_t len) {
  25107. unsigned int sent = 0, offset = 0;
  25108. struct clm_hdr hdr = {
  25109. .flag = 1 << 12 /* DLOAD_HANDLER_VER */ | MG_BIT(1) /* DL_BEGIN */,
  25110. .type = 2,
  25111. .crc = 0};
  25112. while (sent < len) {
  25113. unsigned int bytes = len - sent;
  25114. if (bytes > 1024) bytes = 1024;
  25115. if (sent + bytes >= len) hdr.flag |= MG_BIT(2); // DL_END;
  25116. hdr.len = bytes;
  25117. if (!cyw_ioctl_iovar_set2_(0, "clmload", (void *) &hdr, sizeof(hdr), (uint8_t *) data + offset, bytes))
  25118. break;
  25119. sent += bytes;
  25120. offset += bytes;
  25121. hdr.flag &= (uint16_t)~MG_BIT(1); // DL_BEGIN
  25122. }
  25123. return sent >= len;
  25124. }
  25125. // clang-format on
  25126. static void cyw_update_hash_table(void) {
  25127. // TODO(): read database, rebuild hash table
  25128. uint32_t val = 0;
  25129. val = 1;
  25130. cyw_ioctl_iovar_set2_(0, "mcast_list", (uint8_t *) &val, sizeof(val),
  25131. (uint8_t *) mcast_addr, sizeof(mcast_addr));
  25132. mg_delayms(50);
  25133. }
  25134. // CYW43 chip backplane specifics. All values read and written are in little
  25135. // endian format
  25136. // Access to chip backplane is done windowed in 32KB banks
  25137. // - addr = area base address + register offset
  25138. // - set the window address to addr & ~ADDRMSK
  25139. // - access addr & ADDRMSK for non-32-bit quantities
  25140. // - if accesing 32-bit quantities, do it on (addr & ADDRMSK) | ACCSS4B
  25141. #define CYW_CHIP_CHIPCOMMON 0x18000000
  25142. #define CYW_CHIP_BCKPLN_WINSZ 0x8000
  25143. #define CYW_CHIP_BCKPLN_ADDRMSK 0x7fff
  25144. #define CYW_CHIP_BCKPLN_ACCSS4B MG_BIT(15)
  25145. #define CYW_CHIP_BCKPLN_WRAPPOFF 0x100000
  25146. // BUS DEPENDENCY: max bus to backplane transfer size, bus function id
  25147. #define CYW_CHIP_BCKPLN_SPIMAX 64
  25148. #define CYW_CHIP_BCKPLN_SDIOMAX 1536
  25149. #if MG_ENABLE_DRIVER_CYW_SDIO
  25150. #define CYW_CHIP_BCKPLN_BUSMAX CYW_CHIP_BCKPLN_SDIOMAX
  25151. #define CYW_BUS_FUNC_CHIP CYW_SDIO_FUNC_CHIP
  25152. #else
  25153. #define CYW_CHIP_BCKPLN_BUSMAX CYW_CHIP_BCKPLN_SPIMAX
  25154. #define CYW_BUS_FUNC_CHIP CYW_SPID_FUNC_CHIP
  25155. #endif
  25156. // CHIP DEPENDENCY
  25157. #define CYW_CHIP_ARMCORE_BASE (CYW_CHIP_CHIPCOMMON + 0x3000)
  25158. #define CYW_CHIP_SOCSRAM_BASE (CYW_CHIP_CHIPCOMMON + 0x4000)
  25159. #define CYW_CHIP_ARMCORE (CYW_CHIP_ARMCORE_BASE + CYW_CHIP_BCKPLN_WRAPPOFF)
  25160. #define CYW_CHIP_SOCSRAM (CYW_CHIP_SOCSRAM_BASE + CYW_CHIP_BCKPLN_WRAPPOFF)
  25161. #define CYW_CHIP_ATCMRAM_BASE 0
  25162. #define CYW_CHIP_RAM_SIZE 0x80000
  25163. //
  25164. #define CYW_CHIP_ADDRLOW 0x1000a
  25165. #define CYW_CHIP_ADDRMID 0x1000b
  25166. #define CYW_CHIP_ADDRHIGH 0x1000c
  25167. #define CYW_CHIP_SPIFRCTRL 0x1000d
  25168. #define CYW_CHIP_CLOCKCSR 0x1000e
  25169. #define CYW_CHIP_PULLUP 0x1000f
  25170. #define CYW_CHIP_WAKEUPCTL 0x1001e
  25171. #define CYW_CHIP_SLEEPCSR 0x1001f
  25172. #define CYW_CHIP_SOCSRAM_BANKXIDX 0x010
  25173. #define CYW_CHIP_SOCSRAM_BANKXPDA 0x044
  25174. #define CYW_CHIP_AI_IOCTRL 0x408
  25175. #define CYW_CHIP_AI_RESETCTRL 0x800
  25176. static bool cyw_bus_write(unsigned int f, uint32_t addr, void *data,
  25177. uint16_t len);
  25178. static bool cyw_bus_read(unsigned int f, uint32_t addr, void *data,
  25179. uint16_t len);
  25180. // clang-format off
  25181. // set backplane window to requested area.
  25182. static void cyw_set_backplane_window(uint32_t addr) {
  25183. uint32_t val;
  25184. addr &= ~CYW_CHIP_BCKPLN_ADDRMSK;
  25185. val = (addr >> 24) & 0xff; cyw_bus_write(CYW_BUS_FUNC_CHIP, CYW_CHIP_ADDRHIGH, &val, 1);
  25186. val = (addr >> 16) & 0xff; cyw_bus_write(CYW_BUS_FUNC_CHIP, CYW_CHIP_ADDRMID, &val, 1);
  25187. val = (addr >> 8) & 0xff; cyw_bus_write(CYW_BUS_FUNC_CHIP, CYW_CHIP_ADDRLOW, &val, 1);
  25188. }
  25189. static bool cyw_core_reset(uint32_t core_base, bool check) {
  25190. uint32_t val = 0;
  25191. // core disabled after chip reset
  25192. cyw_set_backplane_window(core_base); // set backplane window for requested area; we do know offsets fall within that window
  25193. // possible CHIP DEPENDENCY: AI_RESETSTATUS check and wait (instead of these cool reads) to ensure backplane operations end
  25194. cyw_bus_read(CYW_BUS_FUNC_CHIP, (core_base + CYW_CHIP_AI_IOCTRL) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 1); // ensure backplane operations end
  25195. val = MG_BIT(1) | MG_BIT(0) /* SICF_FGC | SICF_CLOCK_EN */; cyw_bus_write(CYW_BUS_FUNC_CHIP, (core_base + CYW_CHIP_AI_IOCTRL) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 1); // reset
  25196. cyw_bus_read(CYW_BUS_FUNC_CHIP, (core_base + CYW_CHIP_AI_IOCTRL) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 1); // ensure backplane operations end
  25197. val = 0x00; cyw_bus_write(CYW_BUS_FUNC_CHIP, (core_base + CYW_CHIP_AI_RESETCTRL) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 1); // release reset
  25198. mg_delayms(1);
  25199. val = MG_BIT(0) /* SICF_CLOCK_EN */; cyw_bus_write(CYW_BUS_FUNC_CHIP, (core_base + CYW_CHIP_AI_IOCTRL) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 1);
  25200. cyw_bus_read(CYW_BUS_FUNC_CHIP, (core_base + CYW_CHIP_AI_IOCTRL) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 1); // ensure backplane operations end
  25201. mg_delayms(1);
  25202. if (check) {
  25203. // Verify only clock is enabled
  25204. cyw_bus_read(CYW_BUS_FUNC_CHIP, (core_base + CYW_CHIP_AI_IOCTRL) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 1);
  25205. if ((val & (MG_BIT(1) | MG_BIT(0)) /* SICF_FGC | SICF_CLOCK_EN) */) != MG_BIT(0)) return false;
  25206. // Verify it is not in reset state
  25207. cyw_bus_read(CYW_BUS_FUNC_CHIP, (core_base + CYW_CHIP_AI_RESETCTRL) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 1);
  25208. if (val & MG_BIT(0)) return false; // AIRC_RESET
  25209. }
  25210. return true;
  25211. }
  25212. static void cyw_socram_init(void) {
  25213. uint32_t val;
  25214. // CHIP DEPENDENCY: disable remap for SRAM_3: 43430 and 43439 only
  25215. cyw_set_backplane_window(CYW_CHIP_SOCSRAM_BASE); // set backplane window for requested area; we do know offsets fall within that window
  25216. val = 0x03; cyw_bus_write(CYW_BUS_FUNC_CHIP, ((CYW_CHIP_SOCSRAM_BASE + CYW_CHIP_SOCSRAM_BANKXIDX) & CYW_CHIP_BCKPLN_ADDRMSK), &val, sizeof(val));
  25217. val = 0x00; cyw_bus_write(CYW_BUS_FUNC_CHIP, ((CYW_CHIP_SOCSRAM_BASE + CYW_CHIP_SOCSRAM_BANKXPDA) & CYW_CHIP_BCKPLN_ADDRMSK), &val, sizeof(val));
  25218. }
  25219. // transfer is fractioned in bus-to-backplane-size units within backplane windows
  25220. static void cyw_load_data(uint32_t dest, void *data, size_t len) {
  25221. size_t sent = 0, offset = 0;
  25222. uint32_t last_addr = (uint32_t) ~0;
  25223. while (sent < len) {
  25224. size_t bytes = len - sent, avail;
  25225. uint32_t addr = dest + offset;
  25226. if (addr - last_addr >= CYW_CHIP_BCKPLN_WINSZ || last_addr == (uint32_t) ~0) {
  25227. cyw_set_backplane_window(addr); // set backplane window for requested area
  25228. last_addr = addr & ~CYW_CHIP_BCKPLN_ADDRMSK;
  25229. }
  25230. addr &= CYW_CHIP_BCKPLN_ADDRMSK;
  25231. avail = CYW_CHIP_BCKPLN_WINSZ - (unsigned int) addr; // internal backplane limit
  25232. if (bytes > avail) bytes = avail;
  25233. if (bytes > CYW_CHIP_BCKPLN_BUSMAX) bytes = CYW_CHIP_BCKPLN_BUSMAX; // bus to backplane transfer limit
  25234. cyw_bus_write(CYW_BUS_FUNC_CHIP, addr, (uint8_t *)data + offset, (uint16_t) bytes);
  25235. sent += bytes;
  25236. offset += bytes;
  25237. }
  25238. }
  25239. // CHIP DEPENDENCY: no SOCSRAM base address; start address in fwdata image (Cortex-R4 chips)
  25240. static bool cyw_load_fwll(void *fwdata, size_t fwlen, void *nvramdata, size_t nvramlen) {
  25241. uint32_t val = ((~(nvramlen / 4) & 0xffff) << 16) | (nvramlen / 4); // ~len len in 32-bit words
  25242. cyw_core_reset(CYW_CHIP_SOCSRAM, false); // cores were disabled at chip reset
  25243. cyw_socram_init();
  25244. cyw_load_data(CYW_CHIP_ATCMRAM_BASE, fwdata, fwlen);
  25245. mg_delayms(5); // TODO(scaprile): CHECK IF THIS IS ACTUALLY NEEDED
  25246. // Load NVRAM and place 'length ~length' at the end; end of chip RAM
  25247. {
  25248. const uint32_t start = CYW_CHIP_RAM_SIZE - 4 - nvramlen;
  25249. cyw_load_data(start, nvramdata, nvramlen); // nvramlen must be a multiple of 4
  25250. // RAM_SIZE is a multiple of WINSZ, so the place for len ~len will be at the end of the window
  25251. cyw_bus_write(CYW_BUS_FUNC_CHIP, (CYW_CHIP_BCKPLN_WINSZ - 4), &val, sizeof(val));
  25252. }
  25253. // Reset ARM core and check it starts
  25254. if (!cyw_core_reset(CYW_CHIP_ARMCORE, true)) return false;
  25255. return true;
  25256. }
  25257. // clang-format on
  25258. #if !MG_ENABLE_DRIVER_CYW_SDIO
  25259. // CYW43 SPI bus specifics
  25260. #define CYW_BUS_SPI_BUSCTRL 0x00 // 4 regs, 0 to 3
  25261. #define CYW_BUS_SPI_INT 0x04 // 2 regs, 4 to 5
  25262. #define CYW_BUS_SPI_INTEN 0x06 // 16-bit register
  25263. #define CYW_BUS_SPI_STATUS 0x08 // 32-bit register
  25264. #define CYW_BUS_SPI_TEST 0x14 // 32-bit register
  25265. #define CYW_BUS_SPI_RESPDLY_F1 0x1d // 8-bit register, F1: chip
  25266. #define CYW_BUS_STS_LEN(x) ((x >> 9) & 0x7ff)
  25267. static bool cyw_spi_write(unsigned int f, uint32_t addr, void *data,
  25268. uint16_t len);
  25269. static void cyw_spi_read(unsigned int f, uint32_t addr, void *data,
  25270. uint16_t len);
  25271. // clang-format off
  25272. static size_t cyw_spi_poll(uint8_t *response) {
  25273. size_t len;
  25274. uint32_t res;
  25275. // SPI poll
  25276. cyw_spi_read(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_STATUS, &res, sizeof(res));
  25277. if (res == (uint32_t) ~0 || !(res & MG_BIT(8) /* packet available */ )) return 0;
  25278. len = CYW_BUS_STS_LEN(res);
  25279. if (len == 0) { // just ack IRQ
  25280. uint16_t val = 1;
  25281. cyw_spi_write(CYW_SPID_FUNC_CHIP, CYW_CHIP_SPIFRCTRL, &val, 1);
  25282. cyw_spi_read(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_INT, &val, sizeof(val));
  25283. cyw_spi_write(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_INT, &val, sizeof(val));
  25284. return 0;
  25285. }
  25286. cyw_spi_read(CYW_SPID_FUNC_WLAN, 0, response, (uint16_t)len);
  25287. return len;
  25288. }
  25289. static size_t cyw_spi_tx(uint32_t *data, uint16_t len) {
  25290. while (len & 3) ((uint8_t *)data)[len++] = 0; // SPI 32-bit padding
  25291. return cyw_spi_write(CYW_SPID_FUNC_WLAN, 0, data, len) ? len: 0;
  25292. }
  25293. // this can be integrated in lowest level SPI read/write _driver_ functions
  25294. // (those calling hal SPI transaction functions), though is only used at start
  25295. uint32_t sw16_2(uint32_t data) {
  25296. return ((uint32_t)mg_htons((uint16_t)(data >> 16)) << 16) + mg_htons((uint16_t)data);
  25297. }
  25298. // DS 4.2.2 Table 6: signal we're working in 16-bit mode
  25299. #define CYW_SPI_16bMODE MG_BIT(2) // arbitrary bit out of the FUNC space
  25300. static bool cyw_spi_init() {
  25301. struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) s_ifp->driver_data;
  25302. uint32_t val = 0;
  25303. // DS 4.2.3 Boot-Up Sequence; WHD: other chips might require more effort
  25304. unsigned int times = 51;
  25305. while (times--) {
  25306. cyw_spi_read(CYW_SPID_FUNC_BUS | CYW_SPI_16bMODE, CYW_BUS_SPI_TEST, &val, sizeof(val));
  25307. if (sw16_2(val) == 0xFEEDBEAD) break;
  25308. mg_delayms(1);
  25309. }
  25310. if (times == (unsigned int) ~0) return false;
  25311. // DS 4.2.3 Table 6. Chip starts in 16-bit little-endian mode.
  25312. // Configure SPI and switch to 32-bit big-endian mode:
  25313. // - High-speed mode: d->hs true
  25314. // - IRQ POLARITY high
  25315. // - SPI RESPONSE DELAY 4 bytes time [not in DS] TODO(scaprile): logic ana
  25316. // - Status not sent after command, IRQ with status
  25317. val = sw16_2(0x000204a3 | (d->hs ? MG_BIT(4) : 0)); // 4 reg content
  25318. cyw_spi_write(CYW_SPID_FUNC_BUS | CYW_SPI_16bMODE, CYW_BUS_SPI_BUSCTRL, &val, sizeof(val));
  25319. mg_tcpip_call(s_ifp, MG_TCPIP_EV_DRIVER, NULL);
  25320. cyw_spi_read(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_TEST, &val, sizeof(val));
  25321. if (val != 0xFEEDBEAD) return false;
  25322. val = 4; cyw_spi_write(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_RESPDLY_F1, &val, 1);
  25323. val = 0x99; // clear error bits DATA_UNAVAILABLE, COMMAND_ERROR, DATA_ERROR, F1_OVERFLOW
  25324. cyw_spi_write(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_INT, &val, 1);
  25325. val = 0x00be; // Enable IRQs F2_F3_FIFO_RD_UNDERFLOW, F2_F3_FIFO_WR_OVERFLOW, COMMAND_ERROR, DATA_ERROR, F2_PACKET_AVAILABLE, F1_OVERFLOW
  25326. // BT-ENABLED DEPENDENCY: add F1_INTR (bit 13)
  25327. cyw_spi_write(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_INTEN, &val, sizeof(uint16_t));
  25328. // chip backplane is ready, initialize it
  25329. // request ALP (Active Low Power) clock
  25330. val = MG_BIT(3) /* ALP_REQ */; cyw_spi_write(CYW_SPID_FUNC_CHIP, CYW_CHIP_CLOCKCSR, &val, 1);
  25331. // BT-ENABLED DEPENDENCY
  25332. times = 10;
  25333. while (times--) {
  25334. cyw_spi_read(CYW_SPID_FUNC_CHIP, CYW_CHIP_CLOCKCSR, &val, 1);
  25335. if (val & MG_BIT(6)) break; // ALP_AVAIL
  25336. mg_delayms(1);
  25337. }
  25338. if (times == (unsigned int) ~0) return false;
  25339. // clear request
  25340. val = 0; cyw_spi_write(CYW_SPID_FUNC_CHIP, CYW_CHIP_CLOCKCSR, &val, 1);
  25341. cyw_set_backplane_window(CYW_CHIP_CHIPCOMMON); // set backplane window to start of CHIPCOMMON area
  25342. cyw_spi_read(CYW_SPID_FUNC_CHIP, (CYW_CHIP_CHIPCOMMON + 0x00) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 2);
  25343. if (val == 43430) val = 4343;
  25344. MG_INFO(("WLAN chip is CYW%u%c", val, val == 4343 ? 'W' : ' '));
  25345. // Load firmware (code and NVRAM)
  25346. if (!cyw_load_firmware(d->fw)) return false;
  25347. // Wait for High Throughput (HT) clock ready
  25348. times = 50;
  25349. while (times--) {
  25350. cyw_spi_read(CYW_SPID_FUNC_CHIP, CYW_CHIP_CLOCKCSR, &val, 1);
  25351. if (val & MG_BIT(7)) break; // HT_AVAIL
  25352. mg_delayms(1);
  25353. }
  25354. if (times == (unsigned int) ~0) return false;
  25355. // Wait for backplane ready
  25356. times = 1000;
  25357. while (times--) {
  25358. cyw_spi_read(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_STATUS, &val, sizeof(val));
  25359. if (val & MG_BIT(5)) break; // F2_RX_READY
  25360. mg_delayms(1);
  25361. }
  25362. if (times == (unsigned int) ~0) return false;
  25363. // CHIP DEPENDENCY
  25364. // Enable save / restore
  25365. // Configure WakeupCtrl, set HT_AVAIL in CLOCK_CSR
  25366. cyw_spi_read(CYW_SPID_FUNC_CHIP, CYW_CHIP_WAKEUPCTL, &val, 1);
  25367. val |= MG_BIT(1) /* WAKE_TILL_HT_AVAIL */; cyw_spi_write(CYW_SPID_FUNC_CHIP, CYW_CHIP_WAKEUPCTL, &val, 1);
  25368. #if 0
  25369. // Set BRCM_CARDCAP to CMD_NODEC. NOTE(): This is probably only necessary for SDIO, not SPI
  25370. val = MG_BIT(3); cyw_spi_write(CYW_SPID_FUNC_BUS, 0xf0 /* SDIOD_CCCR_BRCM_CARDCAP */, &val, 1);
  25371. #endif
  25372. // Force HT request to chip backplane
  25373. val = MG_BIT(1) /* FORCE_HT */; cyw_spi_write(CYW_SPID_FUNC_CHIP, CYW_CHIP_CLOCKCSR, &val, 1);
  25374. // Enable Keep SDIO On (KSO)
  25375. cyw_spi_read(CYW_SPID_FUNC_CHIP, CYW_CHIP_SLEEPCSR, &val, 1);
  25376. if (!(val & MG_BIT(0))) {
  25377. val |= MG_BIT(0); cyw_spi_write(CYW_SPID_FUNC_CHIP, CYW_CHIP_SLEEPCSR, &val, 1);
  25378. }
  25379. // The SPI bus can be configured for sleep (KSO controls wlan block sleep)
  25380. cyw_spi_read(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_BUSCTRL, &val, sizeof(val));
  25381. val &= ~MG_BIT(7) /* WAKE_UP */; cyw_spi_write(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_BUSCTRL, &val, sizeof(val));
  25382. // Set SPI bus sleep
  25383. val = 0x0f; cyw_spi_write(CYW_SPID_FUNC_CHIP, CYW_CHIP_PULLUP, &val, 1);
  25384. // Clear pullups. NOTE(): ?
  25385. val = 0x00; cyw_spi_write(CYW_SPID_FUNC_CHIP, CYW_CHIP_PULLUP, &val, 1);
  25386. cyw_spi_read(CYW_SPID_FUNC_CHIP, CYW_CHIP_PULLUP, &val, 1);
  25387. // Clear possible data unavailable error
  25388. cyw_spi_read(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_INTEN, &val, sizeof(uint16_t));
  25389. if (val & MG_BIT(0)) cyw_spi_write(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_INTEN, &val, sizeof(uint16_t));
  25390. return true;
  25391. }
  25392. // clang-format on
  25393. // gSPI, CYW43439 DS 4.2.1 Fig.12
  25394. #define CYW_SPID_LEN(x) ((x) &0x7FF) // bits 0-10
  25395. #define CYW_SPID_ADDR(x) (((x) &0x1FFFF) << 11) // bits 11-27,
  25396. #define CYW_SPID_FUNC(x) (((x) &3) << 28) // bits 28-29
  25397. #define CYW_SPID_INC MG_BIT(30)
  25398. #define CYW_SPID_WR MG_BIT(31)
  25399. static bool cyw_spi_write(unsigned int f, uint32_t addr, void *data,
  25400. uint16_t len) {
  25401. struct mg_tcpip_driver_cyw_data *d =
  25402. (struct mg_tcpip_driver_cyw_data *) s_ifp->driver_data;
  25403. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) d->bus;
  25404. uint32_t hdr = CYW_SPID_WR | CYW_SPID_INC | CYW_SPID_FUNC(f) |
  25405. CYW_SPID_ADDR(addr) | CYW_SPID_LEN(len); // gSPI header
  25406. // TODO(scaprile): check spin in between and timeout values, return false
  25407. if (f == CYW_SPID_FUNC_WLAN) {
  25408. uint32_t val = 0;
  25409. while ((val & MG_BIT(5)) != MG_BIT(5)) // F2 rx ready (FIFO ready)
  25410. cyw_spi_read(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_STATUS, &val, sizeof(val));
  25411. }
  25412. if (f & CYW_SPI_16bMODE)
  25413. hdr = sw16_2(hdr); // swap half-words in 16-bit little-endian mode
  25414. s->begin(NULL);
  25415. s->txn(NULL, (uint8_t *) &hdr, NULL, sizeof(hdr));
  25416. if (len <= 4) {
  25417. uint32_t pad = 0;
  25418. memcpy(&pad, data, len);
  25419. s->txn(NULL, (uint8_t *) &pad, NULL, sizeof(pad));
  25420. } else {
  25421. s->txn(NULL, (uint8_t *) data, NULL, len);
  25422. }
  25423. s->end(NULL);
  25424. return true;
  25425. }
  25426. // will write 32-bit aligned quantities to data if f == CYW_SPID_FUNC_WLAN
  25427. static void cyw_spi_read(unsigned int f, uint32_t addr, void *data,
  25428. uint16_t len) {
  25429. struct mg_tcpip_driver_cyw_data *d =
  25430. (struct mg_tcpip_driver_cyw_data *) s_ifp->driver_data;
  25431. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) d->bus;
  25432. uint32_t padding =
  25433. f == CYW_SPID_FUNC_CHIP
  25434. ? 4
  25435. : 0; // add padding to chip backplane reads as a response delay
  25436. uint32_t hdr = CYW_SPID_INC | CYW_SPID_FUNC(f) | CYW_SPID_ADDR(addr) |
  25437. CYW_SPID_LEN(len + padding); // gSPI header
  25438. if (f == CYW_SPID_FUNC_WLAN && (len & 3))
  25439. len = (len + 4) & ~3; // align WLAN transfers to 32-bit
  25440. if (f & CYW_SPI_16bMODE)
  25441. hdr = sw16_2(hdr); // swap half-words in 16-bit little-endian mode
  25442. s->begin(NULL);
  25443. s->txn(NULL, (uint8_t *) &hdr, NULL, sizeof(hdr));
  25444. if (f == CYW_SPID_FUNC_CHIP) {
  25445. uint32_t pad;
  25446. s->txn(NULL, NULL, (uint8_t *) &pad, 4); // read padding back and discard
  25447. }
  25448. s->txn(NULL, NULL, (uint8_t *) data, len);
  25449. s->end(NULL);
  25450. }
  25451. static bool cyw_bus_specific_init(void) {
  25452. return cyw_spi_init();
  25453. }
  25454. static size_t cyw_bus_specific_poll(uint32_t *response) {
  25455. return cyw_spi_poll((uint8_t *) response);
  25456. }
  25457. static size_t cyw_bus_specific_tx(uint32_t *data, uint16_t len) {
  25458. return cyw_spi_tx(data, len);
  25459. }
  25460. static bool cyw_bus_write(unsigned int f, uint32_t addr, void *data,
  25461. uint16_t len) {
  25462. if (f == CYW_SPID_FUNC_CHIP && len >= 4) addr |= CYW_CHIP_BCKPLN_ACCSS4B;
  25463. return cyw_spi_write(f, addr, data, len);
  25464. }
  25465. static bool cyw_bus_read(unsigned int f, uint32_t addr, void *data,
  25466. uint16_t len) {
  25467. cyw_spi_read(f, addr, data, len);
  25468. return true;
  25469. }
  25470. #else // MG_ENABLE_DRIVER_CYW_SDIO
  25471. // CYW43 SDIO bus specifics
  25472. // CYW4343W and CYW43439 DS 4.1 SDIO v2.0:
  25473. //- F0: max block size is 32 bytes
  25474. //- F1: max block size is 64 bytes
  25475. //- F2: max block size is 512 bytes
  25476. // clang-format off
  25477. static bool cyw_sdio_transfer(bool write, unsigned int f, uint32_t addr, void *data, uint32_t len) {
  25478. struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) s_ifp->driver_data;
  25479. struct mg_tcpip_sdio *s = (struct mg_tcpip_sdio *) d->bus;
  25480. uint32_t *ptr = (uint32_t *) data; // assume 32-bit aligned data (all except firmware)
  25481. if (write && (size_t) data & 3) { // missed, source data is not 32-bit aligned
  25482. memcpy(txdata, data, len); // copy to an aligned buffer, we know it fits
  25483. ptr = txdata;
  25484. } // all possible read destinations are 32-bit aligned
  25485. // mg_sdio_transfer requires 32-bit alignment for > 1 byte transfers
  25486. return mg_sdio_transfer(s, write, f, addr, ptr, len);
  25487. }
  25488. static size_t cyw_sdio_poll(uint32_t *response) {
  25489. uint32_t res;
  25490. uint16_t *len = (uint16_t *)&res;
  25491. // WHD: internal docs, "tag" hinting a possible packet.
  25492. // This is actually the len / ~len field of a possible struct sdpcm_hdr, if there is a packet available, or 0 if there is none.
  25493. cyw_sdio_transfer(false, CYW_SDIO_FUNC_WLAN, 0, &res, sizeof(res)); // read "the tag"
  25494. if ((len[0] | len[1]) == 0 || (len[0] ^ len[1]) != 0xffff || *len <= 4) return 0;
  25495. response[0] = res; // copy what we already read, then read the rest
  25496. cyw_sdio_transfer(false, CYW_SDIO_FUNC_WLAN, 0, response + 1, *len - sizeof(res));
  25497. return (size_t)*len;
  25498. }
  25499. static size_t cyw_sdio_tx(uint32_t *data, uint16_t len) {
  25500. return cyw_sdio_transfer(true, CYW_SDIO_FUNC_WLAN, 0, data, len) ? len: 0;
  25501. }
  25502. static bool cyw_sdio_init() {
  25503. struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) s_ifp->driver_data;
  25504. struct mg_tcpip_sdio *s = (struct mg_tcpip_sdio *) d->bus;
  25505. uint32_t val = 0;
  25506. if (!mg_sdio_init(s)) return false;
  25507. // no block transfers on F0. if (!mg_sdio_set_blksz(s, CYW_SDIO_FUNC_BUS, 32)) return false;
  25508. if (!mg_sdio_set_blksz(s, CYW_SDIO_FUNC_CHIP, 64)) return false;
  25509. if (!mg_sdio_set_blksz(s, CYW_SDIO_FUNC_WLAN, 64)) return false;
  25510. // TODO(scaprile): we don't handle SDIO interrupts, study CCCR INTEN and SDIO support (SDIO 6.3, 8)
  25511. // Enable chip backplane (F1)
  25512. if (!mg_sdio_enable_f(s, CYW_SDIO_FUNC_CHIP)) return false;
  25513. // Wait for F1 to be ready
  25514. if (!mg_sdio_waitready_f(s, CYW_SDIO_FUNC_CHIP)) return false;
  25515. // chip backplane is ready, initialize it
  25516. // request ALP (Active Low Power) clock
  25517. val = MG_BIT(5) | MG_BIT(3) | MG_BIT(0); // HW_CLKREQ_OFF ALP_REQ FORCE_ALP
  25518. cyw_sdio_transfer(true, CYW_SDIO_FUNC_CHIP, CYW_CHIP_CLOCKCSR, &val, 1);
  25519. // BT-ENABLED DEPENDENCY
  25520. unsigned int times = 10;
  25521. while (times--) {
  25522. if(!cyw_sdio_transfer(false, CYW_SDIO_FUNC_CHIP, CYW_CHIP_CLOCKCSR, &val, 1)) return false;
  25523. if (val & MG_BIT(6)) break; // ALP_AVAIL
  25524. mg_delayms(1);
  25525. }
  25526. if (times == (unsigned int) ~0) return false;
  25527. // clear request
  25528. val = 0; cyw_sdio_transfer(true, CYW_SDIO_FUNC_CHIP, CYW_CHIP_CLOCKCSR, &val, 1);
  25529. // Enable WLAN (F2)
  25530. if (!mg_sdio_enable_f(s, CYW_SDIO_FUNC_WLAN)) return false;
  25531. // Clear pullups. NOTE(): ?
  25532. val = 0x00; cyw_sdio_transfer(true, CYW_SDIO_FUNC_CHIP, CYW_CHIP_PULLUP, &val, 1);
  25533. // we don't handle wake nor OOB interrupts; SEP_INT_CTL is a vendor specific SDIO register
  25534. // SDIO interrupts: enable F2 interrupt only
  25535. cyw_set_backplane_window(CYW_CHIP_CHIPCOMMON); // set backplane window to start of CHIPCOMMON area
  25536. cyw_sdio_transfer(false, CYW_SDIO_FUNC_CHIP, (CYW_CHIP_CHIPCOMMON + 0x00) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 2);
  25537. if (val == 43430) val = 4343;
  25538. MG_INFO(("WLAN chip is CYW%u%c", val, val == 4343 ? 'W' : ' '));
  25539. // Load firmware (code and NVRAM)
  25540. if (!cyw_load_firmware(d->fw)) return false;
  25541. // Wait for High Throughput (HT) clock ready
  25542. times = 50;
  25543. while (times--) {
  25544. if(!cyw_sdio_transfer(false, CYW_SDIO_FUNC_CHIP, CYW_CHIP_CLOCKCSR, &val, 1)) return false;
  25545. if (val & MG_BIT(7)) break; // HT_AVAIL
  25546. mg_delayms(1);
  25547. }
  25548. if (times == (unsigned int) ~0) return false;
  25549. // Wait for WLAN ready
  25550. if (!mg_sdio_waitready_f(s, CYW_SDIO_FUNC_WLAN)) return false;
  25551. // CHIP DEPENDENCY
  25552. // Enable save / restore
  25553. // Configure WakeupCtrl, set HT_AVAIL in CLOCK_CSR
  25554. if(!cyw_sdio_transfer(false, CYW_SDIO_FUNC_CHIP, CYW_CHIP_WAKEUPCTL, &val, 1)) return false;
  25555. val |= MG_BIT(1) /* WAKE_TILL_HT_AVAIL */; cyw_sdio_transfer(true, CYW_SDIO_FUNC_CHIP, CYW_CHIP_WAKEUPCTL, &val, 1);
  25556. #if 0 // TODO(scaprile): Check if this is actually necessary
  25557. // Set BRCM_CARDCAP to CMD_NODEC. This is a vendor specific SDIO register
  25558. val = MG_BIT(3); cyw_sdio_transfer(true, CYW_SDIO_FUNC_BUS, 0xf0 /* SDIOD_CCCR_BRCM_CARDCAP */, &val, 1);
  25559. #endif
  25560. // Force HT request to chip backplane
  25561. val = MG_BIT(1) /* FORCE_HT */; if(!cyw_sdio_transfer(true, CYW_SDIO_FUNC_CHIP, CYW_CHIP_CLOCKCSR, &val, 1)) return false;
  25562. // Enable Keep SDIO On (KSO)
  25563. cyw_sdio_transfer(false, CYW_SDIO_FUNC_CHIP, CYW_CHIP_SLEEPCSR, &val, 1);
  25564. if (!(val & MG_BIT(0))) {
  25565. val |= MG_BIT(0); cyw_sdio_transfer(true, CYW_SDIO_FUNC_CHIP, CYW_CHIP_SLEEPCSR, &val, 1);
  25566. }
  25567. return true;
  25568. }
  25569. // clang-format on
  25570. static bool cyw_bus_specific_init(void) {
  25571. return cyw_sdio_init();
  25572. }
  25573. static size_t cyw_bus_specific_poll(uint32_t *response) {
  25574. return cyw_sdio_poll(response);
  25575. }
  25576. static size_t cyw_bus_specific_tx(uint32_t *data, uint16_t len) {
  25577. return cyw_sdio_tx(data, len);
  25578. }
  25579. static bool cyw_bus_write(unsigned int f, uint32_t addr, void *data,
  25580. uint16_t len) {
  25581. if (f == CYW_SDIO_FUNC_CHIP && len == 4) addr |= CYW_CHIP_BCKPLN_ACCSS4B;
  25582. return cyw_sdio_transfer(true, f, addr, data, (uint32_t) len);
  25583. }
  25584. static bool cyw_bus_read(unsigned int f, uint32_t addr, void *data,
  25585. uint16_t len) {
  25586. return cyw_sdio_transfer(false, f, addr, data, (uint32_t) len);
  25587. }
  25588. #endif
  25589. // Mongoose Wi-Fi API functions
  25590. bool mg_wifi_scan(void) {
  25591. return cyw_wifi_scan();
  25592. }
  25593. bool mg_wifi_connect(struct mg_wifi_data *wifi) {
  25594. s_ifp->ip = s_ip;
  25595. s_ifp->mask = s_mask;
  25596. if (s_ifp->ip == 0) s_ifp->enable_dhcp_client = true;
  25597. s_ifp->enable_dhcp_server = false;
  25598. MG_DEBUG(("Connecting to '%s'", wifi->ssid));
  25599. return cyw_wifi_connect(wifi->ssid, wifi->pass);
  25600. }
  25601. bool mg_wifi_disconnect(void) {
  25602. return cyw_wifi_disconnect();
  25603. }
  25604. bool mg_wifi_ap_start(struct mg_wifi_data *wifi) {
  25605. MG_DEBUG(("Starting AP '%s' (%u)", wifi->apssid, wifi->apchannel));
  25606. return cyw_wifi_ap_start(wifi->apssid, wifi->appass, wifi->apchannel);
  25607. }
  25608. bool mg_wifi_ap_stop(void) {
  25609. return cyw_wifi_ap_stop();
  25610. }
  25611. #endif
  25612. #ifdef MG_ENABLE_LINES
  25613. #line 1 "src/drivers/imxrt.c"
  25614. #endif
  25615. #if MG_ENABLE_TCPIP && \
  25616. (defined(MG_ENABLE_DRIVER_IMXRT10) && MG_ENABLE_DRIVER_IMXRT10) || \
  25617. (defined(MG_ENABLE_DRIVER_IMXRT11) && MG_ENABLE_DRIVER_IMXRT11) || \
  25618. (defined(MG_ENABLE_DRIVER_MCXE) && MG_ENABLE_DRIVER_MCXE)
  25619. struct imxrt_enet {
  25620. volatile uint32_t RESERVED0, EIR, EIMR, RESERVED1, RDAR, TDAR, RESERVED2[3],
  25621. ECR, RESERVED3[6], MMFR, MSCR, RESERVED4[7], MIBC, RESERVED5[7], RCR,
  25622. RESERVED6[15], TCR, RESERVED7[7], PALR, PAUR, OPD, TXIC0, TXIC1, TXIC2,
  25623. RESERVED8, RXIC0, RXIC1, RXIC2, RESERVED9[3], IAUR, IALR, GAUR, GALR,
  25624. RESERVED10[7], TFWR, RESERVED11[14], RDSR, TDSR, MRBR[2], RSFL, RSEM,
  25625. RAEM, RAFL, TSEM, TAEM, TAFL, TIPG, FTRL, RESERVED12[3], TACC, RACC,
  25626. RESERVED13[15], RMON_T_PACKETS, RMON_T_BC_PKT, RMON_T_MC_PKT,
  25627. RMON_T_CRC_ALIGN, RMON_T_UNDERSIZE, RMON_T_OVERSIZE, RMON_T_FRAG,
  25628. RMON_T_JAB, RMON_T_COL, RMON_T_P64, RMON_T_P65TO127, RMON_T_P128TO255,
  25629. RMON_T_P256TO511, RMON_T_P512TO1023, RMON_T_P1024TO2048, RMON_T_GTE2048,
  25630. RMON_T_OCTETS, IEEE_T_DROP, IEEE_T_FRAME_OK, IEEE_T_1COL, IEEE_T_MCOL,
  25631. IEEE_T_DEF, IEEE_T_LCOL, IEEE_T_EXCOL, IEEE_T_MACERR, IEEE_T_CSERR,
  25632. IEEE_T_SQE, IEEE_T_FDXFC, IEEE_T_OCTETS_OK, RESERVED14[3], RMON_R_PACKETS,
  25633. RMON_R_BC_PKT, RMON_R_MC_PKT, RMON_R_CRC_ALIGN, RMON_R_UNDERSIZE,
  25634. RMON_R_OVERSIZE, RMON_R_FRAG, RMON_R_JAB, RESERVED15, RMON_R_P64,
  25635. RMON_R_P65TO127, RMON_R_P128TO255, RMON_R_P256TO511, RMON_R_P512TO1023,
  25636. RMON_R_P1024TO2047, RMON_R_GTE2048, RMON_R_OCTETS, IEEE_R_DROP,
  25637. IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR, IEEE_R_FDXFC,
  25638. IEEE_R_OCTETS_OK, RESERVED16[71], ATCR, ATVR, ATOFF, ATPER, ATCOR, ATINC,
  25639. ATSTMP, RESERVED17[122], TGSR, TCSR0, TCCR0, TCSR1, TCCR1, TCSR2, TCCR2,
  25640. TCSR3;
  25641. };
  25642. #undef ENET
  25643. #if defined(MG_ENABLE_DRIVER_IMXRT11) && MG_ENABLE_DRIVER_IMXRT11
  25644. #define ENET ((struct imxrt_enet *) (uintptr_t) 0x40424000U)
  25645. #define ETH_DESC_CNT 5 // Descriptors count
  25646. #elif defined(MG_ENABLE_DRIVER_IMXRT10) && MG_ENABLE_DRIVER_IMXRT10
  25647. #define ENET ((struct imxrt_enet *) (uintptr_t) 0x402D8000U)
  25648. #define ETH_DESC_CNT 4 // Descriptors count
  25649. #else // MG_ENABLE_DRIVER_MCXE
  25650. #define ENET ((struct imxrt_enet *) (uintptr_t) 0x40079000U)
  25651. #define ETH_DESC_CNT 4 // Descriptor count
  25652. #endif
  25653. #define ETH_PKT_SIZE 1536 // Max frame size, 64-bit aligned
  25654. struct enet_desc {
  25655. uint16_t length; // Data length
  25656. uint16_t control; // Control and status
  25657. uint32_t *buffer; // Data ptr
  25658. };
  25659. // Descriptors: in non-cached area (TODO(scaprile)), (37.5.1.22.2 37.5.1.23.2)
  25660. // Buffers: 64-byte aligned (37.3.14)
  25661. static volatile struct enet_desc s_rxdesc[ETH_DESC_CNT] MG_ETH_RAM MG_64BYTE_ALIGNED;
  25662. static volatile struct enet_desc s_txdesc[ETH_DESC_CNT] MG_ETH_RAM MG_64BYTE_ALIGNED;
  25663. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM MG_64BYTE_ALIGNED;
  25664. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM MG_64BYTE_ALIGNED;
  25665. static struct mg_tcpip_if *s_ifp; // MIP interface
  25666. static uint16_t enet_read_phy(uint8_t addr, uint8_t reg) {
  25667. ENET->EIR |= MG_BIT(23); // MII interrupt clear
  25668. ENET->MMFR = (1 << 30) | (2 << 28) | (addr << 23) | (reg << 18) | (2 << 16);
  25669. while ((ENET->EIR & MG_BIT(23)) == 0) (void) 0;
  25670. return ENET->MMFR & 0xffff;
  25671. }
  25672. static void enet_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
  25673. ENET->EIR |= MG_BIT(23); // MII interrupt clear
  25674. ENET->MMFR =
  25675. (1 << 30) | (1 << 28) | (addr << 23) | (reg << 18) | (2 << 16) | val;
  25676. while ((ENET->EIR & MG_BIT(23)) == 0) (void) 0;
  25677. }
  25678. // MDC clock is generated from IPS Bus clock (ipg_clk); as per 802.3,
  25679. // it must not exceed 2.5MHz
  25680. // The PHY receives the PLL6-generated 50MHz clock
  25681. static bool mg_tcpip_driver_imxrt_init(struct mg_tcpip_if *ifp) {
  25682. struct mg_tcpip_driver_imxrt_data *d =
  25683. (struct mg_tcpip_driver_imxrt_data *) ifp->driver_data;
  25684. s_ifp = ifp;
  25685. // Init RX descriptors
  25686. for (int i = 0; i < ETH_DESC_CNT; i++) {
  25687. s_rxdesc[i].control = MG_BIT(15); // Own (E)
  25688. s_rxdesc[i].buffer = (uint32_t *) s_rxbuf[i]; // Point to data buffer
  25689. }
  25690. s_rxdesc[ETH_DESC_CNT - 1].control |= MG_BIT(13); // Wrap last descriptor
  25691. // Init TX descriptors
  25692. for (int i = 0; i < ETH_DESC_CNT; i++) {
  25693. // s_txdesc[i].control = MG_BIT(10); // Own (TC)
  25694. s_txdesc[i].buffer = (uint32_t *) s_txbuf[i];
  25695. }
  25696. s_txdesc[ETH_DESC_CNT - 1].control |= MG_BIT(13); // Wrap last descriptor
  25697. ENET->ECR = MG_BIT(0); // Software reset, disable
  25698. while ((ENET->ECR & MG_BIT(0))) (void) 0; // Wait until done
  25699. // Set MDC clock divider. If user told us the value, use it.
  25700. // TODO(): Otherwise, guess (currently assuming max freq)
  25701. int cr = (d == NULL || d->mdc_cr < 0) ? 24 : d->mdc_cr;
  25702. ENET->MSCR = (1 << 8) | ((cr & 0x3f) << 1); // HOLDTIME 2 clks
  25703. struct mg_phy phy = {enet_read_phy, enet_write_phy};
  25704. mg_phy_init(&phy, d->phy_addr, MG_PHY_LEDS_ACTIVE_HIGH); // MAC clocks PHY
  25705. // Select RMII mode, 100M, keep CRC, set max rx length, disable loop
  25706. ENET->RCR = (1518 << 16) | MG_BIT(8) | MG_BIT(2);
  25707. // ENET->RCR |= MG_BIT(3); // Receive all
  25708. ENET->TCR = MG_BIT(2); // Full-duplex
  25709. ENET->RDSR = (uint32_t) (uintptr_t) s_rxdesc;
  25710. ENET->TDSR = (uint32_t) (uintptr_t) s_txdesc;
  25711. ENET->MRBR[0] = ETH_PKT_SIZE; // Same size for RX/TX buffers
  25712. // MAC address filtering (bytes in reversed order)
  25713. ENET->PAUR = ((uint32_t) ifp->mac[4] << 24U) | (uint32_t) ifp->mac[5] << 16U;
  25714. ENET->PALR = (uint32_t) (ifp->mac[0] << 24U) |
  25715. ((uint32_t) ifp->mac[1] << 16U) |
  25716. ((uint32_t) ifp->mac[2] << 8U) | ifp->mac[3];
  25717. ENET->ECR = MG_BIT(8) | MG_BIT(1); // Little-endian CPU, Enable
  25718. ENET->EIMR = MG_BIT(25); // Set interrupt mask
  25719. ENET->RDAR = MG_BIT(24); // Receive Descriptors have changed
  25720. ENET->TDAR = MG_BIT(24); // Transmit Descriptors have changed
  25721. // ENET->OPD = 0x10014;
  25722. ENET->IAUR = 0;
  25723. ENET->IALR = 0;
  25724. ENET->GAUR = 0;
  25725. ENET->GALR = 0;
  25726. return true;
  25727. }
  25728. // Transmit frame
  25729. static size_t mg_tcpip_driver_imxrt_tx(const void *buf, size_t len,
  25730. struct mg_tcpip_if *ifp) {
  25731. static int s_txno; // Current descriptor index
  25732. if (len > sizeof(s_txbuf[ETH_DESC_CNT])) {
  25733. MG_ERROR(("Frame too big, %ld", (long) len));
  25734. len = (size_t) -1; // fail
  25735. } else if ((s_txdesc[s_txno].control & MG_BIT(15))) {
  25736. ifp->nerr++;
  25737. MG_ERROR(("No descriptors available"));
  25738. len = 0; // retry later
  25739. } else {
  25740. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  25741. s_txdesc[s_txno].length = (uint16_t) len; // Set data len
  25742. // Table 37-34, R, L, TC (Ready, last, transmit CRC after frame
  25743. s_txdesc[s_txno].control |=
  25744. (uint16_t) (MG_BIT(15) | MG_BIT(11) | MG_BIT(10));
  25745. ENET->TDAR = MG_BIT(24); // Descriptor ring updated
  25746. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  25747. }
  25748. (void) ifp;
  25749. return len;
  25750. }
  25751. static void mg_tcpip_driver_imxrt_update_hash_table(struct mg_tcpip_if *ifp) {
  25752. // TODO(): read database, rebuild hash table
  25753. // RM 37.3.4.3.2
  25754. uint32_t hash_table[2] = {0, 0};
  25755. // uint8_t hash64 = ((~mg_crc32(0, mcast_addr, 6)) >> 26) & 0x3f;
  25756. // hash_table[((uint8_t)hash64) >> 5] |= (1 << (hash64 & 0x1f));
  25757. hash_table[1] = MG_BIT(1); // above reduces to this for mDNS addr
  25758. ENET->GAUR = hash_table[1];
  25759. ENET->GALR = hash_table[0];
  25760. (void) ifp;
  25761. }
  25762. static bool mg_tcpip_driver_imxrt_poll(struct mg_tcpip_if *ifp, bool s1) {
  25763. if (ifp->update_mac_hash_table) {
  25764. mg_tcpip_driver_imxrt_update_hash_table(ifp);
  25765. ifp->update_mac_hash_table = false;
  25766. }
  25767. if (!s1) return false;
  25768. struct mg_tcpip_driver_imxrt_data *d =
  25769. (struct mg_tcpip_driver_imxrt_data *) ifp->driver_data;
  25770. uint8_t speed = MG_PHY_SPEED_10M;
  25771. bool up = false, full_duplex = false;
  25772. struct mg_phy phy = {enet_read_phy, enet_write_phy};
  25773. up = mg_phy_up(&phy, d->phy_addr, &full_duplex, &speed);
  25774. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  25775. // tmp = reg with flags set to the most likely situation: 100M full-duplex
  25776. // if(link is slow or half) set flags otherwise
  25777. // reg = tmp
  25778. uint32_t tcr = ENET->TCR | MG_BIT(2); // Full-duplex
  25779. uint32_t rcr = ENET->RCR & ~MG_BIT(9); // 100M
  25780. if (speed == MG_PHY_SPEED_10M) rcr |= MG_BIT(9); // 10M
  25781. if (full_duplex == false) tcr &= ~MG_BIT(2); // Half-duplex
  25782. ENET->TCR = tcr; // IRQ handler does not fiddle with these registers
  25783. ENET->RCR = rcr;
  25784. MG_DEBUG(("Link is %uM %s-duplex", rcr & MG_BIT(9) ? 10 : 100,
  25785. tcr & MG_BIT(2) ? "full" : "half"));
  25786. }
  25787. return up;
  25788. }
  25789. static uint32_t s_rxno;
  25790. #if !defined(MG_ENABLE_DRIVER_MCXE)
  25791. void ENET_IRQHandler(void);
  25792. void ENET_IRQHandler(void) {
  25793. #else
  25794. void ENET_Receive_IRQHandler(void);
  25795. void ENET_Receive_IRQHandler(void) {
  25796. #endif
  25797. ENET->EIR = MG_BIT(25); // Ack IRQ
  25798. // Frame received, loop
  25799. for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
  25800. uint32_t r = s_rxdesc[s_rxno].control;
  25801. if (r & MG_BIT(15)) break; // exit when done
  25802. // skip partial/errored frames (Table 37-32)
  25803. if ((r & MG_BIT(11)) &&
  25804. !(r & (MG_BIT(5) | MG_BIT(4) | MG_BIT(2) | MG_BIT(1) | MG_BIT(0)))) {
  25805. size_t len = s_rxdesc[s_rxno].length;
  25806. mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
  25807. }
  25808. s_rxdesc[s_rxno].control |= MG_BIT(15);
  25809. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  25810. }
  25811. ENET->RDAR = MG_BIT(24); // Receive Descriptors have changed
  25812. // If b24 == 0, descriptors were exhausted and probably frames were dropped
  25813. }
  25814. struct mg_tcpip_driver mg_tcpip_driver_imxrt = {mg_tcpip_driver_imxrt_init,
  25815. mg_tcpip_driver_imxrt_tx, NULL,
  25816. mg_tcpip_driver_imxrt_poll};
  25817. #endif
  25818. #ifdef MG_ENABLE_LINES
  25819. #line 1 "src/drivers/nxp_wifi.c"
  25820. #endif
  25821. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_NXP_WIFI) && \
  25822. MG_ENABLE_DRIVER_NXP_WIFI
  25823. bool __attribute__((weak)) netif_init(struct mg_tcpip_if *ifp) {
  25824. (void) ifp;
  25825. MG_ERROR(("Please link wifi/port/net contents"));
  25826. return false;
  25827. }
  25828. size_t __attribute__((weak))
  25829. netif_tx(const void *bfr, size_t len, struct mg_tcpip_if *ifp) {
  25830. (void) bfr;
  25831. (void) len;
  25832. netif_init(ifp);
  25833. return 0;
  25834. }
  25835. bool __attribute__((weak)) netif_connect(struct mg_wifi_data *wifi) {
  25836. (void) wifi;
  25837. return netif_init(NULL);
  25838. }
  25839. bool __attribute__((weak))
  25840. netif_poll(struct mg_tcpip_if *ifp, bool s1, mg_tcpip_event_handler_t evcb) {
  25841. (void) ifp;
  25842. (void) s1;
  25843. (void) evcb;
  25844. return false;
  25845. }
  25846. static struct mg_tcpip_if *s_ifp;
  25847. static uint32_t s_ip, s_mask;
  25848. static void wifi_cb(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
  25849. struct mg_wifi_data *wifi =
  25850. &((struct mg_tcpip_driver_nxp_wifi_data *) ifp->driver_data)->wifi;
  25851. if (wifi->apmode && ev == MG_TCPIP_EV_STATE_CHANGE &&
  25852. *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) {
  25853. MG_DEBUG(("Access Point started"));
  25854. s_ip = ifp->ip, ifp->ip = wifi->apip;
  25855. s_mask = ifp->mask, ifp->mask = wifi->apmask;
  25856. ifp->enable_dhcp_client = false;
  25857. ifp->enable_dhcp_server = true;
  25858. }
  25859. }
  25860. static bool nxp_wifi_init(struct mg_tcpip_if *ifp) {
  25861. struct mg_wifi_data *wifi =
  25862. &((struct mg_tcpip_driver_nxp_wifi_data *) ifp->driver_data)->wifi;
  25863. s_ifp = ifp;
  25864. s_ip = ifp->ip;
  25865. s_mask = ifp->mask;
  25866. ifp->pfn = wifi_cb;
  25867. if (!netif_init(ifp)) return false;
  25868. if (wifi->apmode) {
  25869. return mg_wifi_ap_start(wifi);
  25870. } else if (wifi->ssid != NULL && wifi->pass != NULL) {
  25871. return mg_wifi_connect(wifi);
  25872. }
  25873. return true;
  25874. }
  25875. bool nxp_wifi_poll(struct mg_tcpip_if *ifp, bool s1) {
  25876. return netif_poll(ifp, s1, mg_tcpip_call);
  25877. }
  25878. struct mg_tcpip_driver mg_tcpip_driver_nxp_wifi = {nxp_wifi_init, netif_tx,
  25879. NULL, nxp_wifi_poll};
  25880. bool mg_wifi_connect(struct mg_wifi_data *wifi) {
  25881. s_ifp->ip = s_ip;
  25882. s_ifp->mask = s_mask;
  25883. if (s_ifp->ip == 0) s_ifp->enable_dhcp_client = true;
  25884. s_ifp->enable_dhcp_server = false;
  25885. return netif_connect(wifi);
  25886. }
  25887. bool __attribute__((weak)) mg_wifi_scan(void) {
  25888. return netif_init(NULL);
  25889. }
  25890. bool __attribute__((weak)) mg_wifi_disconnect(void) {
  25891. return netif_init(NULL);
  25892. }
  25893. bool __attribute__((weak)) mg_wifi_ap_start(struct mg_wifi_data *wifi) {
  25894. (void) wifi;
  25895. return netif_init(NULL);
  25896. }
  25897. bool __attribute__((weak)) mg_wifi_ap_stop(void) {
  25898. return netif_init(NULL);
  25899. }
  25900. #endif
  25901. #ifdef MG_ENABLE_LINES
  25902. #line 1 "src/drivers/phy.c"
  25903. #endif
  25904. enum { // ID1 ID2
  25905. MG_PHY_KSZ8x = 0x22, // 0022 156x - KSZ8081RNB, KSZ8091RNB
  25906. MG_PHY_DP83x = 0x2000,
  25907. MG_PHY_DP83867 = 0xa231, // 2000 a231 - TI DP83867I
  25908. MG_PHY_DP83825 = 0xa140, // 2000 a140 - TI DP83825I
  25909. MG_PHY_DP83848 = 0x5ca2, // 2000 5ca2 - TI DP83848I
  25910. MG_PHY_LAN87x = 0x7, // 0007 c0fx - LAN8720
  25911. MG_PHY_RTL82x = 0x1c,
  25912. MG_PHY_RTL8201 = 0xc816, // 001c c816 - RTL8201F
  25913. MG_PHY_RTL8211 = 0xc916, // 001c c916 - RTL8211F
  25914. MG_PHY_ICS1894x = 0x15,
  25915. MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894
  25916. };
  25917. enum {
  25918. MG_PHY_REG_BCR = 0,
  25919. MG_PHY_REG_BSR = 1,
  25920. MG_PHY_REG_ID1 = 2,
  25921. MG_PHY_REG_ID2 = 3,
  25922. MG_PHY_DP83x_REG_PHYSTS = 16,
  25923. MG_PHY_DP83867_REG_PHYSTS = 17,
  25924. MG_PHY_DP83x_REG_RCSR = 23,
  25925. MG_PHY_DP83x_REG_LEDCR = 24,
  25926. MG_PHY_KSZ8x_REG_PC1R = 30,
  25927. MG_PHY_KSZ8x_REG_PC2R = 31,
  25928. MG_PHY_LAN87x_REG_SCSR = 31,
  25929. MG_PHY_RTL82x_REG_PAGESEL = 31,
  25930. MG_PHY_RTL8201_REG_RMSR = 16, // in page 7
  25931. MG_PHY_RTL8211_REG_PHYSR = 26, // in page a43
  25932. MG_PHY_ICS189432_REG_POLL = 17
  25933. };
  25934. static const char *mg_phy_id_to_str(uint16_t id1, uint16_t id2) {
  25935. switch (id1) {
  25936. case MG_PHY_DP83x:
  25937. switch (id2) {
  25938. case MG_PHY_DP83867:
  25939. return "DP83867";
  25940. case MG_PHY_DP83848:
  25941. return "DP83848";
  25942. case MG_PHY_DP83825:
  25943. return "DP83825";
  25944. default:
  25945. return "DP83x";
  25946. }
  25947. case MG_PHY_KSZ8x:
  25948. return "KSZ8x";
  25949. case MG_PHY_LAN87x:
  25950. return "LAN87x";
  25951. case MG_PHY_RTL82x:
  25952. switch (id2) {
  25953. case MG_PHY_RTL8201:
  25954. return "RTL8201";
  25955. case MG_PHY_RTL8211:
  25956. return "RTL8211";
  25957. default:
  25958. return "RTL82x";
  25959. }
  25960. case MG_PHY_ICS1894x:
  25961. return "ICS1894x";
  25962. default:
  25963. return "unknown";
  25964. }
  25965. }
  25966. void mg_phy_init(struct mg_phy *phy, uint8_t phy_addr, uint8_t config) {
  25967. uint16_t id1, id2;
  25968. phy->write_reg(phy_addr, MG_PHY_REG_BCR, MG_BIT(15)); // Reset PHY
  25969. while (phy->read_reg(phy_addr, MG_PHY_REG_BCR) & MG_BIT(15)) (void) 0;
  25970. // MG_PHY_REG_BCR[12]: Autonegotiation is default unless hw says otherwise
  25971. id1 = phy->read_reg(phy_addr, MG_PHY_REG_ID1);
  25972. id2 = phy->read_reg(phy_addr, MG_PHY_REG_ID2);
  25973. MG_INFO(("PHY ID: %#04x %#04x (%s)", id1, id2, mg_phy_id_to_str(id1, id2)));
  25974. if (id1 == MG_PHY_DP83x && id2 == MG_PHY_DP83867) {
  25975. phy->write_reg(phy_addr, 0x0d, 0x1f); // write 0x10d to IO_MUX_CFG (0x0170)
  25976. phy->write_reg(phy_addr, 0x0e, 0x170);
  25977. phy->write_reg(phy_addr, 0x0d, 0x401f);
  25978. phy->write_reg(phy_addr, 0x0e, 0x10d);
  25979. }
  25980. if (config & MG_PHY_CLOCKS_MAC) {
  25981. // Use PHY crystal oscillator (preserve defaults)
  25982. // nothing to do
  25983. } else { // MAC clocks PHY, PHY has no xtal
  25984. // Enable 50 MHz external ref clock at XI (preserve defaults)
  25985. if (id1 == MG_PHY_DP83x && id2 != MG_PHY_DP83867 && id2 != MG_PHY_DP83848) {
  25986. phy->write_reg(phy_addr, MG_PHY_DP83x_REG_RCSR, MG_BIT(7) | MG_BIT(0));
  25987. } else if (id1 == MG_PHY_KSZ8x) {
  25988. // Disable isolation (override hw, it doesn't make sense at this point)
  25989. // - #2848, some NXP boards set ISO, even though docs say they don't
  25990. phy->write_reg(phy_addr, MG_PHY_REG_BCR,
  25991. (uint16_t) (phy->read_reg(phy_addr, MG_PHY_REG_BCR) &
  25992. (uint16_t) ~MG_BIT(10)));
  25993. // now do clock stuff
  25994. phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R,
  25995. (uint16_t) (MG_BIT(15) | MG_BIT(8) | MG_BIT(7)));
  25996. } else if (id1 == MG_PHY_LAN87x) {
  25997. // nothing to do
  25998. } else if (id1 == MG_PHY_RTL82x && id2 == MG_PHY_RTL8201) {
  25999. // assume PHY has been hardware strapped properly
  26000. #if 0
  26001. phy->write_reg(phy_addr, MG_PHY_RTL82x_REG_PAGESEL, 7); // Select page 7
  26002. phy->write_reg(phy_addr, MG_PHY_RTL8201_REG_RMSR, 0x1ffa);
  26003. phy->write_reg(phy_addr, MG_PHY_RTL82x_REG_PAGESEL, 0); // Select page 0
  26004. #endif
  26005. } else if (id1 == MG_PHY_RTL82x && id2 == MG_PHY_RTL8211) {
  26006. // assume PHY has been hardware strapped properly
  26007. }
  26008. }
  26009. if (config & MG_PHY_LEDS_ACTIVE_HIGH && id1 == MG_PHY_DP83x) {
  26010. phy->write_reg(phy_addr, MG_PHY_DP83x_REG_LEDCR,
  26011. MG_BIT(9) | MG_BIT(7)); // LED status, active high
  26012. } // Other PHYs do not support this feature
  26013. }
  26014. bool mg_phy_up(struct mg_phy *phy, uint8_t phy_addr, bool *full_duplex,
  26015. uint8_t *speed) {
  26016. bool up = false;
  26017. uint16_t bsr = phy->read_reg(phy_addr, MG_PHY_REG_BSR);
  26018. if ((bsr & MG_BIT(5)) && !(bsr & MG_BIT(2))) // some PHYs latch down events
  26019. bsr = phy->read_reg(phy_addr, MG_PHY_REG_BSR); // read again
  26020. up = bsr & MG_BIT(2);
  26021. if (up && full_duplex != NULL && speed != NULL) {
  26022. uint16_t id1 = phy->read_reg(phy_addr, MG_PHY_REG_ID1);
  26023. if (id1 == MG_PHY_DP83x) {
  26024. uint16_t id2 = phy->read_reg(phy_addr, MG_PHY_REG_ID2);
  26025. if (id2 == MG_PHY_DP83867) {
  26026. uint16_t physts = phy->read_reg(phy_addr, MG_PHY_DP83867_REG_PHYSTS);
  26027. *full_duplex = physts & MG_BIT(13);
  26028. *speed = (physts & MG_BIT(15)) ? MG_PHY_SPEED_1000M
  26029. : (physts & MG_BIT(14)) ? MG_PHY_SPEED_100M
  26030. : MG_PHY_SPEED_10M;
  26031. } else {
  26032. uint16_t physts = phy->read_reg(phy_addr, MG_PHY_DP83x_REG_PHYSTS);
  26033. *full_duplex = physts & MG_BIT(2);
  26034. *speed = (physts & MG_BIT(1)) ? MG_PHY_SPEED_10M : MG_PHY_SPEED_100M;
  26035. }
  26036. } else if (id1 == MG_PHY_KSZ8x) {
  26037. uint16_t pc1r = phy->read_reg(phy_addr, MG_PHY_KSZ8x_REG_PC1R);
  26038. *full_duplex = pc1r & MG_BIT(2);
  26039. *speed = (pc1r & 3) == 1 ? MG_PHY_SPEED_10M : MG_PHY_SPEED_100M;
  26040. } else if (id1 == MG_PHY_LAN87x) {
  26041. uint16_t scsr = phy->read_reg(phy_addr, MG_PHY_LAN87x_REG_SCSR);
  26042. *full_duplex = scsr & MG_BIT(4);
  26043. *speed = (scsr & MG_BIT(3)) ? MG_PHY_SPEED_100M : MG_PHY_SPEED_10M;
  26044. } else if (id1 == MG_PHY_RTL82x) {
  26045. uint16_t id2 = phy->read_reg(phy_addr, MG_PHY_REG_ID2);
  26046. if (id2 == MG_PHY_RTL8211) {
  26047. uint16_t physr;
  26048. phy->write_reg(phy_addr, MG_PHY_RTL82x_REG_PAGESEL, 0xa43);
  26049. physr = phy->read_reg(phy_addr, MG_PHY_RTL8211_REG_PHYSR);
  26050. phy->write_reg(phy_addr, MG_PHY_RTL82x_REG_PAGESEL, 0);
  26051. *full_duplex = physr & MG_BIT(3);
  26052. *speed = (physr & MG_BIT(5)) ? MG_PHY_SPEED_1000M
  26053. : (physr & MG_BIT(4)) ? MG_PHY_SPEED_100M
  26054. : MG_PHY_SPEED_10M;
  26055. } else {
  26056. uint16_t bcr = phy->read_reg(phy_addr, MG_PHY_REG_BCR);
  26057. *full_duplex = bcr & MG_BIT(8);
  26058. *speed = (bcr & MG_BIT(13)) ? MG_PHY_SPEED_100M : MG_PHY_SPEED_10M;
  26059. }
  26060. } else if (id1 == MG_PHY_ICS1894x) {
  26061. uint16_t poll_reg = phy->read_reg(phy_addr, MG_PHY_ICS189432_REG_POLL);
  26062. *full_duplex = poll_reg & MG_BIT(14);
  26063. *speed = (poll_reg & MG_BIT(15)) ? MG_PHY_SPEED_100M : MG_PHY_SPEED_10M;
  26064. }
  26065. }
  26066. return up;
  26067. }
  26068. #ifdef MG_ENABLE_LINES
  26069. #line 1 "src/drivers/pico-w.c"
  26070. #endif
  26071. #if MG_ENABLE_TCPIP && MG_ARCH == MG_ARCH_PICOSDK && \
  26072. defined(MG_ENABLE_DRIVER_PICO_W) && MG_ENABLE_DRIVER_PICO_W
  26073. static struct mg_tcpip_if *s_ifp;
  26074. static uint32_t s_ip, s_mask;
  26075. static bool s_aplink = false, s_scanning = false;
  26076. static bool s_stalink = false, s_connecting = false;
  26077. static void wifi_cb(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
  26078. struct mg_wifi_data *wifi =
  26079. &((struct mg_tcpip_driver_pico_w_data *) ifp->driver_data)->wifi;
  26080. if (wifi->apmode && ev == MG_TCPIP_EV_STATE_CHANGE &&
  26081. *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) {
  26082. MG_DEBUG(("Access Point started"));
  26083. s_ip = ifp->ip, ifp->ip = wifi->apip;
  26084. s_mask = ifp->mask, ifp->mask = wifi->apmask;
  26085. ifp->enable_dhcp_client = false;
  26086. ifp->enable_dhcp_server = true;
  26087. }
  26088. }
  26089. static bool mg_tcpip_driver_pico_w_init(struct mg_tcpip_if *ifp) {
  26090. struct mg_tcpip_driver_pico_w_data *d =
  26091. (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data;
  26092. struct mg_wifi_data *wifi = &d->wifi;
  26093. s_ifp = ifp;
  26094. s_ip = ifp->ip;
  26095. s_mask = ifp->mask;
  26096. ifp->pfn = wifi_cb;
  26097. if (cyw43_arch_init() != 0)
  26098. return false; // initialize async_context and WiFi chip
  26099. if (wifi->apmode && wifi->apssid != NULL) {
  26100. if (!mg_wifi_ap_start(wifi)) return false;
  26101. cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac); // same MAC
  26102. } else {
  26103. cyw43_arch_enable_sta_mode();
  26104. cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac);
  26105. if (wifi->ssid != NULL) {
  26106. return mg_wifi_connect(wifi);
  26107. } else {
  26108. cyw43_arch_disable_sta_mode();
  26109. }
  26110. }
  26111. return true;
  26112. }
  26113. static size_t mg_tcpip_driver_pico_w_tx(const void *buf, size_t len,
  26114. struct mg_tcpip_if *ifp) {
  26115. struct mg_tcpip_driver_pico_w_data *d =
  26116. (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data;
  26117. return cyw43_send_ethernet(&cyw43_state,
  26118. d->wifi.apmode ? CYW43_ITF_AP : CYW43_ITF_STA, len,
  26119. buf, false) == 0
  26120. ? len
  26121. : 0;
  26122. }
  26123. static bool mg_tcpip_driver_pico_w_poll(struct mg_tcpip_if *ifp, bool s1) {
  26124. cyw43_arch_poll(); // not necessary, except when IRQs are disabled (OTA)
  26125. if (s_scanning && !cyw43_wifi_scan_active(&cyw43_state)) {
  26126. MG_VERBOSE(("scan complete"));
  26127. s_scanning = 0;
  26128. mg_tcpip_call(ifp, MG_TCPIP_EV_WIFI_SCAN_END, NULL);
  26129. }
  26130. if (ifp->update_mac_hash_table) {
  26131. // first call to _poll() is after _init(), so this is safe
  26132. cyw43_wifi_update_multicast_filter(&cyw43_state, (uint8_t *) mcast_addr,
  26133. true);
  26134. ifp->update_mac_hash_table = false;
  26135. }
  26136. if (!s1) return false;
  26137. struct mg_tcpip_driver_pico_w_data *d =
  26138. (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data;
  26139. if (d->wifi.apmode) return s_aplink;
  26140. int sdkstate = cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA);
  26141. MG_VERBOSE(("conn: %c state: %d", s_connecting ? '1' : '0', sdkstate));
  26142. if (sdkstate < 0 && s_connecting) {
  26143. mg_tcpip_call(ifp, MG_TCPIP_EV_WIFI_CONNECT_ERR, &sdkstate);
  26144. s_connecting = false;
  26145. }
  26146. return s_stalink;
  26147. }
  26148. struct mg_tcpip_driver mg_tcpip_driver_pico_w = {
  26149. mg_tcpip_driver_pico_w_init,
  26150. mg_tcpip_driver_pico_w_tx,
  26151. NULL,
  26152. mg_tcpip_driver_pico_w_poll,
  26153. };
  26154. // Called once per outstanding frame by async_context
  26155. void cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len,
  26156. const uint8_t *buf) {
  26157. mg_tcpip_qwrite((void *) buf, len, s_ifp);
  26158. (void) cb_data;
  26159. }
  26160. // Called by async_context
  26161. void cyw43_cb_tcpip_set_link_up(cyw43_t *self, int itf) {
  26162. if (itf == CYW43_ITF_AP) {
  26163. s_aplink = true;
  26164. } else {
  26165. s_stalink = true;
  26166. s_connecting = false;
  26167. }
  26168. }
  26169. void cyw43_cb_tcpip_set_link_down(cyw43_t *self, int itf) {
  26170. if (itf == CYW43_ITF_AP) {
  26171. s_aplink = false;
  26172. } else {
  26173. s_stalink = false;
  26174. // SDK calls this before we check status, don't clear s_connecting here
  26175. }
  26176. }
  26177. // there's life beyond lwIP
  26178. void pbuf_copy_partial(void) {
  26179. (void) 0;
  26180. }
  26181. static int result_cb(void *arg, const cyw43_ev_scan_result_t *data) {
  26182. struct mg_wifi_scan_bss_data bss;
  26183. bss.SSID = mg_str_n(data->ssid, data->ssid_len);
  26184. bss.BSSID = (char *) data->bssid;
  26185. bss.RSSI = (int8_t) data->rssi;
  26186. bss.has_n = 0; // SDK ignores this
  26187. bss.channel = (uint8_t) data->channel;
  26188. bss.band = MG_WIFI_BAND_2G;
  26189. // SDK-internal dependency, 2.1.0
  26190. bss.security = data->auth_mode & MG_BIT(0) ? MG_WIFI_SECURITY_WEP
  26191. : MG_WIFI_SECURITY_OPEN;
  26192. if (data->auth_mode & MG_BIT(1)) bss.security |= MG_WIFI_SECURITY_WPA;
  26193. if (data->auth_mode & MG_BIT(2)) bss.security |= MG_WIFI_SECURITY_WPA2;
  26194. MG_VERBOSE(("BSS: %.*s (%u) (%M) %d dBm %u", bss.SSID.len, bss.SSID.buf,
  26195. bss.channel, mg_print_mac, bss.BSSID, (int) bss.RSSI,
  26196. bss.security));
  26197. mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_SCAN_RESULT, &bss);
  26198. return 0;
  26199. }
  26200. bool mg_wifi_scan(void) {
  26201. cyw43_wifi_scan_options_t opts;
  26202. memset(&opts, 0, sizeof(opts));
  26203. bool res = (cyw43_wifi_scan(&cyw43_state, &opts, NULL, result_cb) == 0);
  26204. if (res) s_scanning = true;
  26205. return res;
  26206. }
  26207. bool mg_wifi_connect(struct mg_wifi_data *wifi) {
  26208. s_ifp->ip = s_ip;
  26209. s_ifp->mask = s_mask;
  26210. if (s_ifp->ip == 0) s_ifp->enable_dhcp_client = true;
  26211. s_ifp->enable_dhcp_server = false;
  26212. cyw43_arch_enable_sta_mode();
  26213. MG_DEBUG(("Connecting to '%s'", wifi->ssid));
  26214. int res = cyw43_arch_wifi_connect_async(wifi->ssid, wifi->pass,
  26215. CYW43_AUTH_WPA2_AES_PSK);
  26216. MG_VERBOSE(("res: %d", res));
  26217. if (res == 0) s_connecting = true;
  26218. return (res == 0);
  26219. }
  26220. bool mg_wifi_disconnect(void) {
  26221. cyw43_arch_disable_sta_mode();
  26222. s_connecting = false;
  26223. return true;
  26224. }
  26225. bool mg_wifi_ap_start(struct mg_wifi_data *wifi) {
  26226. MG_DEBUG(("Starting AP '%s' (%u)", wifi->apssid, wifi->apchannel));
  26227. cyw43_wifi_ap_set_channel(&cyw43_state, wifi->apchannel);
  26228. cyw43_arch_enable_ap_mode(wifi->apssid, wifi->appass,
  26229. CYW43_AUTH_WPA2_AES_PSK);
  26230. return true;
  26231. }
  26232. bool mg_wifi_ap_stop(void) {
  26233. cyw43_arch_disable_ap_mode();
  26234. return true;
  26235. }
  26236. #endif
  26237. #ifdef MG_ENABLE_LINES
  26238. #line 1 "src/drivers/ra.c"
  26239. #endif
  26240. #if MG_ENABLE_TCPIP && \
  26241. (defined(MG_ENABLE_DRIVER_RA6) && MG_ENABLE_DRIVER_RA6) || \
  26242. (defined(MG_ENABLE_DRIVER_RA8) && MG_ENABLE_DRIVER_RA8)
  26243. struct ra_etherc {
  26244. volatile uint32_t ECMR, RESERVED, RFLR, RESERVED1, ECSR, RESERVED2, ECSIPR,
  26245. RESERVED3, PIR, RESERVED4, PSR, RESERVED5[5], RDMLR, RESERVED6[3], IPGR,
  26246. APR, MPR, RESERVED7, RFCF, TPAUSER, TPAUSECR, BCFRR, RESERVED8[20], MAHR,
  26247. RESERVED9, MALR, RESERVED10, TROCR, CDCR, LCCR, CNDCR, RESERVED11, CEFCR,
  26248. FRECR, TSFRCR, TLFRCR, RFCR, MAFCR;
  26249. };
  26250. struct ra_edmac {
  26251. volatile uint32_t EDMR, RESERVED, EDTRR, RESERVED1, EDRRR, RESERVED2, TDLAR,
  26252. RESERVED3, RDLAR, RESERVED4, EESR, RESERVED5, EESIPR, RESERVED6, TRSCER,
  26253. RESERVED7, RMFCR, RESERVED8, TFTR, RESERVED9, FDR, RESERVED10, RMCR,
  26254. RESERVED11[2], TFUCR, RFOCR, IOSR, FCFTR, RESERVED12, RPADIR, TRIMD,
  26255. RESERVED13[18], RBWAR, RDFAR, RESERVED14, TBRAR, TDFAR;
  26256. };
  26257. #undef ETHERC
  26258. #undef EDMAC
  26259. #undef RASYSC
  26260. #undef ICU_IELSR
  26261. #if defined(MG_ENABLE_DRIVER_RA8) && MG_ENABLE_DRIVER_RA8
  26262. #define ETHERC ((struct ra_etherc *) (uintptr_t) 0x40354100U)
  26263. #define EDMAC ((struct ra_edmac *) (uintptr_t) 0x40354000U)
  26264. #define RASYSC ((uint32_t *) (uintptr_t) 0x4001E000U)
  26265. #define ICU_IELSR ((uint32_t *) (uintptr_t) 0x4000C300U)
  26266. #else
  26267. #define ETHERC ((struct ra_etherc *) (uintptr_t) 0x40114100U)
  26268. #define EDMAC ((struct ra_edmac *) (uintptr_t) 0x40114000U)
  26269. #define RASYSC ((uint32_t *) (uintptr_t) 0x4001E000U)
  26270. #define ICU_IELSR ((uint32_t *) (uintptr_t) 0x40006300U)
  26271. #endif
  26272. #define ETH_PKT_SIZE 1536 // Max frame size, multiple of 32
  26273. #define ETH_DESC_CNT 4 // Descriptors count
  26274. // Descriptors: 16-byte aligned
  26275. // Buffers: 32-byte aligned (27.3.1)
  26276. static volatile uint32_t s_rxdesc[ETH_DESC_CNT][4] MG_ETH_RAM MG_16BYTE_ALIGNED;
  26277. static volatile uint32_t s_txdesc[ETH_DESC_CNT][4] MG_ETH_RAM MG_16BYTE_ALIGNED;
  26278. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM MG_32BYTE_ALIGNED;
  26279. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM MG_32BYTE_ALIGNED;
  26280. static struct mg_tcpip_if *s_ifp; // MIP interface
  26281. // fastest is 3 cycles (SUB + BNE) on a 3-stage pipeline or equivalent
  26282. static inline void raspin(volatile uint32_t count) {
  26283. while (count--) (void) 0;
  26284. }
  26285. // count to get the 200ns SMC semi-cycle period (2.5MHz) calling raspin():
  26286. // SYS_FREQUENCY * 200ns / 3 = SYS_FREQUENCY / 15000000
  26287. static uint32_t s_smispin;
  26288. // Bit-banged SMI
  26289. static void smi_preamble(void) {
  26290. unsigned int i = 32;
  26291. uint32_t pir = MG_BIT(1) | MG_BIT(2); // write, mdio = 1, mdc = 0
  26292. ETHERC->PIR = pir;
  26293. while (i--) {
  26294. pir &= ~MG_BIT(0); // mdc = 0
  26295. ETHERC->PIR = pir;
  26296. raspin(s_smispin);
  26297. pir |= MG_BIT(0); // mdc = 1
  26298. ETHERC->PIR = pir;
  26299. raspin(s_smispin);
  26300. }
  26301. }
  26302. static void smi_wr(uint16_t header, uint16_t data) {
  26303. uint32_t word = (header << 16) | data;
  26304. smi_preamble();
  26305. unsigned int i = 32;
  26306. while (i--) {
  26307. uint32_t pir = MG_BIT(1) |
  26308. (word & 0x80000000 ? MG_BIT(2) : 0); // write, mdc = 0, data
  26309. ETHERC->PIR = pir;
  26310. raspin(s_smispin);
  26311. pir |= MG_BIT(0); // mdc = 1
  26312. ETHERC->PIR = pir;
  26313. raspin(s_smispin);
  26314. word <<= 1;
  26315. }
  26316. }
  26317. static uint16_t smi_rd(uint16_t header) {
  26318. smi_preamble();
  26319. unsigned int i = 16; // 2 LSb as turnaround
  26320. uint32_t pir;
  26321. while (i--) {
  26322. pir = (i > 1 ? MG_BIT(1) : 0) |
  26323. (header & 0x8000
  26324. ? MG_BIT(2)
  26325. : 0); // mdc = 0, header, set read direction at turnaround
  26326. ETHERC->PIR = pir;
  26327. raspin(s_smispin);
  26328. pir |= MG_BIT(0); // mdc = 1
  26329. ETHERC->PIR = pir;
  26330. raspin(s_smispin);
  26331. header <<= 1;
  26332. }
  26333. i = 16;
  26334. uint16_t data = 0;
  26335. while (i--) {
  26336. data <<= 1;
  26337. pir = 0; // read, mdc = 0
  26338. ETHERC->PIR = pir;
  26339. raspin(s_smispin / 2); // 1/4 clock period, 300ns max access time
  26340. data |= (uint16_t) (ETHERC->PIR & MG_BIT(3) ? 1 : 0); // read mdio
  26341. raspin(s_smispin / 2); // 1/4 clock period
  26342. pir |= MG_BIT(0); // mdc = 1
  26343. ETHERC->PIR = pir;
  26344. raspin(s_smispin);
  26345. }
  26346. return data;
  26347. }
  26348. static uint16_t raeth_read_phy(uint8_t addr, uint8_t reg) {
  26349. return smi_rd(
  26350. (uint16_t) ((1 << 14) | (2 << 12) | (addr << 7) | (reg << 2) | (2 << 0)));
  26351. }
  26352. static void raeth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
  26353. smi_wr(
  26354. (uint16_t) ((1 << 14) | (1 << 12) | (addr << 7) | (reg << 2) | (2 << 0)),
  26355. val);
  26356. }
  26357. // MDC clock is generated manually; as per 802.3, it must not exceed 2.5MHz
  26358. static bool mg_tcpip_driver_ra_init(struct mg_tcpip_if *ifp) {
  26359. struct mg_tcpip_driver_ra_data *d =
  26360. (struct mg_tcpip_driver_ra_data *) ifp->driver_data;
  26361. s_ifp = ifp;
  26362. // Init SMI clock timing. If user told us the clock value, use it.
  26363. // TODO(): Otherwise, guess
  26364. s_smispin = d->clock / 15000000;
  26365. // Init RX descriptors
  26366. for (int i = 0; i < ETH_DESC_CNT; i++) {
  26367. s_rxdesc[i][0] = MG_BIT(31); // RACT
  26368. s_rxdesc[i][1] = ETH_PKT_SIZE << 16; // RBL
  26369. s_rxdesc[i][2] = (uint32_t) s_rxbuf[i]; // Point to data buffer
  26370. }
  26371. s_rxdesc[ETH_DESC_CNT - 1][0] |= MG_BIT(30); // Wrap last descriptor
  26372. // Init TX descriptors
  26373. for (int i = 0; i < ETH_DESC_CNT; i++) {
  26374. // TACT = 0
  26375. s_txdesc[i][2] = (uint32_t) s_txbuf[i];
  26376. }
  26377. s_txdesc[ETH_DESC_CNT - 1][0] |= MG_BIT(30); // Wrap last descriptor
  26378. EDMAC->EDMR = MG_BIT(0); // Software reset, wait 64 PCLKA clocks (27.2.1)
  26379. uint32_t sckdivcr = RASYSC[8]; // get divisors from SCKDIVCR (8.2.2)
  26380. uint32_t ick = 1 << ((sckdivcr >> 24) & 7); // sys_clock div
  26381. uint32_t pcka = 1 << ((sckdivcr >> 12) & 7); // pclka div
  26382. raspin((64U * pcka) / (3U * ick));
  26383. EDMAC->EDMR = MG_BIT(6); // Initialize, little-endian (27.2.1)
  26384. MG_DEBUG(("PHY addr: %d, smispin: %d", d->phy_addr, s_smispin));
  26385. struct mg_phy phy = {raeth_read_phy, raeth_write_phy};
  26386. mg_phy_init(&phy, d->phy_addr, MG_PHY_CLOCKS_MAC);
  26387. // Select RMII mode,
  26388. ETHERC->ECMR = MG_BIT(2) | MG_BIT(1); // 100M, Full-duplex, CRC
  26389. // ETHERC->ECMR |= MG_BIT(0); // Receive all
  26390. ETHERC->RFLR = 1518; // Set max rx length
  26391. EDMAC->RDLAR = (uint32_t) (uintptr_t) s_rxdesc;
  26392. EDMAC->TDLAR = (uint32_t) (uintptr_t) s_txdesc;
  26393. // MAC address filtering (bytes in reversed order)
  26394. ETHERC->MAHR = (uint32_t) (ifp->mac[0] << 24U) |
  26395. ((uint32_t) ifp->mac[1] << 16U) |
  26396. ((uint32_t) ifp->mac[2] << 8U) | ifp->mac[3];
  26397. ETHERC->MALR = ((uint32_t) ifp->mac[4] << 8U) | ifp->mac[5];
  26398. EDMAC->TFTR = 0; // Store and forward (27.2.10)
  26399. EDMAC->FDR = 0x070f; // (27.2.11)
  26400. EDMAC->RMCR = MG_BIT(0); // (27.2.12)
  26401. ETHERC->ECMR |= MG_BIT(6) | MG_BIT(5); // TE RE
  26402. EDMAC->EESIPR = MG_BIT(18); // FR: Enable Rx (frame) IRQ
  26403. EDMAC->EDRRR = MG_BIT(0); // Receive Descriptors have changed
  26404. EDMAC->EDTRR = MG_BIT(0); // Transmit Descriptors have changed
  26405. return true;
  26406. }
  26407. // Transmit frame
  26408. static size_t mg_tcpip_driver_ra_tx(const void *buf, size_t len,
  26409. struct mg_tcpip_if *ifp) {
  26410. static int s_txno; // Current descriptor index
  26411. if (len > sizeof(s_txbuf[ETH_DESC_CNT])) {
  26412. MG_ERROR(("Frame too big, %ld", (long) len));
  26413. len = (size_t) -1; // fail
  26414. } else if ((s_txdesc[s_txno][0] & MG_BIT(31))) {
  26415. ifp->nerr++;
  26416. MG_ERROR(("No descriptors available"));
  26417. len = 0; // retry later
  26418. } else {
  26419. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  26420. s_txdesc[s_txno][1] = len << 16; // Set data len
  26421. s_txdesc[s_txno][0] |= MG_BIT(31) | 3 << 28; // (27.3.1.1) mark valid
  26422. EDMAC->EDTRR = MG_BIT(0); // Transmit request
  26423. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  26424. }
  26425. return len;
  26426. }
  26427. static bool mg_tcpip_driver_ra_poll(struct mg_tcpip_if *ifp, bool s1) {
  26428. if (ifp->update_mac_hash_table) {
  26429. EDMAC->EESIPR = MG_BIT(18) | MG_BIT(7); // FR, RMAF: Frame and mcast IRQ
  26430. ifp->update_mac_hash_table = false;
  26431. }
  26432. if (!s1) return false;
  26433. struct mg_tcpip_driver_ra_data *d =
  26434. (struct mg_tcpip_driver_ra_data *) ifp->driver_data;
  26435. uint8_t speed = MG_PHY_SPEED_10M;
  26436. bool up = false, full_duplex = false;
  26437. struct mg_phy phy = {raeth_read_phy, raeth_write_phy};
  26438. up = mg_phy_up(&phy, d->phy_addr, &full_duplex, &speed);
  26439. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  26440. // tmp = reg with flags set to the most likely situation: 100M full-duplex
  26441. // if(link is slow or half) set flags otherwise
  26442. // reg = tmp
  26443. uint32_t ecmr = ETHERC->ECMR | MG_BIT(2) | MG_BIT(1); // 100M Full-duplex
  26444. if (speed == MG_PHY_SPEED_10M) ecmr &= ~MG_BIT(2); // 10M
  26445. if (full_duplex == false) ecmr &= ~MG_BIT(1); // Half-duplex
  26446. ETHERC->ECMR = ecmr; // IRQ handler does not fiddle with these registers
  26447. MG_DEBUG(("Link is %uM %s-duplex", ecmr & MG_BIT(2) ? 100 : 10,
  26448. ecmr & MG_BIT(1) ? "full" : "half"));
  26449. }
  26450. return up;
  26451. }
  26452. void EDMAC_IRQHandler(void);
  26453. static uint32_t s_rxno;
  26454. void EDMAC_IRQHandler(void) {
  26455. struct mg_tcpip_driver_ra_data *d =
  26456. (struct mg_tcpip_driver_ra_data *) s_ifp->driver_data;
  26457. EDMAC->EESR = MG_BIT(18) | MG_BIT(7); // Ack IRQ in EDMAC 1st
  26458. ICU_IELSR[d->irqno] &= ~MG_BIT(16); // Ack IRQ in ICU last
  26459. // Frame received, loop
  26460. for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
  26461. uint32_t r = s_rxdesc[s_rxno][0];
  26462. if (r & MG_BIT(31)) break; // exit when done
  26463. // skip partial/errored frames (27.3.1.2)
  26464. if ((r & (MG_BIT(29) | MG_BIT(28)) && !(r & MG_BIT(27)))) {
  26465. size_t len = s_rxdesc[s_rxno][1] & 0xffff;
  26466. mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp); // CRC already stripped
  26467. }
  26468. s_rxdesc[s_rxno][0] |= MG_BIT(31);
  26469. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  26470. }
  26471. EDMAC->EDRRR = MG_BIT(0); // Receive Descriptors have changed
  26472. // If b0 == 0, descriptors were exhausted and probably frames were dropped,
  26473. // (27.2.9 RMFCR counts them)
  26474. }
  26475. struct mg_tcpip_driver mg_tcpip_driver_ra = {mg_tcpip_driver_ra_init,
  26476. mg_tcpip_driver_ra_tx, NULL,
  26477. mg_tcpip_driver_ra_poll};
  26478. #endif
  26479. #ifdef MG_ENABLE_LINES
  26480. #line 1 "src/drivers/rw612.c"
  26481. #endif
  26482. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_RW612) && MG_ENABLE_DRIVER_RW612
  26483. struct ENET_Type {
  26484. volatile uint32_t RESERVED_0[1], EIR, EIMR, RESERVED_1[1], RDAR, TDAR,
  26485. RESERVED_2[3], ECR, RESERVED_3[6], MMFR, MSCR, RESERVED_4[7], MIBC,
  26486. RESERVED_5[7], RCR, RESERVED_6[15], TCR, RESERVED_7[7], PALR, PAUR, OPD,
  26487. TXIC[1], RESERVED_8[3], RXIC[1], RESERVED_9[5], IAUR, IALR, GAUR, GALR,
  26488. RESERVED_10[7], TFWR, RESERVED_11[14], RDSR, TDSR, MRBR, RESERVED_12[1],
  26489. RSFL, RSEM, RAEM, RAFL, TSEM, TAEM, TAFL, TIPG, FTRL, RESERVED_13[3],
  26490. TACC, RACC, RESERVED_14[15], RMON_T_PACKETS, RMON_T_BC_PKT, RMON_T_MC_PKT,
  26491. RMON_T_CRC_ALIGN, RMON_T_UNDERSIZE, RMON_T_OVERSIZE, RMON_T_FRAG,
  26492. RMON_T_JAB, RMON_T_COL, RMON_T_P64, RMON_T_P65TO127, RMON_T_P128TO255,
  26493. RMON_T_P256TO511, RMON_T_P512TO1023, RMON_T_P1024TO2047, RMON_T_P_GTE2048,
  26494. RMON_T_OCTETS, IEEE_T_DROP, IEEE_T_FRAME_OK, IEEE_T_1COL, IEEE_T_MCOL,
  26495. IEEE_T_DEF, IEEE_T_LCOL, IEEE_T_EXCOL, IEEE_T_MACERR, IEEE_T_CSERR,
  26496. IEEE_T_SQE, IEEE_T_FDXFC, IEEE_T_OCTETS_OK, RESERVED_15[3],
  26497. RMON_R_PACKETS, RMON_R_BC_PKT, RMON_R_MC_PKT, RMON_R_CRC_ALIGN,
  26498. RMON_R_UNDERSIZE, RMON_R_OVERSIZE, RMON_R_FRAG, RMON_R_JAB,
  26499. RESERVED_16[1], RMON_R_P64, RMON_R_P65TO127, RMON_R_P128TO255,
  26500. RMON_R_P256TO511, RMON_R_P512TO1023, RMON_R_P1024TO2047, RMON_R_P_GTE2048,
  26501. RMON_R_OCTETS, IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN,
  26502. IEEE_R_MACERR, IEEE_R_FDXFC, IEEE_R_OCTETS_OK, RESERVED_17[71], ATCR,
  26503. ATVR, ATOFF, ATPER, ATCOR, ATINC, ATSTMP, RESERVED_18[122], TGSR,
  26504. CHANNEL_TCSR[4], CHANNEL_TCCR[4];
  26505. };
  26506. #undef ENET
  26507. #define ENET ((struct ENET_Type *) 0x40138000)
  26508. #define ETH_PKT_SIZE 1536 // Max frame size
  26509. #define ETH_DESC_CNT 4 // Descriptors count
  26510. #define ETH_DS 2 // Descriptor size (words)
  26511. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM MG_8BYTE_ALIGNED;
  26512. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM MG_8BYTE_ALIGNED;
  26513. static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS] MG_ETH_RAM MG_8BYTE_ALIGNED;
  26514. static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS] MG_ETH_RAM MG_8BYTE_ALIGNED;
  26515. static uint8_t s_txno; // Current TX descriptor
  26516. static uint8_t s_rxno; // Current RX descriptor
  26517. static struct mg_tcpip_if *s_ifp; // MIP interface
  26518. static uint16_t eth_read_phy(uint8_t addr, uint8_t reg) {
  26519. ENET->MMFR = MG_BIT(30) | // Start of frame delimiter
  26520. MG_BIT(29) | // Opcode
  26521. ((addr & 0x1f) << 23) | ((reg & 0x1f) << 18) | MG_BIT(17);
  26522. while ((ENET->EIR & MG_BIT(23)) == 0) (void) 0;
  26523. ENET->EIR |= MG_BIT(23);
  26524. return ENET->MMFR & 0xffff;
  26525. }
  26526. static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
  26527. ENET->MMFR = MG_BIT(30) | // Start of frame delimiter
  26528. MG_BIT(28) | // Opcode
  26529. ((addr & 0x1f) << 23) | ((reg & 0x1f) << 18) | MG_BIT(17) | val;
  26530. while ((ENET->EIR & MG_BIT(23)) == 0) (void) 0;
  26531. ENET->EIR |= MG_BIT(23);
  26532. }
  26533. static bool mg_tcpip_driver_rw612_init(struct mg_tcpip_if *ifp) {
  26534. struct mg_tcpip_driver_rw612_data *d =
  26535. (struct mg_tcpip_driver_rw612_data *) ifp->driver_data;
  26536. s_ifp = ifp;
  26537. ENET->MSCR = ((d->mdc_cr & 0x3f) << 1) | ((d->mdc_holdtime & 7) << 8);
  26538. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  26539. mg_phy_init(&phy, d->phy_addr, 0);
  26540. ENET->ECR |= MG_BIT(0); // reset ETH
  26541. // initialize descriptors
  26542. for (int i = 0; i < ETH_DESC_CNT; i++) {
  26543. s_rxdesc[i][1] = (uint32_t) s_rxbuf[i];
  26544. s_rxdesc[i][0] = MG_BIT(31); // OWN
  26545. if (i == ETH_DESC_CNT - 1) {
  26546. s_rxdesc[i][0] |= MG_BIT(29); // mark last descriptor
  26547. }
  26548. s_txdesc[i][1] = (uint32_t) s_txbuf[i];
  26549. if (i == ETH_DESC_CNT - 1) {
  26550. s_txdesc[i][0] |= MG_BIT(29); // mark last descriptor
  26551. }
  26552. }
  26553. ENET->RCR = (ENET->RCR & (0xffff << 16)) | MG_BIT(14) | MG_BIT(8) | MG_BIT(2);
  26554. ENET->TCR = MG_BIT(2); // full duplex
  26555. ENET->TDSR = (uint32_t) &s_txdesc[0][0];
  26556. ENET->RDSR = (uint32_t) &s_rxdesc[0][0];
  26557. ENET->MRBR = ETH_PKT_SIZE;
  26558. ENET->PALR =
  26559. ifp->mac[0] << 24 | ifp->mac[1] << 16 | ifp->mac[2] << 8 | ifp->mac[3];
  26560. ENET->PAUR |= (ifp->mac[4] << 24 | ifp->mac[5] << 16);
  26561. ENET->IALR = 0;
  26562. ENET->IAUR = 0;
  26563. ENET->GALR = 0;
  26564. ENET->GAUR = 0;
  26565. ENET->MSCR = ((d->mdc_cr & 0x3f) << 1) | ((d->mdc_holdtime & 7) << 8);
  26566. ENET->EIMR = MG_BIT(25); // Enable RX interrupt
  26567. ENET->ECR |= MG_BIT(8) | MG_BIT(1); // DBSWP, Enable
  26568. ENET->RDAR = 0; // activate RX descriptors ring
  26569. return true;
  26570. }
  26571. static size_t mg_tcpip_driver_rw612_tx(const void *buf, size_t len,
  26572. struct mg_tcpip_if *ifp) {
  26573. if (len > sizeof(s_txbuf[s_txno])) {
  26574. MG_ERROR(("Frame too big, %ld", (long) len));
  26575. len = 0; // Frame is too big
  26576. } else if (((s_txdesc[s_txno][0] & MG_BIT(31)) != 0)) {
  26577. ifp->nerr++;
  26578. MG_ERROR(("No free descriptors"));
  26579. len = 0; // All descriptors are busy, fail
  26580. } else {
  26581. memcpy(s_txbuf[s_txno], buf, len);
  26582. s_txdesc[s_txno][0] = len | MG_BIT(27) | MG_BIT(26); // last buffer, crc
  26583. if (s_txno == ETH_DESC_CNT - 1) {
  26584. s_txdesc[s_txno][0] |= MG_BIT(29); // wrap
  26585. }
  26586. s_txdesc[s_txno][0] |= MG_BIT(31); // release ownership
  26587. MG_DSB();
  26588. ENET->TDAR = 0;
  26589. // MG_INFO(("s_txdesc[%d][0]: 0x%x", s_txno, s_txdesc[s_txno][0]));
  26590. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  26591. }
  26592. return len;
  26593. }
  26594. static void mg_tcpip_driver_rw612_update_hash_table(struct mg_tcpip_if *ifp) {
  26595. // TODO(): read database, rebuild hash table
  26596. ENET->GAUR = MG_BIT(1); // see imxrt, it reduces to this for mDNS
  26597. (void) ifp;
  26598. }
  26599. static bool mg_tcpip_driver_rw612_poll(struct mg_tcpip_if *ifp, bool s1) {
  26600. if (ifp->update_mac_hash_table) {
  26601. mg_tcpip_driver_rw612_update_hash_table(ifp);
  26602. ifp->update_mac_hash_table = false;
  26603. }
  26604. if (!s1) return false;
  26605. struct mg_tcpip_driver_rw612_data *d =
  26606. (struct mg_tcpip_driver_rw612_data *) ifp->driver_data;
  26607. uint8_t speed = MG_PHY_SPEED_10M;
  26608. bool up = false, full_duplex = false;
  26609. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  26610. up = mg_phy_up(&phy, d->phy_addr, &full_duplex, &speed);
  26611. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  26612. // tmp = reg with flags set to the most likely situation: 100M full-duplex
  26613. // if(link is slow or half) set flags otherwise
  26614. // reg = tmp
  26615. if (speed == MG_PHY_SPEED_100M && (ENET->RCR & MG_BIT(9))) {
  26616. ENET->RCR &= ~MG_BIT(9);
  26617. } else if (speed == MG_PHY_SPEED_10M && (ENET->RCR & MG_BIT(9)) == 0) {
  26618. ENET->RCR |= MG_BIT(9);
  26619. }
  26620. if (full_duplex && (ENET->TCR & MG_BIT(2)) == 0) {
  26621. ENET->ECR &= ~MG_BIT(1);
  26622. ENET->TCR |= MG_BIT(2);
  26623. ENET->ECR |= MG_BIT(1);
  26624. } else if (!full_duplex && (ENET->TCR & MG_BIT(2))) {
  26625. ENET->ECR &= ~MG_BIT(1);
  26626. ENET->TCR &= ~MG_BIT(2);
  26627. ENET->ECR |= MG_BIT(1);
  26628. }
  26629. MG_INFO(("Link is %uM %s-duplex",
  26630. speed == MG_PHY_SPEED_10M
  26631. ? 10
  26632. : (speed == MG_PHY_SPEED_100M ? 100 : 1000),
  26633. full_duplex ? "full" : "half"));
  26634. }
  26635. return up;
  26636. }
  26637. void ENET_IRQHandler(void) {
  26638. if (ENET->EIR & MG_BIT(25)) {
  26639. ENET->EIR = MG_BIT(25); // Ack RX
  26640. for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
  26641. if ((s_rxdesc[s_rxno][0] & MG_BIT(31)) != 0) break; // exit when done
  26642. // skip partial/errored frames
  26643. if ((s_rxdesc[s_rxno][0] & MG_BIT(27)) &&
  26644. !(s_rxdesc[s_rxno][0] &
  26645. (MG_BIT(21) | MG_BIT(20) | MG_BIT(18) | MG_BIT(17) | MG_BIT(16)))) {
  26646. size_t len = s_rxdesc[s_rxno][0] & 0xffff;
  26647. mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
  26648. }
  26649. s_rxdesc[s_rxno][0] |= MG_BIT(31); // OWN bit: handle control to DMA
  26650. MG_DSB();
  26651. ENET->RDAR = 0;
  26652. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  26653. }
  26654. }
  26655. }
  26656. struct mg_tcpip_driver mg_tcpip_driver_rw612 = {mg_tcpip_driver_rw612_init,
  26657. mg_tcpip_driver_rw612_tx, NULL,
  26658. mg_tcpip_driver_rw612_poll};
  26659. #endif
  26660. #ifdef MG_ENABLE_LINES
  26661. #line 1 "src/drivers/same54.c"
  26662. #endif
  26663. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_SAME54) && \
  26664. MG_ENABLE_DRIVER_SAME54
  26665. struct GMAC_REGS_ {
  26666. uint32_t GMAC_NCR, GMAC_NCFGR, GMAC_NSR, GMAC_UR, GMAC_DCFGR, GMAC_TSR,
  26667. GMAC_RBQB, GMAC_TBQB, GMAC_RSR, GMAC_ISR, GMAC_IER, GMAC_IDR, GMAC_IMR,
  26668. GMAC_MAN, GMAC_RPQ, GMAC_TPQ, GMAC_TPSF, GMAC_RPSF, GMAC_RJFML,
  26669. Reserved1[13], GMAC_HRB, GMAC_HRT, GMAC_SAB0, GMAC_SAT0, GMAC_SAB1,
  26670. GMAC_SAT1, GMAC_SAB2, GMAC_SAT2, GMAC_SAB3, GMAC_SAT3, GMAC_TIDM[4],
  26671. GMAC_WOL, GMAC_IPGS, GMAC_SVLAN, GMAC_TPFCP, GMAC_SAMB1, GMAC_SAMT1,
  26672. Reserved2[3], GMAC_NSC, GMAC_SCL, GMAC_SCH, GMAC_EFTSH, GMAC_EFRSH,
  26673. GMAC_PEFTSH, GMAC_PEFRSH, Reserved3[2], GMAC_OTLO, GMAC_OTHI, GMAC_FT,
  26674. GMAC_BCFT, GMAC_MFT, GMAC_PFT, GMAC_BFT64, GMAC_TBFT127, GMAC_TBFT255,
  26675. GMAC_TBFT511, GMAC_TBFT1023, GMAC_TBFT1518, GMAC_GTBFT1518, GMAC_TUR,
  26676. GMAC_SCF, GMAC_MCF, GMAC_EC, GMAC_LC, GMAC_DTF, GMAC_CSE, GMAC_ORLO,
  26677. GMAC_ORHI, GMAC_FR, GMAC_BCFR, GMAC_MFR, GMAC_PFR, GMAC_BFR64,
  26678. GMAC_TBFR127, GMAC_TBFR255, GMAC_TBFR511, GMAC_TBFR1023, GMAC_TBFR1518,
  26679. GMAC_TMXBFR, GMAC_UFR, GMAC_OFR, GMAC_JR, GMAC_FCSE, GMAC_LFFE, GMAC_RSE,
  26680. GMAC_AE, GMAC_RRE, GMAC_ROE, GMAC_IHCE, GMAC_TCE, GMAC_UCE, Reserved4[2],
  26681. GMAC_TISUBN, GMAC_TSH, Reserved5, GMAC_TSSSL, GMAC_TSSN, GMAC_TSL,
  26682. GMAC_TN, GMAC_TA, GMAC_TI, GMAC_EFTSL, GMAC_EFTN, GMAC_EFRSL, GMAC_EFRN,
  26683. GMAC_PEFTSL, GMAC_PEFTN, GMAC_PEFRSL, GMAC_PEFRN, Reserved6[28],
  26684. GMAC_RLPITR, GMAC_RLPITI, GMAC_TLPITR, GMAC_TLPITI;
  26685. };
  26686. struct GCLK_REGS_ {
  26687. uint32_t GCLK_CTRLA_RESERVED, GCLK_SYNCBUSY, Reserved2[6], GCLK_GENCTRL[12],
  26688. Reserved3[12], GCLK_PCHCTRL[48];
  26689. };
  26690. #define GMAC_REGS ((struct GMAC_REGS_ *) 0x42000800)
  26691. #define GCLK_REGS ((struct GCLK_REGS_ *) 0x40001c00)
  26692. #define ETH_PKT_SIZE 1536 // Max frame size
  26693. #define ETH_DESC_CNT 4 // Descriptors count
  26694. #define ETH_DS 2 // Descriptor size (words)
  26695. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE];
  26696. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE];
  26697. static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
  26698. static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
  26699. static uint8_t s_txno; // Current TX descriptor
  26700. static uint8_t s_rxno; // Current RX descriptor
  26701. static struct mg_tcpip_if *s_ifp; // MIP interface
  26702. static uint16_t eth_read_phy(uint8_t addr, uint8_t reg) {
  26703. GMAC_REGS->GMAC_MAN = MG_BIT(30) | // Clause 22
  26704. MG_BIT(29) | // Setting the read operation
  26705. MG_BIT(17) | ((addr & 0x1f) << 23) | // PHY address
  26706. ((reg & 0x1f) << 18); // Setting the register
  26707. while (!(GMAC_REGS->GMAC_NSR & MG_BIT(2))) (void) 0;
  26708. return GMAC_REGS->GMAC_MAN & 0xffff; // Getting the read value
  26709. }
  26710. static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
  26711. GMAC_REGS->GMAC_MAN = MG_BIT(30) |
  26712. MG_BIT(28) | // Setting the write operation
  26713. MG_BIT(17) | ((addr & 0x1f) << 23) | // PHY address
  26714. ((reg & 0x1f) << 18) | val; // Setting the register
  26715. while (!(GMAC_REGS->GMAC_NSR & MG_BIT(2)))
  26716. ; // Waiting until the write op is complete
  26717. }
  26718. uint32_t get_clock_rate(struct mg_tcpip_driver_same54_data *d) {
  26719. if (d && d->mdc_cr >= 0 && d->mdc_cr <= 5) {
  26720. return d->mdc_cr;
  26721. } else {
  26722. // get MCLK from GCLK_GENERATOR 0
  26723. uint32_t div = 512;
  26724. uint32_t mclk;
  26725. if (!(GCLK_REGS->GCLK_GENCTRL[0] & MG_BIT(12))) {
  26726. div = ((GCLK_REGS->GCLK_GENCTRL[0] & 0x00FF0000) >> 16);
  26727. if (div == 0) div = 1;
  26728. }
  26729. switch (GCLK_REGS->GCLK_GENCTRL[0] & 0xF) {
  26730. case 0: // GCLK_GENCTRL_SRC_XOSC0_Val
  26731. mclk = 32000000UL; // 32MHz
  26732. break;
  26733. case 1: // GCLK_GENCTRL_SRC_XOSC1_Val
  26734. mclk = 32000000UL; // 32MHz
  26735. break;
  26736. case 4: // GCLK_GENCTRL_SRC_OSCULP32K_Val
  26737. mclk = 32000UL; // 32Khz
  26738. break;
  26739. case 5: // GCLK_GENCTRL_SRC_XOSC32K_Val
  26740. mclk = 32000UL; // 32Khz
  26741. break;
  26742. case 6: // GCLK_GENCTRL_SRC_DFLL_Val
  26743. mclk = 48000000UL; // 48MHz
  26744. break;
  26745. case 7: // GCLK_GENCTRL_SRC_DPLL0_Val:
  26746. mclk = 200000000UL; // 200MHz
  26747. break;
  26748. case 8: // GCLK_GENCTRL_SRC_DPLL1_Val
  26749. mclk = 200000000UL; // 200MHz
  26750. break;
  26751. default:
  26752. mclk = 200000000UL; // 200MHz
  26753. }
  26754. mclk /= div;
  26755. uint8_t crs[] = {0, 1, 2, 3, 4, 5}; // GMAC->NCFGR::CLK values
  26756. uint8_t dividers[] = {8, 16, 32, 48, 64, 96}; // Respective CLK dividers
  26757. for (int i = 0; i < 6; i++) {
  26758. if (mclk / dividers[i] <= 2375000UL) { // 2.5MHz - 5%
  26759. return crs[i];
  26760. }
  26761. }
  26762. return 5;
  26763. }
  26764. }
  26765. static bool mg_tcpip_driver_same54_init(struct mg_tcpip_if *ifp) {
  26766. struct mg_tcpip_driver_same54_data *d =
  26767. (struct mg_tcpip_driver_same54_data *) ifp->driver_data;
  26768. s_ifp = ifp;
  26769. GMAC_REGS->GMAC_NCFGR = get_clock_rate(d) << 18; // Set MDC divider
  26770. GMAC_REGS->GMAC_NCR = 0; // Disable RX & TX
  26771. GMAC_REGS->GMAC_NCR |= MG_BIT(4); // Enable MDC & MDIO
  26772. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  26773. mg_phy_init(&phy, d->phy_addr, 0);
  26774. for (int i = 0; i < ETH_DESC_CNT; i++) { // Init TX descriptors
  26775. s_txdesc[i][0] = (uint32_t) s_txbuf[i]; // Point to data buffer
  26776. s_txdesc[i][1] = MG_BIT(31); // OWN bit
  26777. }
  26778. s_txdesc[ETH_DESC_CNT - 1][1] |= MG_BIT(30); // Last tx descriptor - wrap
  26779. GMAC_REGS->GMAC_DCFGR = (0x18 << 16) | // DMA recv buf 1536
  26780. (3 << 8) | // RXBMS
  26781. MG_BIT(10); // See #2487
  26782. for (int i = 0; i < ETH_DESC_CNT; i++) { // Init RX descriptors
  26783. s_rxdesc[i][0] = (uint32_t) s_rxbuf[i]; // Address of the data buffer
  26784. s_rxdesc[i][1] = 0; // Clear status
  26785. }
  26786. s_rxdesc[ETH_DESC_CNT - 1][0] |= MG_BIT(1); // Last rx descriptor - wrap
  26787. GMAC_REGS->GMAC_TBQB = (uint32_t) s_txdesc; // about the descriptor addresses
  26788. GMAC_REGS->GMAC_RBQB = (uint32_t) s_rxdesc; // Let the controller know
  26789. GMAC_REGS->GMAC_SAB0 =
  26790. MG_U32(ifp->mac[3], ifp->mac[2], ifp->mac[1], ifp->mac[0]);
  26791. GMAC_REGS->GMAC_SAT0 = MG_U32(0, 0, ifp->mac[5], ifp->mac[4]);
  26792. GMAC_REGS->GMAC_UR &= ~MG_BIT(0); // Disable MII, use RMII
  26793. GMAC_REGS->GMAC_NCFGR |= MG_BIT(8) | MG_BIT(6) | // MAXFX, MTIHEN
  26794. MG_BIT(25) | MG_BIT(4); // EFRHD, CAF
  26795. GMAC_REGS->GMAC_TSR = 0x17f; // all transmit statuses
  26796. GMAC_REGS->GMAC_RSR = 0xf; // all recv statuses
  26797. GMAC_REGS->GMAC_IDR = ~0U; // Disable interrupts, then enable required
  26798. GMAC_REGS->GMAC_IER = MG_BIT(11) | MG_BIT(10) | // HRESP, ROVR
  26799. MG_BIT(7) | MG_BIT(6) | // TCOMP, TFC
  26800. MG_BIT(5) | MG_BIT(4) | // RLEX, TUR
  26801. MG_BIT(2) | MG_BIT(1); // RXUBR, RCOMP
  26802. GMAC_REGS->GMAC_NCR |= MG_BIT(3) | MG_BIT(2); // TXEN, RXEN
  26803. return true;
  26804. }
  26805. static size_t mg_tcpip_driver_same54_tx(const void *buf, size_t len,
  26806. struct mg_tcpip_if *ifp) {
  26807. if (len > sizeof(s_txbuf[s_txno])) {
  26808. MG_ERROR(("Frame too big, %ld", (long) len));
  26809. len = 0; // Frame is too big
  26810. } else if ((s_txdesc[s_txno][1] & MG_BIT(31)) == 0) {
  26811. ifp->nerr++;
  26812. MG_ERROR(("No free descriptors"));
  26813. len = 0; // All descriptors are busy, fail
  26814. } else {
  26815. uint32_t status = len | MG_BIT(15); // Frame length, last chunk
  26816. if (s_txno == ETH_DESC_CNT - 1) status |= MG_BIT(30); // wrap
  26817. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  26818. s_txdesc[s_txno][1] = status;
  26819. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  26820. }
  26821. MG_DSB(); // Ensure descriptors have been written
  26822. GMAC_REGS->GMAC_NCR |= MG_BIT(9); // Enable transmission
  26823. return len;
  26824. }
  26825. static void mg_tcpip_driver_same54_update_hash_table(struct mg_tcpip_if *ifp) {
  26826. // TODO(): read database, rebuild hash table
  26827. // Setting Hash Index for 01:00:5e:00:00:fb (multicast)
  26828. // 24.6.9 Hash addressing
  26829. // computed hash is 55, which means bit 23 (55 - 32) in
  26830. // HRT register must be set
  26831. GMAC_REGS->GMAC_HRT = MG_BIT(23);
  26832. GMAC_REGS->GMAC_NCFGR |= MG_BIT(6); // enable multicast hash filtering
  26833. (void) ifp;
  26834. }
  26835. static bool mg_tcpip_driver_same54_poll(struct mg_tcpip_if *ifp, bool s1) {
  26836. if (ifp->update_mac_hash_table) {
  26837. mg_tcpip_driver_same54_update_hash_table(ifp);
  26838. ifp->update_mac_hash_table = false;
  26839. }
  26840. bool up = false;
  26841. if (s1) {
  26842. uint8_t speed = MG_PHY_SPEED_10M;
  26843. bool full_duplex = false;
  26844. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  26845. up = mg_phy_up(&phy, 0, &full_duplex, &speed);
  26846. // If PHY is ready, update NCFGR accordingly
  26847. if (ifp->state == MG_TCPIP_STATE_DOWN && up) {
  26848. GMAC_REGS->GMAC_NCFGR =
  26849. (GMAC_REGS->GMAC_NCFGR & ~(MG_BIT(0) | MG_BIT(1))) | (speed & 1) |
  26850. (full_duplex << 1);
  26851. }
  26852. }
  26853. return up;
  26854. }
  26855. void GMAC_Handler(void);
  26856. void GMAC_Handler(void) {
  26857. uint32_t isr = GMAC_REGS->GMAC_ISR;
  26858. uint32_t rsr = GMAC_REGS->GMAC_RSR;
  26859. uint32_t tsr = GMAC_REGS->GMAC_TSR;
  26860. if (isr & MG_BIT(1)) {
  26861. if (rsr & MG_BIT(1)) {
  26862. for (uint8_t i = 0; i < ETH_DESC_CNT; i++) {
  26863. if ((s_rxdesc[s_rxno][0] & MG_BIT(0)) == 0) break;
  26864. size_t len = s_rxdesc[s_rxno][1] & (MG_BIT(13) - 1);
  26865. mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
  26866. s_rxdesc[s_rxno][0] &= ~MG_BIT(0); // Disown
  26867. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  26868. }
  26869. }
  26870. }
  26871. if (tsr != 0) {
  26872. // MG_INFO((" --> %#x %#x", s_txdesc[s_txno][1], tsr));
  26873. if (!(s_txdesc[s_txno][1] & MG_BIT(31))) s_txdesc[s_txno][1] |= MG_BIT(31);
  26874. }
  26875. GMAC_REGS->GMAC_RSR = rsr;
  26876. GMAC_REGS->GMAC_TSR = tsr;
  26877. }
  26878. struct mg_tcpip_driver mg_tcpip_driver_same54 = {
  26879. mg_tcpip_driver_same54_init, mg_tcpip_driver_same54_tx, NULL,
  26880. mg_tcpip_driver_same54_poll};
  26881. #endif
  26882. #ifdef MG_ENABLE_LINES
  26883. #line 1 "src/drivers/sdio.c"
  26884. #endif
  26885. #if MG_ENABLE_TCPIP && \
  26886. (defined(MG_ENABLE_DRIVER_CYW_SDIO) && MG_ENABLE_DRIVER_CYW_SDIO)
  26887. // SDIO 6.9 Table 6-1 CCCR (Common Card Control Registers)
  26888. #define MG_SDIO_CCCR_SDIOREV 0x000
  26889. #define MG_SDIO_CCCR_SDREV 0x001
  26890. #define MG_SDIO_CCCR_IOEN 0x002
  26891. #define MG_SDIO_CCCR_IORDY 0x003
  26892. #define MG_SDIO_CCCR_INTEN 0x004
  26893. #define MG_SDIO_CCCR_BIC 0x007
  26894. #define MG_SDIO_CCCR_CCAP 0x008
  26895. #define MG_SDIO_CCCR_CCIS 0x009 // 3 registers
  26896. #define MG_SDIO_CCCR_F0BLKSZ 0x010 // 2 registers
  26897. #define MG_SDIO_CCCR_HISPD 0x013
  26898. // SDIO 6.10 Table 6-3 FBR (Function Basic Registers)
  26899. #define MG_SDIO_FBR_FnBLKSZ(n) (((n) &7) * 0x100 + 0x10) // 2 registers
  26900. // SDIO 5.1 IO_RW_DIRECT Command (CMD52)
  26901. #define MG_SDIO_DATA(x) ((x) &0xFF) // bits 0-7
  26902. #define MG_SDIO_ADDR(x) (((x) &0x1FFFF) << 9) // bits 9-25
  26903. #define MG_SDIO_FUNC(x) (((x) &3) << 28) // bits 28-30 (30 unused here)
  26904. #define MG_SDIO_WR MG_BIT(31)
  26905. // SDIO 5.3 IO_RW_EXTENDED Command (CMD53)
  26906. #define MG_SDIO_LEN(x) ((x) &0x1FF) // bits 0-8
  26907. #define MG_SDIO_OPINC MG_BIT(26)
  26908. #define MG_SDIO_BLKMODE MG_BIT(27)
  26909. // - Drivers set blocksize, drivers request transfers. Requesting a read
  26910. // transfer > blocksize means block transfer will be used.
  26911. // - To simplify the use of DMA transfers and avoid intermediate buffers,
  26912. // drivers must have room to accomodate a whole block transfer, e.g.: blocksize
  26913. // = 64, read 65 => 2 blocks = 128 bytes
  26914. // - Transfers of more than 1 byte assume (uint32_t *) data. 1-byte transfers
  26915. // use (uint8_t *) data
  26916. // - 'len' is the number of _bytes_ to transfer
  26917. bool mg_sdio_transfer(struct mg_tcpip_sdio *sdio, bool write, unsigned int f,
  26918. uint32_t addr, void *data, uint32_t len) {
  26919. uint32_t arg, val = 0;
  26920. unsigned int blksz = 64; // TODO(): mg_sdio_set_blksz() stores in an array,
  26921. // index on f, skip if 0
  26922. if (len == 1) {
  26923. arg = (write ? MG_SDIO_WR : 0) | MG_SDIO_FUNC(f) | MG_SDIO_ADDR(addr) |
  26924. (write ? MG_SDIO_DATA(*(uint8_t *) data) : 0);
  26925. bool res = sdio->txn(sdio, 52, arg, &val); // IO_RW_DIRECT
  26926. if (!write) *(uint8_t *) data = (uint8_t) val;
  26927. return res;
  26928. }
  26929. // IO_RW_EXTENDED
  26930. arg = (write ? MG_SDIO_WR : 0) | MG_SDIO_OPINC | MG_SDIO_FUNC(f) |
  26931. MG_SDIO_ADDR(addr);
  26932. if (len > 512 || (blksz != 0 && len > blksz)) { // SDIO 5.3 512 -> len=0
  26933. unsigned int blkcnt;
  26934. if (blksz == 0) return false; // > 512 requires block size set
  26935. blkcnt = (len + blksz - 1) / blksz;
  26936. if (blkcnt > 511) return false; // we don't support "infinite" blocks
  26937. arg |= MG_SDIO_BLKMODE | MG_SDIO_LEN(blkcnt); // block transfer
  26938. len = blksz * blkcnt;
  26939. } else {
  26940. arg |= MG_SDIO_LEN(len); // multi-byte transfer
  26941. }
  26942. return sdio->xfr(sdio, write, arg,
  26943. (arg & MG_SDIO_BLKMODE) ? (uint16_t) blksz : 0,
  26944. (uint32_t *) data, len, &val);
  26945. }
  26946. bool mg_sdio_set_blksz(struct mg_tcpip_sdio *sdio, unsigned int f,
  26947. uint16_t blksz) {
  26948. uint32_t val = blksz & 0xff;
  26949. if (!mg_sdio_transfer(sdio, true, 0, MG_SDIO_FBR_FnBLKSZ(f), &val, 1))
  26950. return false;
  26951. val = (blksz >> 8) & 0x0f; // SDIO 6.10 Table 6-4, max 2048
  26952. if (!mg_sdio_transfer(sdio, true, 0, MG_SDIO_FBR_FnBLKSZ(f) + 1, &val, 1))
  26953. return false;
  26954. // TODO(): store in an array, index on f. Static 8-element array
  26955. MG_VERBOSE(("F%c block size set", (f & 7) + '0'));
  26956. return true;
  26957. }
  26958. // Enable Fx
  26959. bool mg_sdio_enable_f(struct mg_tcpip_sdio *sdio, unsigned int f) {
  26960. uint8_t bit = 1U << (f & 7), bits;
  26961. uint32_t val = 0;
  26962. if (!mg_sdio_transfer(sdio, false, 0, MG_SDIO_CCCR_IOEN, &val, 1))
  26963. return false;
  26964. bits = (uint8_t) val | bit;
  26965. unsigned int times = 501;
  26966. while (times--) {
  26967. val = bits; /* IOEf */
  26968. ;
  26969. if (!mg_sdio_transfer(sdio, true, 0, MG_SDIO_CCCR_IOEN, &val, 1))
  26970. return false;
  26971. mg_delayms(1);
  26972. val = 0;
  26973. if (!mg_sdio_transfer(sdio, false, 0, MG_SDIO_CCCR_IOEN, &val, 1))
  26974. return false;
  26975. if (val & bit) break;
  26976. }
  26977. if (times == (unsigned int) ~0) return false;
  26978. MG_VERBOSE(("F%c enabled", (f & 7) + '0'));
  26979. return true;
  26980. }
  26981. // Wait for Fx to be ready
  26982. bool mg_sdio_waitready_f(struct mg_tcpip_sdio *sdio, unsigned int f) {
  26983. uint8_t bit = 1U << (f & 7);
  26984. unsigned int times = 501;
  26985. while (times--) {
  26986. uint32_t val;
  26987. if (!mg_sdio_transfer(sdio, false, 0, MG_SDIO_CCCR_IORDY, &val, 1))
  26988. return false;
  26989. if (val & bit) break; // IORf
  26990. mg_delayms(1);
  26991. }
  26992. if (times == (unsigned int) ~0) return false;
  26993. MG_VERBOSE(("F%c ready", (f & 7) + '0'));
  26994. return true;
  26995. }
  26996. // SDIO 6.14 Bus State Diagram
  26997. bool mg_sdio_init(struct mg_tcpip_sdio *sdio) {
  26998. uint32_t val = 0;
  26999. if (!sdio->txn(sdio, 0, 0, NULL)) return false; // GO_IDLE_STATE
  27000. sdio->txn(sdio, 5, 0, &val); // IO_SEND_OP_COND, no CRC
  27001. MG_VERBOSE(("IO Functions: %u, Memory: %c", 1 + ((val >> 28) & 7),
  27002. (val & MG_BIT(27)) ? 'Y' : 'N'));
  27003. if (!sdio->txn(sdio, 3, 0, &val)) return false; // SEND_RELATIVE_ADDR
  27004. val = ((uint32_t) val) >> 16; // RCA
  27005. if (!sdio->txn(sdio, 7, val << 16, &val))
  27006. return false; // SELECT/DESELECT_CARD
  27007. mg_sdio_transfer(sdio, false, 0, MG_SDIO_CCCR_SDIOREV, &val, 1);
  27008. MG_DEBUG(("CCCR: %u.%u, SDIO: %u.%u", 1 + ((val >> 2) & 3), (val >> 0) & 3,
  27009. 1 + ((val >> 6) & 3), (val >> 4) & 3));
  27010. mg_sdio_transfer(sdio, false, 0, MG_SDIO_CCCR_SDREV, &val, 1);
  27011. MG_VERBOSE(("SD: %u.%u", 1 + ((val >> 2) & 3), (val >> 0) & 3));
  27012. mg_sdio_transfer(sdio, false, 0, MG_SDIO_CCCR_BIC, &val, 1);
  27013. MG_SET_BITS(val, 3,
  27014. MG_BIT(7) | MG_BIT(1)); // SDIO 6.9 Tables 6-1 6-2, 4-bit bus
  27015. mg_sdio_transfer(sdio, true, 0, MG_SDIO_CCCR_BIC, &val, 1);
  27016. // All Full-Speed SDIO cards support a 4-bit bus. Skip for Low-Speed SDIO
  27017. // cards, we don't provide separate low-level functions for width and speed
  27018. sdio->cfg(sdio, 0); // set DS;
  27019. if (!mg_sdio_transfer(sdio, false, 0, MG_SDIO_CCCR_HISPD, &val, 1))
  27020. return false;
  27021. if (val & MG_BIT(0) /* SHS */) {
  27022. val = MG_BIT(1); /* EHS */
  27023. if (!mg_sdio_transfer(sdio, true, 0, MG_SDIO_CCCR_HISPD, &val, 1))
  27024. return false;
  27025. sdio->cfg(sdio, 1); // set HS;
  27026. MG_VERBOSE(("Bus set to 4-bit @50MHz"));
  27027. } else {
  27028. MG_VERBOSE(("Bus set to 4-bit @25MHz"));
  27029. }
  27030. return true;
  27031. }
  27032. // - 6.11 Card Information Structure (CIS): 0x0001000-0x017FF; for card common
  27033. // and all functions
  27034. // - 16.5 SDIO Card Metaformat
  27035. // - 16.7.2 CISTPL_FUNCE (0x22): Function Extension Tuple, provides standard
  27036. // information about the card (common) and each individual function. One
  27037. // CISTPL_FUNCE in each function’s CIS, immediately following the CISTPL_FUNCID
  27038. // tuple
  27039. // - 16.7.3 CISTPL_FUNCE Tuple for Function 0 (common)
  27040. // - 16.7.4 CISTPL_FUNCE Tuple for Function 1-7
  27041. #endif
  27042. #ifdef MG_ENABLE_LINES
  27043. #line 1 "src/drivers/st67w6.c"
  27044. #endif
  27045. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_ST67W6) && \
  27046. MG_ENABLE_DRIVER_ST67W6
  27047. static struct mg_tcpip_if *s_ifp;
  27048. static uint32_t s_ip, s_mask;
  27049. static bool s_link = false, s_connecting = false;
  27050. static void wifi_cb(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
  27051. struct mg_wifi_data *wifi =
  27052. &((struct mg_tcpip_driver_st67w6_data *) ifp->driver_data)->wifi;
  27053. if (wifi->apmode && ev == MG_TCPIP_EV_STATE_CHANGE &&
  27054. *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) {
  27055. MG_DEBUG(("Access Point started"));
  27056. s_ip = ifp->ip, ifp->ip = wifi->apip;
  27057. s_mask = ifp->mask, ifp->mask = wifi->apmask;
  27058. ifp->enable_dhcp_client = false;
  27059. ifp->enable_dhcp_server = true;
  27060. }
  27061. }
  27062. static bool st67w6_init(uint8_t *mac);
  27063. static void st67w6_poll(bool is_at);
  27064. static bool mg_tcpip_driver_st67w6_init(struct mg_tcpip_if *ifp) {
  27065. struct mg_tcpip_driver_st67w6_data *d =
  27066. (struct mg_tcpip_driver_st67w6_data *) ifp->driver_data;
  27067. struct mg_wifi_data *wifi = &d->wifi;
  27068. if (MG_BIG_ENDIAN) {
  27069. MG_ERROR(("Big-endian host"));
  27070. return false;
  27071. }
  27072. if (d->is_ready == NULL) return false;
  27073. s_ifp = ifp;
  27074. s_ip = ifp->ip;
  27075. s_mask = ifp->mask;
  27076. s_link = false;
  27077. ifp->pfn = wifi_cb;
  27078. if (!st67w6_init(ifp->mac)) return false;
  27079. if (d->send_queue.size == 0) d->send_queue.size = 8192;
  27080. d->send_queue.buf = (char *) mg_calloc(1, d->send_queue.size);
  27081. if (d->send_queue.buf == NULL) {
  27082. MG_ERROR(("OOM"));
  27083. return false;
  27084. }
  27085. if (wifi->apmode) {
  27086. return mg_wifi_ap_start(wifi);
  27087. } else if (wifi->ssid != NULL && wifi->pass != NULL) {
  27088. return mg_wifi_connect(wifi);
  27089. }
  27090. return true;
  27091. }
  27092. // Decouple; module access depends on it being RDY. See st67w6_poll()
  27093. size_t mg_tcpip_driver_st67w6_output(const void *buf, size_t len,
  27094. struct mg_tcpip_if *ifp) {
  27095. struct mg_tcpip_driver_st67w6_data *d =
  27096. (struct mg_tcpip_driver_st67w6_data *) ifp->driver_data;
  27097. char *p;
  27098. if (mg_queue_book(&d->send_queue, &p, len) < len) return 0;
  27099. memcpy(p, buf, len);
  27100. mg_queue_add(&d->send_queue, len);
  27101. return len;
  27102. }
  27103. static bool mg_tcpip_driver_st67w6_poll(struct mg_tcpip_if *ifp, bool s1) {
  27104. struct mg_tcpip_driver_st67w6_data *d =
  27105. (struct mg_tcpip_driver_st67w6_data *) ifp->driver_data;
  27106. if (d->is_ready == NULL) return false;
  27107. st67w6_poll(false);
  27108. if (!s1) return false;
  27109. return s_link;
  27110. }
  27111. struct mg_tcpip_driver mg_tcpip_driver_st67w6 = {
  27112. mg_tcpip_driver_st67w6_init, mg_tcpip_driver_st67w6_output, NULL,
  27113. mg_tcpip_driver_st67w6_poll};
  27114. // AT | STA | AP | HCI | OT
  27115. // --------------------------
  27116. // framing <-- includes rx stall indication
  27117. // --------------------------
  27118. // SPI <-- padded to 32-bit
  27119. //
  27120. // Transactions take place when the module signals RDY, 'tx' and 'write'
  27121. // functions actually just write to memory
  27122. // - AT: handles configuration and events (unsolicited +foo:). Responses may
  27123. // come as:
  27124. // - 1 frame: just OK or ERROR
  27125. // - 2 frames: 1 text line each, a response and OK
  27126. // - 3 frames: 2 text lines: 1 frame with text and no CR/LF, 1 frame with
  27127. // binary and CR/LF, 1 text line with OK
  27128. // - STA and AP contain plain Ethernet frames to/from the STA and AP networks,
  27129. // respectively
  27130. // - HCI: BLE stuff
  27131. // - OT: ?
  27132. #pragma pack(push, 1)
  27133. // little endian
  27134. struct spi_hdr {
  27135. uint16_t magic;
  27136. uint16_t len;
  27137. uint8_t vflags; // version :2, rx_stall :1, flags :5
  27138. uint8_t type;
  27139. uint16_t reserved;
  27140. };
  27141. #define ST67W6_SPI_TYPE_AT 0
  27142. #define ST67W6_SPI_TYPE_STA 1
  27143. #define ST67W6_SPI_TYPE_AP 2
  27144. #define ST67W6_SPI_TYPE_HCI 3
  27145. #define ST67W6_SPI_TYPE_OT 4
  27146. #pragma pack(pop)
  27147. static uint32_t txdata[2048 / 4], rxdata[2048 / 4];
  27148. static uint8_t at_resp[300];
  27149. static bool s_at_ok, s_at_err;
  27150. static size_t s_at_resp_len;
  27151. static void st67w6_handle_wifi_evnt(char *, size_t len);
  27152. static void st67w6_handle_scan_result(char *, size_t len);
  27153. static size_t st67w6_spi_poll(uint8_t *write, uint8_t *read);
  27154. static void st67w6_write(unsigned int f, void *data, uint16_t len);
  27155. static void st67w6_update_hash_table(void);
  27156. // High-level comm stuff
  27157. static void st67w6_poll(bool is_at) {
  27158. struct mg_tcpip_driver_st67w6_data *d =
  27159. (struct mg_tcpip_driver_st67w6_data *) s_ifp->driver_data;
  27160. struct spi_hdr *h = (struct spi_hdr *) rxdata;
  27161. unsigned int type;
  27162. uint8_t *txsource = (uint8_t *) txdata;
  27163. if (s_ifp->update_mac_hash_table) {
  27164. // first call to _poll() is after _init(), so this is safe
  27165. st67w6_update_hash_table();
  27166. s_ifp->update_mac_hash_table = false;
  27167. }
  27168. if (!is_at) { // send outstanding WLAN frames in the queue
  27169. char *buf;
  27170. size_t len;
  27171. // NOTE(): have traffic-dependent queues or queue traffic type with data
  27172. if ((len = mg_queue_next(&d->send_queue, &buf)) > 0) {
  27173. st67w6_write(d->wifi.apmode ? ST67W6_SPI_TYPE_AP : ST67W6_SPI_TYPE_STA,
  27174. buf, (uint16_t) len);
  27175. mg_queue_del(&d->send_queue, len);
  27176. } else { // nothing to send
  27177. txsource = NULL;
  27178. }
  27179. }
  27180. if (st67w6_spi_poll(txsource, (uint8_t *) rxdata) == 0) return;
  27181. if (h->len == 0) return;
  27182. type = h->type;
  27183. if (type == ST67W6_SPI_TYPE_AT) {
  27184. char *p = (char *) (h + 1);
  27185. size_t len = h->len;
  27186. if (len > 7 && strncmp(p, "+CWLAP:", 7) == 0) { // scan result
  27187. st67w6_handle_scan_result(p + 7, len - 7);
  27188. } else if (len > 4 && strncmp(p, "+CW:", 4) == 0) {
  27189. st67w6_handle_wifi_evnt(p + 4, len - 4);
  27190. } else {
  27191. MG_VERBOSE(("AT partial: %.*s", (int) len, p));
  27192. if (s_at_resp_len + len >= sizeof(at_resp))
  27193. s_at_resp_len = 0; // truncate response, error will be caught later
  27194. memcpy(at_resp + s_at_resp_len, p, len);
  27195. s_at_resp_len += len;
  27196. if (mg_match(mg_str_n((char *) at_resp, s_at_resp_len),
  27197. mg_str_n("*ERROR*", 7), NULL)) {
  27198. s_at_err = true;
  27199. } else if (mg_match(mg_str_n((char *) at_resp, s_at_resp_len),
  27200. mg_str_n("*OK*", 4), NULL)) {
  27201. s_at_ok = true;
  27202. }
  27203. }
  27204. } else if (type == ST67W6_SPI_TYPE_STA || type == ST67W6_SPI_TYPE_AP) {
  27205. // WLAN frame reception
  27206. mg_tcpip_qwrite(h + 1, h->len, s_ifp);
  27207. } // else silently discard
  27208. }
  27209. // WLAN event handling
  27210. // - Do not call any AT functions here, otherwise revise st67w6_at_wait()
  27211. // - The module likes to send ERROR along with other events
  27212. static void st67w6_handle_wifi_evnt(char *p, size_t len) {
  27213. struct mg_str data[2];
  27214. MG_VERBOSE(("event: %.*s", (int) len, p));
  27215. if (len > 9 && strncmp(p, "CONNECTED", 9) == 0) {
  27216. s_link = true;
  27217. s_connecting = false;
  27218. } else if (len > 12 && strncmp(p, "DISCONNECTED", 12) == 0) {
  27219. s_link = false;
  27220. s_connecting = false; // should not be needed
  27221. } else if (s_connecting && len > 6 &&
  27222. mg_match(mg_str_n(p, len), mg_str_n("ERROR,*\r\n*", 10), data)) {
  27223. size_t reason = 0;
  27224. bool ok = mg_to_size_t(data[0], &reason);
  27225. s_connecting = false;
  27226. MG_ERROR(("CONNECT FAILED"));
  27227. mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_CONNECT_ERR, ok ? &reason : NULL);
  27228. } else if (len > 9 && strncmp(p, "SCAN_DONE", 9) == 0) {
  27229. MG_VERBOSE(("scan complete"));
  27230. mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_SCAN_END, NULL);
  27231. } // else silently discard: CONNECTING; STA_CONNECTED,"MAC";
  27232. // STA_DISCONNECTED,"MAC"; DIST_STA_IP,"MAC","IP"
  27233. }
  27234. static bool st67w6_at_cmd(char *cmd, size_t len);
  27235. // Wi-Fi network stuff
  27236. static bool st67w6_wifi_connect(char *ssid, char *pass) {
  27237. char cmd[90]; // ssid + pass + AT
  27238. size_t cmd_len;
  27239. if (!st67w6_at_cmd("AT+CWMODE=1,0\r\n", 15)) return false;
  27240. cmd_len = mg_snprintf(cmd, sizeof(cmd), "AT+CWJAP=\"%s\",\"%s\",,0\r\n", ssid,
  27241. pass); // takes >700ms
  27242. if (!st67w6_at_cmd(cmd, cmd_len)) return false;
  27243. st67w6_at_cmd("AT+CWRECONNCFG=0,0\r\n", 20); // disregard error, connecting
  27244. s_connecting = true;
  27245. return true;
  27246. }
  27247. static bool st67w6_wifi_disconnect(void) {
  27248. s_connecting = false;
  27249. if (!st67w6_at_cmd("AT+CWQAP=0\r\n", 12)) return false; // takes >800ms
  27250. return st67w6_at_cmd("AT+CWMODE=0,0\r\n", 15); // takes >550ms
  27251. }
  27252. static bool st67w6_wifi_ap_start(char *ssid, char *pass, unsigned int channel) {
  27253. char cmd[90]; // ssid + pass + AT
  27254. size_t cmd_len;
  27255. if (!st67w6_at_cmd("AT+CWMODE=2,0\r\n", 15)) return false; // takes >800ms
  27256. cmd_len = mg_snprintf(
  27257. cmd, sizeof(cmd), "AT+CWSAP=\"%s\",\"%s\",%u,3,2,0\r\n", ssid, pass,
  27258. channel); // 3: WPA2_PSK; 2: max stations // takes >350ms
  27259. s_link = true;
  27260. return st67w6_at_cmd(cmd, cmd_len);
  27261. }
  27262. static bool st67w6_wifi_ap_stop(void) {
  27263. s_link = false;
  27264. return st67w6_at_cmd("AT+CWMODE=0,0\r\n", 15); // takes >550ms
  27265. }
  27266. // WLAN scan handling
  27267. // +CWLAP:(security,"SSID",RSSI,"BSSID",channel,cipher,proto,wps)\r\n
  27268. // security: OPEN, WEP, WPA, WPA2, WPA-WPA2, WPA-EAP, WPA3-SAE, WPA2-WPA3-SAE
  27269. // cipher: NONE, WEP, AES/CCMP, TKIP, TKIP and AES/CCMP
  27270. // proto: 4-bit bitmap AX,N,G,B; all set from right to left
  27271. static bool st67w6_wifi_scan(void) {
  27272. return st67w6_at_cmd("AT+CWLAPOPT=1,1695,-100,255,50\r\n", 32) &&
  27273. st67w6_at_cmd("AT+CWLAP=0,,,0\r\n", 16);
  27274. }
  27275. static void st67w6_handle_scan_result(char *data, size_t len) {
  27276. struct mg_wifi_scan_bss_data bss;
  27277. struct mg_str fields[2];
  27278. char mac[6];
  27279. uint8_t val;
  27280. unsigned int i;
  27281. MG_VERBOSE(("scan result event: %.*s", (int) len, data));
  27282. ++data, --len; // skip '('
  27283. if (!mg_span(mg_str_n(data, len), &fields[0], &fields[1], ',') ||
  27284. !mg_str_to_num(fields[0], 10, &val, 1))
  27285. return;
  27286. bss.security =
  27287. (val == 0) ? MG_WIFI_SECURITY_OPEN : (uint8_t) MG_WIFI_SECURITY_WEP;
  27288. if (val == 2 || val == 4) bss.security |= MG_WIFI_SECURITY_WPA;
  27289. if (val == 3 || val == 4 || val == 7) bss.security |= MG_WIFI_SECURITY_WPA2;
  27290. if (val == 6 || val == 7) bss.security |= MG_WIFI_SECURITY_WPA3;
  27291. if (val == 5) bss.security |= MG_WIFI_SECURITY_WPA_ENTERPRISE;
  27292. if (!mg_span(fields[1], &fields[0], &fields[1], ',')) return;
  27293. bss.SSID.buf = fields[0].buf + 1, bss.SSID.len = fields[0].len - 2;
  27294. if (!mg_span(fields[1], &fields[0], &fields[1], ',')) return;
  27295. while (fields[0].buf[0] == ' ') ++fields[0].buf, --fields[0].len;
  27296. if (fields[0].buf[0] != '-') return; // positive RSSI would be great
  27297. ++fields[0].buf, --fields[0].len;
  27298. if (!mg_str_to_num(fields[0], 10, &val, 1)) return;
  27299. bss.RSSI = (int8_t) - (int8_t) val;
  27300. if (!mg_span(fields[1], &fields[0], &fields[1], ',')) return;
  27301. if (fields[0].len < 19) return;
  27302. ++fields[0].buf, --fields[0].len; // skip '"'
  27303. for (i = 0; i < 6; i++) {
  27304. struct mg_str str;
  27305. str.buf = fields[0].buf + 3 * i;
  27306. str.len = 2;
  27307. if (!mg_str_to_num(str, 16, &mac[i], 1)) return;
  27308. }
  27309. bss.BSSID = mac;
  27310. if (!mg_span(fields[1], &fields[0], &fields[1], ',') ||
  27311. !mg_str_to_num(fields[0], 10, &bss.channel, 1))
  27312. return;
  27313. if (!mg_span(fields[1], &fields[0], &fields[1], ',') ||
  27314. !mg_str_to_num(fields[0], 10, &val, 1))
  27315. return;
  27316. // ignore cypher
  27317. if (!mg_span(fields[1], &fields[0], &fields[1], ',') ||
  27318. !mg_str_to_num(fields[0], 10, &val, 1))
  27319. return;
  27320. bss.has_n = (val & 4) != 0;
  27321. bss.has_ax = (val & 8) != 0;
  27322. bss.band = MG_WIFI_BAND_2G; // NOT INFORMED with default options, no docs
  27323. MG_VERBOSE(("BSS: %.*s (%u) (%M) %d dBm %u", bss.SSID.len, bss.SSID.buf,
  27324. bss.channel, mg_print_mac, bss.BSSID, (int) bss.RSSI,
  27325. bss.security));
  27326. mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_SCAN_RESULT, &bss);
  27327. }
  27328. // AT stuff
  27329. static inline bool delayms(unsigned int ms) {
  27330. mg_delayms(ms);
  27331. return true;
  27332. }
  27333. // send AT command, wait for a response or timeout, meanwhile delivering
  27334. // received frames and events
  27335. static bool st67w6_at_cmd(char *cmd, size_t len) {
  27336. bool is_at = true;
  27337. unsigned int times = 1000;
  27338. s_at_resp_len = 0;
  27339. st67w6_write(ST67W6_SPI_TYPE_AT, cmd, (uint16_t) len);
  27340. s_at_ok = false, s_at_err = false;
  27341. do { // AT response processing does not call any other AT function
  27342. st67w6_poll(is_at); // otherwise we can't allow them to pile up here
  27343. is_at = false; // avoid repeating, allow queued WLAN frames to be sent
  27344. // network frames will be pushed to the queue so that is safe
  27345. } while (!s_at_ok && !s_at_err && times-- > 0 && delayms(1));
  27346. MG_VERBOSE(("AT response:\n%.*s", s_at_resp_len, at_resp));
  27347. MG_VERBOSE(("ok: %c, err: %c, times: %d", s_at_ok ? '1' : '0',
  27348. s_at_err ? '1' : '0', (int) times));
  27349. return s_at_ok;
  27350. }
  27351. static bool st67w6_spi_init(void);
  27352. bool mg_to_size_t(struct mg_str str, size_t *val);
  27353. static bool st67w6_init(uint8_t *mac) {
  27354. // struct mg_tcpip_driver_st67w6_data *d = (struct
  27355. // mg_tcpip_driver_st67w6_data *) s_ifp->driver_data;
  27356. struct mg_str data[3];
  27357. size_t val;
  27358. bool is_b = false;
  27359. if (!st67w6_spi_init()) return false;
  27360. if (!st67w6_at_cmd("AT\r\n", 4)) return false;
  27361. if (!st67w6_at_cmd("AT+CWNETMODE?\r\n", 15) ||
  27362. !mg_match(mg_str_n((char *) at_resp, s_at_resp_len),
  27363. mg_str_n("*:*\r\n*", 6), data) ||
  27364. !mg_to_size_t(data[1], &val))
  27365. return false;
  27366. if (val != 0) {
  27367. MG_ERROR(("Wrong firmware, T02 is needed"));
  27368. return false;
  27369. }
  27370. // set clock, who cares ???
  27371. if (!st67w6_at_cmd("AT+GET_CLOCK\r\n", 14)) return false;
  27372. MG_DEBUG(("%.*s", s_at_resp_len, at_resp)); // TODO(scaprile): --> VERBOSE
  27373. // BT-ENABLED DEPENDENCY
  27374. // MODULE DEPENDENCY
  27375. if (!st67w6_at_cmd("AT+EFUSE-R=24,\"0x100\"\r\n", 23) ||
  27376. !mg_match(mg_str_n((char *) at_resp, s_at_resp_len), mg_str_n("*,*", 3),
  27377. data))
  27378. return false;
  27379. if (data[1].buf[0] == 'C' && data[1].buf[1] == '6') is_b = true;
  27380. MG_DEBUG(("WLAN module is %sB type", is_b ? "" : "not")); // --> VERBOSE
  27381. if (is_b) {
  27382. // Disable the antenna diversity pin
  27383. if (!st67w6_at_cmd("AT+IORST=0\r\n", 12)) return false;
  27384. // Apparently they intend to disable some antenna ...
  27385. if (!st67w6_at_cmd("AT+CWANTENABLE?\r\n", 17)) return false;
  27386. MG_DEBUG(("%.*s", s_at_resp_len, at_resp)); // --> VERBOSE
  27387. }
  27388. // Do not set wake-up pin (AT+SLWKIO)
  27389. // Disable power save mode
  27390. // NOTE(scaprile): (no response if in hibernate mode, though I guess we
  27391. // wouldn't have reached this point in that case either)
  27392. if (!st67w6_at_cmd("AT+PWR=0\r\n", 12)) return false;
  27393. // set Wi-Fi
  27394. // set country code
  27395. if (!st67w6_at_cmd("AT+CWCOUNTRY=0,\"00\"\r\n", 21)) return false;
  27396. #if 0
  27397. // set DTIM
  27398. if (!st67w6_at_cmd("AT+SLWKDTIM=1\r\n", 15)) return false;
  27399. #endif
  27400. // Read only default MAC, ignore set bit count (data[6] & 0x3F). Custom MACs
  27401. // reside at @0x64 and 0x70
  27402. if (st67w6_at_cmd("AT+EFUSE-R=7,\"0x014\"\r\n", 22) &&
  27403. mg_match(mg_str_n((char *) at_resp, s_at_resp_len), mg_str_n("*,*", 3),
  27404. data)) {
  27405. int i;
  27406. for (i = 0; i < 6; i++) mac[i] = data[1].buf[5 - i];
  27407. MG_DEBUG(("MAC: %M", mg_print_mac, mac));
  27408. } else {
  27409. MG_ERROR(("read MAC failed"));
  27410. }
  27411. return true;
  27412. }
  27413. static void st67w6_update_hash_table(void) {
  27414. // TODO(): read database, rebuild hash table
  27415. // uint32_t val = 0;
  27416. // val = 1;
  27417. // st67w6_at_iovar_set2_(0, "mcast_list", (uint8_t *) &val, sizeof(val),
  27418. // (uint8_t *) mcast_addr, sizeof(mcast_addr)); mg_delayms(50);
  27419. }
  27420. // SPI specifics
  27421. #define ST67W6_SPI_MAGIC 0x55AA
  27422. // #define ST67W6_SPI_VERSION(x), IS_STALL, FLAGS(x), ...
  27423. static const uint8_t idlehdr[sizeof(struct spi_hdr)] = {0xaa, 0x55, 0, 0,
  27424. 0, 0, 0, 0};
  27425. static void st67w6_write(unsigned int f, void *data, uint16_t len) {
  27426. struct spi_hdr *h = (struct spi_hdr *) txdata;
  27427. h->magic = ST67W6_SPI_MAGIC;
  27428. h->type = (uint8_t) f;
  27429. h->vflags = 0;
  27430. h->len = len;
  27431. h->reserved = 0;
  27432. memmove(h + 1, data, len);
  27433. }
  27434. static size_t st67w6_spi_poll(uint8_t *write, uint8_t *read) {
  27435. struct mg_tcpip_driver_st67w6_data *d =
  27436. (struct mg_tcpip_driver_st67w6_data *) s_ifp->driver_data;
  27437. struct spi_hdr *th, *rh = (struct spi_hdr *) read;
  27438. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) d->spi;
  27439. size_t padded;
  27440. unsigned int times;
  27441. th = (write != NULL) ? (struct spi_hdr *) write : (struct spi_hdr *) idlehdr;
  27442. s->begin(s->spi);
  27443. times = 50;
  27444. while (times--) {
  27445. if (d->is_ready()) break;
  27446. if (times == 0) {
  27447. MG_ERROR(("RDY TIMEOUT"));
  27448. s->end(s->spi);
  27449. return 0;
  27450. }
  27451. mg_delayms(1);
  27452. }
  27453. padded = (th->len + 3) & ~3;
  27454. s->txn(s->spi, (uint8_t *) th, (uint8_t *) rh, sizeof(*th) + padded);
  27455. if (rh->magic == ST67W6_SPI_MAGIC && rh->len > padded) {
  27456. size_t remaining_padded = (rh->len - padded + 3) & ~3;
  27457. if (remaining_padded > (2048 - sizeof(*rh) - padded))
  27458. remaining_padded = 2048 - sizeof(*rh) - padded;
  27459. s->txn(s->spi, NULL, read + sizeof(*rh) + padded, remaining_padded);
  27460. }
  27461. times = 50;
  27462. while (times--) {
  27463. if (!d->is_ready()) break;
  27464. if (times == 0) {
  27465. MG_ERROR(("!RDY TIMEOUT"));
  27466. break;
  27467. }
  27468. mg_delayms(1);
  27469. }
  27470. s->end(s->spi);
  27471. return (size_t) rh->len;
  27472. }
  27473. static bool st67w6_spi_init(void) {
  27474. struct mg_tcpip_driver_st67w6_data *d =
  27475. (struct mg_tcpip_driver_st67w6_data *) s_ifp->driver_data;
  27476. size_t len;
  27477. unsigned int times = 1000;
  27478. while (times--) {
  27479. if (d->is_ready()) break;
  27480. if (times == 0) return false;
  27481. mg_delayms(1);
  27482. }
  27483. if (((len = st67w6_spi_poll(NULL, (uint8_t *) rxdata)) == 0) ||
  27484. !mg_match(mg_str_n(((char *) rxdata) + sizeof(struct spi_hdr), len),
  27485. mg_str_n("*ready*", 7), NULL))
  27486. return false;
  27487. return true;
  27488. }
  27489. // Mongoose Wi-Fi API functions
  27490. bool mg_wifi_scan(void) {
  27491. return st67w6_wifi_scan();
  27492. }
  27493. bool mg_wifi_connect(struct mg_wifi_data *wifi) {
  27494. s_ifp->ip = s_ip;
  27495. s_ifp->mask = s_mask;
  27496. if (s_ifp->ip == 0) s_ifp->enable_dhcp_client = true;
  27497. s_ifp->enable_dhcp_server = false;
  27498. MG_DEBUG(("Connecting to '%s'", wifi->ssid));
  27499. return st67w6_wifi_connect(wifi->ssid, wifi->pass);
  27500. }
  27501. bool mg_wifi_disconnect(void) {
  27502. return st67w6_wifi_disconnect();
  27503. }
  27504. bool mg_wifi_ap_start(struct mg_wifi_data *wifi) {
  27505. MG_DEBUG(("Starting AP '%s' (%u)", wifi->apssid, wifi->apchannel));
  27506. return st67w6_wifi_ap_start(wifi->apssid, wifi->appass, wifi->apchannel);
  27507. }
  27508. bool mg_wifi_ap_stop(void) {
  27509. return st67w6_wifi_ap_stop();
  27510. }
  27511. #endif
  27512. #ifdef MG_ENABLE_LINES
  27513. #line 1 "src/drivers/stm32f.c"
  27514. #endif
  27515. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32F) && \
  27516. MG_ENABLE_DRIVER_STM32F
  27517. struct stm32f_eth {
  27518. volatile uint32_t MACCR, MACFFR, MACHTHR, MACHTLR, MACMIIAR, MACMIIDR, MACFCR,
  27519. MACVLANTR, RESERVED0[2], MACRWUFFR, MACPMTCSR, RESERVED1, MACDBGR, MACSR,
  27520. MACIMR, MACA0HR, MACA0LR, MACA1HR, MACA1LR, MACA2HR, MACA2LR, MACA3HR,
  27521. MACA3LR, RESERVED2[40], MMCCR, MMCRIR, MMCTIR, MMCRIMR, MMCTIMR,
  27522. RESERVED3[14], MMCTGFSCCR, MMCTGFMSCCR, RESERVED4[5], MMCTGFCR,
  27523. RESERVED5[10], MMCRFCECR, MMCRFAECR, RESERVED6[10], MMCRGUFCR,
  27524. RESERVED7[334], PTPTSCR, PTPSSIR, PTPTSHR, PTPTSLR, PTPTSHUR, PTPTSLUR,
  27525. PTPTSAR, PTPTTHR, PTPTTLR, RESERVED8, PTPTSSR, PTPPPSCR, RESERVED9[564],
  27526. DMABMR, DMATPDR, DMARPDR, DMARDLAR, DMATDLAR, DMASR, DMAOMR, DMAIER,
  27527. DMAMFBOCR, DMARSWTR, RESERVED10[8], DMACHTDR, DMACHRDR, DMACHTBAR,
  27528. DMACHRBAR;
  27529. };
  27530. #undef ETH
  27531. #define ETH ((struct stm32f_eth *) (uintptr_t) 0x40028000)
  27532. #define ETH_PKT_SIZE 1540 // Max frame size
  27533. #define ETH_DESC_CNT 4 // Descriptors count
  27534. #define ETH_DS 4 // Descriptor size (words)
  27535. static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS] MG_ETH_RAM; // RX descriptors
  27536. static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS] MG_ETH_RAM; // TX descriptors
  27537. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM; // RX ethernet buffers
  27538. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM; // TX ethernet buffers
  27539. static uint8_t s_txno; // Current TX descriptor
  27540. static uint8_t s_rxno; // Current RX descriptor
  27541. static struct mg_tcpip_if *s_ifp; // MIP interface
  27542. static uint16_t eth_read_phy(uint8_t addr, uint8_t reg) {
  27543. ETH->MACMIIAR &= (7 << 2);
  27544. ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6);
  27545. ETH->MACMIIAR |= MG_BIT(0);
  27546. while (ETH->MACMIIAR & MG_BIT(0)) (void) 0;
  27547. return ETH->MACMIIDR & 0xffff;
  27548. }
  27549. static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
  27550. ETH->MACMIIDR = val;
  27551. ETH->MACMIIAR &= (7 << 2);
  27552. ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6) | MG_BIT(1);
  27553. ETH->MACMIIAR |= MG_BIT(0);
  27554. while (ETH->MACMIIAR & MG_BIT(0)) (void) 0;
  27555. }
  27556. static uint32_t get_hclk(void) {
  27557. struct rcc {
  27558. volatile uint32_t CR, PLLCFGR, CFGR;
  27559. } *rcc = (struct rcc *) 0x40023800;
  27560. uint32_t clk = 0, hsi = 16000000 /* 16 MHz */, hse = 8000000 /* 8MHz */;
  27561. if (rcc->CFGR & (1 << 2)) {
  27562. clk = hse;
  27563. } else if (rcc->CFGR & (1 << 3)) {
  27564. uint32_t vco, m, n, p;
  27565. m = (rcc->PLLCFGR & (0x3f << 0)) >> 0;
  27566. n = (rcc->PLLCFGR & (0x1ff << 6)) >> 6;
  27567. p = (((rcc->PLLCFGR & (3 << 16)) >> 16) + 1) * 2;
  27568. clk = (rcc->PLLCFGR & (1 << 22)) ? hse : hsi;
  27569. vco = (uint32_t) ((uint64_t) clk * n / m);
  27570. clk = vco / p;
  27571. } else {
  27572. clk = hsi;
  27573. }
  27574. uint32_t hpre = (rcc->CFGR & (15 << 4)) >> 4;
  27575. if (hpre < 8) return clk;
  27576. uint8_t ahbptab[8] = {1, 2, 3, 4, 6, 7, 8, 9}; // log2(div)
  27577. return ((uint32_t) clk) >> ahbptab[hpre - 8];
  27578. }
  27579. // Guess CR from HCLK. MDC clock is generated from HCLK (AHB); as per 802.3,
  27580. // it must not exceed 2.5MHz As the AHB clock can be (and usually is) derived
  27581. // from the HSI (internal RC), and it can go above specs, the datasheets
  27582. // specify a range of frequencies and activate one of a series of dividers to
  27583. // keep the MDC clock safely below 2.5MHz. We guess a divider setting based on
  27584. // HCLK with a +5% drift. If the user uses a different clock from our
  27585. // defaults, needs to set the macros on top Valid for STM32F74xxx/75xxx
  27586. // (38.8.1) and STM32F42xxx/43xxx (33.8.1) (both 4.5% worst case drift)
  27587. static int guess_mdc_cr(void) {
  27588. uint8_t crs[] = {2, 3, 0, 1, 4, 5}; // ETH->MACMIIAR::CR values
  27589. uint8_t div[] = {16, 26, 42, 62, 102, 124}; // Respective HCLK dividers
  27590. uint32_t hclk = get_hclk(); // Guess system HCLK
  27591. int result = -1; // Invalid CR value
  27592. if (hclk < 25000000) {
  27593. MG_ERROR(("HCLK too low"));
  27594. } else {
  27595. for (int i = 0; i < 6; i++) {
  27596. if (hclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) {
  27597. result = crs[i];
  27598. break;
  27599. }
  27600. }
  27601. if (result < 0) MG_ERROR(("HCLK too high"));
  27602. }
  27603. MG_DEBUG(("HCLK: %u, CR: %d", hclk, result));
  27604. return result;
  27605. }
  27606. static bool mg_tcpip_driver_stm32f_init(struct mg_tcpip_if *ifp) {
  27607. struct mg_tcpip_driver_stm32f_data *d =
  27608. (struct mg_tcpip_driver_stm32f_data *) ifp->driver_data;
  27609. uint8_t phy_addr = d == NULL ? 0 : d->phy_addr;
  27610. s_ifp = ifp;
  27611. // Init RX descriptors
  27612. for (int i = 0; i < ETH_DESC_CNT; i++) {
  27613. s_rxdesc[i][0] = MG_BIT(31); // Own
  27614. s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | MG_BIT(14); // 2nd address chained
  27615. s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
  27616. s_rxdesc[i][3] =
  27617. (uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain
  27618. }
  27619. // Init TX descriptors
  27620. for (int i = 0; i < ETH_DESC_CNT; i++) {
  27621. s_txdesc[i][2] = (uint32_t) (uintptr_t) s_txbuf[i]; // Buf pointer
  27622. s_txdesc[i][3] =
  27623. (uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain
  27624. }
  27625. ETH->DMABMR |= MG_BIT(0); // Software reset
  27626. while ((ETH->DMABMR & MG_BIT(0)) != 0) (void) 0; // Wait until done
  27627. // Set MDC clock divider. If user told us the value, use it. Otherwise, guess
  27628. int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
  27629. ETH->MACMIIAR = ((uint32_t) cr & 7) << 2;
  27630. // NOTE(cpq): we do not use extended descriptor bit 7, and do not use
  27631. // hardware checksum. Therefore, descriptor size is 4, not 8
  27632. // ETH->DMABMR = MG_BIT(13) | MG_BIT(16) | MG_BIT(22) | MG_BIT(23) |
  27633. // MG_BIT(25);
  27634. ETH->MACIMR = MG_BIT(3) | MG_BIT(9); // Mask timestamp & PMT IT
  27635. ETH->MACFCR = MG_BIT(7); // Disable zero quarta pause
  27636. ETH->MACFFR = MG_BIT(10); // Perfect filtering
  27637. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  27638. mg_phy_init(&phy, phy_addr, MG_PHY_CLOCKS_MAC);
  27639. ETH->DMARDLAR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
  27640. ETH->DMATDLAR = (uint32_t) (uintptr_t) s_txdesc; // RX descriptors
  27641. ETH->DMAIER = MG_BIT(6) | MG_BIT(16); // RIE, NISE
  27642. ETH->MACCR =
  27643. MG_BIT(2) | MG_BIT(3) | MG_BIT(11) | MG_BIT(14); // RE, TE, Duplex, Fast
  27644. ETH->DMAOMR =
  27645. MG_BIT(1) | MG_BIT(13) | MG_BIT(21) | MG_BIT(25); // SR, ST, TSF, RSF
  27646. // MAC address filtering
  27647. ETH->MACA0HR = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
  27648. ETH->MACA0LR = (uint32_t) (ifp->mac[3] << 24) |
  27649. ((uint32_t) ifp->mac[2] << 16) |
  27650. ((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
  27651. return true;
  27652. }
  27653. static size_t mg_tcpip_driver_stm32f_tx(const void *buf, size_t len,
  27654. struct mg_tcpip_if *ifp) {
  27655. if (len > sizeof(s_txbuf[s_txno])) {
  27656. MG_ERROR(("Frame too big, %ld", (long) len));
  27657. len = 0; // Frame is too big
  27658. } else if ((s_txdesc[s_txno][0] & MG_BIT(31))) {
  27659. ifp->nerr++;
  27660. MG_ERROR(("No free descriptors"));
  27661. // printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long) ETH->DMASR);
  27662. len = 0; // All descriptors are busy, fail
  27663. } else {
  27664. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  27665. s_txdesc[s_txno][1] = (uint32_t) len; // Set data len
  27666. s_txdesc[s_txno][0] = MG_BIT(20) | MG_BIT(28) | MG_BIT(29); // Chain,FS,LS
  27667. s_txdesc[s_txno][0] |= MG_BIT(31); // Set OWN bit - let DMA take over
  27668. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  27669. }
  27670. MG_DSB(); // ensure descriptors have been written
  27671. ETH->DMASR = MG_BIT(2) | MG_BIT(5); // Clear any prior TBUS/TUS
  27672. ETH->DMATPDR = 0; // and resume
  27673. return len;
  27674. }
  27675. static void mg_tcpip_driver_stm32f_update_hash_table(struct mg_tcpip_if *ifp) {
  27676. // TODO(): read database, rebuild hash table
  27677. ETH->MACA1LR = (uint32_t) mcast_addr[3] << 24 |
  27678. (uint32_t) mcast_addr[2] << 16 |
  27679. (uint32_t) mcast_addr[1] << 8 | (uint32_t) mcast_addr[0];
  27680. ETH->MACA1HR = (uint32_t) mcast_addr[5] << 8 | (uint32_t) mcast_addr[4];
  27681. ETH->MACA1HR |= MG_BIT(31); // AE
  27682. (void) ifp;
  27683. }
  27684. static bool mg_tcpip_driver_stm32f_poll(struct mg_tcpip_if *ifp, bool s1) {
  27685. if (ifp->update_mac_hash_table) {
  27686. mg_tcpip_driver_stm32f_update_hash_table(ifp);
  27687. ifp->update_mac_hash_table = false;
  27688. }
  27689. if (!s1) return false;
  27690. struct mg_tcpip_driver_stm32f_data *d =
  27691. (struct mg_tcpip_driver_stm32f_data *) ifp->driver_data;
  27692. uint8_t phy_addr = d == NULL ? 0 : d->phy_addr;
  27693. uint8_t speed = MG_PHY_SPEED_10M;
  27694. bool up = false, full_duplex = false;
  27695. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  27696. up = mg_phy_up(&phy, phy_addr, &full_duplex, &speed);
  27697. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  27698. // tmp = reg with flags set to the most likely situation: 100M full-duplex
  27699. // if(link is slow or half) set flags otherwise
  27700. // reg = tmp
  27701. uint32_t maccr = ETH->MACCR | MG_BIT(14) | MG_BIT(11); // 100M, Full-duplex
  27702. if (speed == MG_PHY_SPEED_10M) maccr &= ~MG_BIT(14); // 10M
  27703. if (full_duplex == false) maccr &= ~MG_BIT(11); // Half-duplex
  27704. ETH->MACCR = maccr; // IRQ handler does not fiddle with this register
  27705. MG_DEBUG(("Link is %uM %s-duplex", maccr & MG_BIT(14) ? 100 : 10,
  27706. maccr & MG_BIT(11) ? "full" : "half"));
  27707. }
  27708. return up;
  27709. }
  27710. #ifdef __riscv
  27711. __attribute__((interrupt())) // For RISCV CH32V307, which share the same MAC
  27712. #endif
  27713. void ETH_IRQHandler(void);
  27714. void ETH_IRQHandler(void) {
  27715. if (ETH->DMASR & MG_BIT(6)) { // Frame received, loop
  27716. ETH->DMASR = MG_BIT(16) | MG_BIT(6); // Clear flag
  27717. for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
  27718. if (s_rxdesc[s_rxno][0] & MG_BIT(31)) break; // exit when done
  27719. if (((s_rxdesc[s_rxno][0] & (MG_BIT(8) | MG_BIT(9))) ==
  27720. (MG_BIT(8) | MG_BIT(9))) &&
  27721. !(s_rxdesc[s_rxno][0] & MG_BIT(15))) { // skip partial/errored frames
  27722. uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (MG_BIT(14) - 1));
  27723. // printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
  27724. // ETH->DMASR);
  27725. mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
  27726. }
  27727. s_rxdesc[s_rxno][0] = MG_BIT(31);
  27728. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  27729. }
  27730. }
  27731. // Cleanup flags
  27732. ETH->DMASR = MG_BIT(16) // NIS, normal interrupt summary
  27733. | MG_BIT(7); // Clear possible RBUS while processing
  27734. ETH->DMARPDR = 0; // and resume RX
  27735. }
  27736. struct mg_tcpip_driver mg_tcpip_driver_stm32f = {
  27737. mg_tcpip_driver_stm32f_init, mg_tcpip_driver_stm32f_tx, NULL,
  27738. mg_tcpip_driver_stm32f_poll};
  27739. #endif
  27740. #ifdef MG_ENABLE_LINES
  27741. #line 1 "src/drivers/stm32h.c"
  27742. #endif
  27743. #if MG_ENABLE_TCPIP && (MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_MCXN || \
  27744. MG_ENABLE_DRIVER_STM32N)
  27745. // STM32H: vendor modded single-queue Synopsys v4.2
  27746. // STM32N: dual-queue GbE Synopsys v5.2 with no hash table option, 64-bit AXI
  27747. // MCXNx4x: dual-queue Synopsys v5.2 with no hash table option
  27748. // RT1170: ENET_QOS: quad-queue Synopsys v5.1
  27749. #if MG_ENABLE_DRIVER_STM32H
  27750. #define SYNOPSYS_ENET_V5 0
  27751. #define SYNOPSYS_ENET_SINGLEQ 1
  27752. #define SYNOPSYS_ENET_NOHASHTABLE 0
  27753. #define SYNOPSYS_ENET_GbE 0
  27754. #elif MG_ENABLE_DRIVER_STM32N
  27755. #define SYNOPSYS_ENET_V5 1
  27756. #define SYNOPSYS_ENET_SINGLEQ 0
  27757. #define SYNOPSYS_ENET_NOHASHTABLE 1
  27758. #define SYNOPSYS_ENET_GbE 1
  27759. #elif MG_ENABLE_DRIVER_MCXN
  27760. #define SYNOPSYS_ENET_V5 1
  27761. #define SYNOPSYS_ENET_SINGLEQ 0
  27762. #define SYNOPSYS_ENET_NOHASHTABLE 1
  27763. #define SYNOPSYS_ENET_GbE 0
  27764. #endif
  27765. struct synopsys_enet_qos {
  27766. volatile uint32_t MACCR, MACECR, MACPFR, MACWTR, MACHT0R, MACHT1R,
  27767. RESERVED1[14], MACVTR, RESERVED2, MACVHTR, RESERVED3, MACVIR, MACIVIR,
  27768. RESERVED4[2], MACTFCR, RESERVED5[7], MACRFCR, RESERVED6[7], MACISR,
  27769. MACIER, MACRXTXSR, RESERVED7, MACPCSR, MACRWKPFR, RESERVED8[2], MACLCSR,
  27770. MACLTCR, MACLETR, MAC1USTCR, RESERVED9[12], MACVR, MACDR, RESERVED10,
  27771. MACHWF0R, MACHWF1R, MACHWF2R, RESERVED11[54], MACMDIOAR, MACMDIODR,
  27772. RESERVED12[2], MACARPAR, RESERVED13[59], MACA0HR, MACA0LR, MACA1HR,
  27773. MACA1LR, MACA2HR, MACA2LR, MACA3HR, MACA3LR, RESERVED14[248], MMCCR,
  27774. MMCRIR, MMCTIR, MMCRIMR, MMCTIMR, RESERVED15[14], MMCTSCGPR, MMCTMCGPR,
  27775. RESERVED16[5], MMCTPCGR, RESERVED17[10], MMCRCRCEPR, MMCRAEPR,
  27776. RESERVED18[10], MMCRUPGR, RESERVED19[9], MMCTLPIMSTR, MMCTLPITCR,
  27777. MMCRLPIMSTR, MMCRLPITCR, RESERVED20[65], MACL3L4C0R, MACL4A0R,
  27778. RESERVED21[2], MACL3A0R0R, MACL3A1R0R, MACL3A2R0R, MACL3A3R0R,
  27779. RESERVED22[4], MACL3L4C1R, MACL4A1R, RESERVED23[2], MACL3A0R1R,
  27780. MACL3A1R1R, MACL3A2R1R, MACL3A3R1R, RESERVED24[108], MACTSCR, MACSSIR,
  27781. MACSTSR, MACSTNR, MACSTSUR, MACSTNUR, MACTSAR, RESERVED25, MACTSSR,
  27782. RESERVED26[3], MACTTSSNR, MACTTSSSR, RESERVED27[2], MACACR, RESERVED28,
  27783. MACATSNR, MACATSSR, MACTSIACR, MACTSEACR, MACTSICNR, MACTSECNR,
  27784. RESERVED29[4], MACPPSCR, RESERVED30[3], MACPPSTTSR, MACPPSTTNR, MACPPSIR,
  27785. MACPPSWR, RESERVED31[12], MACPOCR, MACSPI0R, MACSPI1R, MACSPI2R, MACLMIR,
  27786. RESERVED32[11], MTLOMR, RESERVED33[7], MTLISR, RESERVED34[55], MTLTQOMR,
  27787. MTLTQUR, MTLTQDR, RESERVED35[8], MTLQICSR, MTLRQOMR, MTLRQMPOCR, MTLRQDR,
  27788. RESERVED36[177], DMAMR, DMASBMR, DMAISR, DMADSR, RESERVED37[60], DMACCR,
  27789. DMACTCR, DMACRCR, RESERVED38[2], DMACTDLAR, RESERVED39, DMACRDLAR,
  27790. DMACTDTPR, RESERVED40, DMACRDTPR, DMACTDRLR, DMACRDRLR, DMACIER,
  27791. DMACRIWTR, DMACSFCSR, RESERVED41, DMACCATDR, RESERVED42, DMACCARDR,
  27792. RESERVED43, DMACCATBR, RESERVED44, DMACCARBR, DMACSR, RESERVED45[2],
  27793. DMACMFCR;
  27794. };
  27795. #undef ETH
  27796. #if MG_ENABLE_DRIVER_STM32H
  27797. #define ETH ((struct synopsys_enet_qos *) (uintptr_t) 0x40028000UL)
  27798. #elif MG_ENABLE_DRIVER_STM32N
  27799. #define ETH ((struct synopsys_enet_qos *) (uintptr_t) 0x48036000UL)
  27800. #elif MG_ENABLE_DRIVER_MCXN
  27801. #define ETH ((struct synopsys_enet_qos *) (uintptr_t) 0x40100000UL)
  27802. #endif
  27803. #define ETH_PKT_SIZE 1540 // Max frame size
  27804. #define ETH_DESC_CNT 4 // Descriptors count
  27805. #define ETH_DS 4 // Descriptor size (words)
  27806. #if MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_STM32N
  27807. #define CACHE_LINESZ 32 // must be a whole number of (d)words (see DESC_SZW)
  27808. #ifndef SCB
  27809. struct m7_scb {
  27810. volatile uint32_t CPUID, RESERVED1[4], CCR, RESERVED2[145], DCIMVAC, DCISW,
  27811. DCCMVAU, DCCMVAC, DCCSW, DCCIMVAC, DCCISW, RESERVED3[10], CACR,
  27812. RESERVED4[3];
  27813. };
  27814. #define SCB ((struct m7_scb *) (uintptr_t) 0xE000ED00UL)
  27815. #endif
  27816. // ending ISB is not needed because we don't cache instructions in data space
  27817. static inline void MG_CACHE_INVAL(uint8_t *addr, int32_t len) {
  27818. #if MG_ENABLE_DRIVER_STM32H
  27819. if ((SCB->CPUID & 0xfff0) != 0xc270) return; // not a Cortex-M7 => not an H7
  27820. #endif
  27821. if ((SCB->CCR & MG_BIT(16)) == 0) return; // cache not enabled
  27822. MG_DSB();
  27823. while (len > 0) {
  27824. SCB->DCIMVAC = (uint32_t) addr;
  27825. addr += CACHE_LINESZ;
  27826. len -= CACHE_LINESZ;
  27827. }
  27828. MG_DSB();
  27829. }
  27830. static inline void MG_CACHE_FLUSH(uint8_t *addr, int32_t len) {
  27831. #if MG_ENABLE_DRIVER_STM32H
  27832. if ((SCB->CPUID & 0xfff0) != 0xc270) return; // not a Cortex-M7 => not an H7
  27833. #endif
  27834. if ((SCB->CCR & MG_BIT(16)) == 0) return; // cache not enabled
  27835. MG_DSB();
  27836. while (len > 0) {
  27837. SCB->DCCMVAC = (uint32_t) addr;
  27838. addr += CACHE_LINESZ;
  27839. len -= CACHE_LINESZ;
  27840. }
  27841. MG_DSB();
  27842. }
  27843. #define ETH_RAM_ALIGNED MG_32BYTE_ALIGNED // depends on CACHE_LINESZ and ETH
  27844. #define CACHE_ALIGN(x) \
  27845. ((((size_t) (x)) + CACHE_LINESZ - 1) & ~(CACHE_LINESZ - 1))
  27846. #define DESC_SZ CACHE_ALIGN(4 * ETH_DS) // grow descriptors to fit a line
  27847. #define DESC_SZW (DESC_SZ / 4)
  27848. #define BUFF_SZ CACHE_ALIGN(ETH_PKT_SIZE) // grow buffers to fit n lines
  27849. #if MG_ENABLE_DRIVER_STM32H
  27850. #define DESC_SKIPW (DESC_SZW - ETH_DS) // tell DMA the descriptor size, words
  27851. #else
  27852. // MG_ENABLE_DRIVER_STM32N, DMA is AXI and specs skip in 64-bit double-words
  27853. #define DESC_SKIPW ((DESC_SZW - ETH_DS) / 2)
  27854. #endif
  27855. #else
  27856. #define MG_CACHE_FLUSH(a, b)
  27857. #define MG_CACHE_INVAL(a, b)
  27858. #define ETH_RAM_ALIGNED MG_8BYTE_ALIGNED // depends on ETH DMA alone
  27859. #define DESC_SZ 0
  27860. #define DESC_SZW ETH_DS
  27861. #define BUFF_SZ ETH_PKT_SIZE
  27862. #define DESC_SKIPW 0 // no need to skip, as we're not aligning to cache lines
  27863. #endif
  27864. // array[rows][cols] = coldata coldata ... for all rows, keeps alignment
  27865. static volatile uint32_t s_rxdesc[ETH_DESC_CNT][DESC_SZW] MG_ETH_RAM
  27866. ETH_RAM_ALIGNED;
  27867. static volatile uint32_t s_txdesc[ETH_DESC_CNT][DESC_SZW] MG_ETH_RAM
  27868. ETH_RAM_ALIGNED;
  27869. static uint8_t s_rxbuf[ETH_DESC_CNT][BUFF_SZ] MG_ETH_RAM ETH_RAM_ALIGNED;
  27870. static uint8_t s_txbuf[ETH_DESC_CNT][BUFF_SZ] MG_ETH_RAM ETH_RAM_ALIGNED;
  27871. static struct mg_tcpip_if *s_ifp; // MIP interface
  27872. static uint16_t eth_read_phy(uint8_t addr, uint8_t reg) {
  27873. ETH->MACMDIOAR &= (0xF << 8);
  27874. ETH->MACMDIOAR |= ((uint32_t) addr << 21) | ((uint32_t) reg << 16) | 3 << 2;
  27875. ETH->MACMDIOAR |= MG_BIT(0);
  27876. while (ETH->MACMDIOAR & MG_BIT(0)) (void) 0;
  27877. return (uint16_t) ETH->MACMDIODR;
  27878. }
  27879. static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
  27880. ETH->MACMDIODR = val;
  27881. ETH->MACMDIOAR &= (0xF << 8);
  27882. ETH->MACMDIOAR |= ((uint32_t) addr << 21) | ((uint32_t) reg << 16) | 1 << 2;
  27883. ETH->MACMDIOAR |= MG_BIT(0);
  27884. while (ETH->MACMDIOAR & MG_BIT(0)) (void) 0;
  27885. }
  27886. static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
  27887. struct mg_tcpip_driver_stm32h_data *d =
  27888. (struct mg_tcpip_driver_stm32h_data *) ifp->driver_data;
  27889. s_ifp = ifp;
  27890. uint8_t phy_addr = d == NULL ? 0 : d->phy_addr;
  27891. uint8_t phy_conf = d == NULL ? MG_PHY_CLOCKS_MAC : d->phy_conf;
  27892. // Init RX descriptors
  27893. memset((char *) s_rxdesc, 0, sizeof(s_rxdesc)); // manual init
  27894. for (int i = 0; i < ETH_DESC_CNT; i++) {
  27895. s_rxdesc[i][0] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
  27896. s_rxdesc[i][3] = MG_BIT(31) | MG_BIT(30) | MG_BIT(24); // OWN, IOC, BUF1V
  27897. }
  27898. MG_CACHE_FLUSH((uint8_t *) s_rxdesc, sizeof(s_rxdesc));
  27899. // Init TX descriptors
  27900. memset((char *) s_txdesc, 0, sizeof(s_txdesc)); // manual init
  27901. for (int i = 0; i < ETH_DESC_CNT; i++) {
  27902. s_txdesc[i][0] = (uint32_t) (uintptr_t) s_txbuf[i]; // Buf pointer
  27903. }
  27904. MG_CACHE_FLUSH((uint8_t *) s_txdesc, sizeof(s_txdesc));
  27905. ETH->DMAMR |= MG_BIT(0); // Software reset
  27906. for (int i = 0; i < 4; i++)
  27907. (void) 0; // wait at least 4 clocks before reading
  27908. while ((ETH->DMAMR & MG_BIT(0)) != 0) (void) 0; // Wait until done
  27909. // Set MDC clock divider. Get user value, else, assume max freq
  27910. int cr = (d == NULL || d->mdc_cr < 0) ? 7 : d->mdc_cr;
  27911. ETH->MACMDIOAR = ((uint32_t) cr & 0xF) << 8;
  27912. // NOTE(scaprile): We do not use timing facilities so the DMA engine does not
  27913. // re-write buffer address
  27914. ETH->DMAMR = 0 << 16; // use interrupt mode 0 (58.8.1) (reset value)
  27915. ETH->DMASBMR |= MG_BIT(12); // AAL NOTE(scaprile): is this actually needed
  27916. ETH->MACIER = 0; // Do not enable additional irq sources (reset value)
  27917. ETH->MACTFCR = MG_BIT(7); // Disable zero-quanta pause
  27918. #if !SYNOPSYS_ENET_V5
  27919. ETH->MACPFR = MG_BIT(10); // Perfect filtering
  27920. #endif
  27921. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  27922. mg_phy_init(&phy, phy_addr, phy_conf);
  27923. ETH->DMACRDLAR =
  27924. (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors start address
  27925. ETH->DMACRDRLR = ETH_DESC_CNT - 1; // ring length
  27926. ETH->DMACRDTPR =
  27927. (uint32_t) (uintptr_t) &s_rxdesc[ETH_DESC_CNT -
  27928. 1]; // last valid descriptor address
  27929. ETH->DMACTDLAR =
  27930. (uint32_t) (uintptr_t) s_txdesc; // TX descriptors start address
  27931. ETH->DMACTDRLR = ETH_DESC_CNT - 1; // ring length
  27932. ETH->DMACTDTPR =
  27933. (uint32_t) (uintptr_t) s_txdesc; // first available descriptor address
  27934. ETH->DMACCR = DESC_SKIPW << 18; // DSL (contiguous/sparse descriptor table)
  27935. #if SYNOPSYS_ENET_V5
  27936. MG_SET_BITS(ETH->DMACTCR, 0x3F << 16, MG_BIT(16));
  27937. MG_SET_BITS(ETH->DMACRCR, 0x3F << 16, MG_BIT(16));
  27938. #endif
  27939. ETH->DMACIER = MG_BIT(6) | MG_BIT(15); // RIE, NIE
  27940. ETH->MACCR = MG_BIT(0) | MG_BIT(1) | MG_BIT(13) | MG_BIT(14) |
  27941. MG_BIT(15); // RE, TE, Duplex, Fast, (10/100)/Reserved
  27942. #if SYNOPSYS_ENET_SINGLEQ
  27943. ETH->MTLTQOMR |= MG_BIT(1); // TSF
  27944. ETH->MTLRQOMR |= MG_BIT(5); // RSF
  27945. #else
  27946. ETH->MTLTQOMR |= (7 << 16) | MG_BIT(3) | MG_BIT(1); // 2KB Q0, TSF
  27947. ETH->MTLRQOMR |= (7 << 20) | MG_BIT(5); // 2KB Q, RSF
  27948. MG_SET_BITS(ETH->RESERVED6[3], 3, 2); // Enable RxQ0 (MAC_RXQ_CTRL0)
  27949. #endif
  27950. ETH->DMACTCR |= MG_BIT(0); // ST
  27951. ETH->DMACRCR |= MG_BIT(0); // SR
  27952. // MAC address filtering
  27953. ETH->MACA0HR = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
  27954. ETH->MACA0LR = (uint32_t) (ifp->mac[3] << 24) |
  27955. ((uint32_t) ifp->mac[2] << 16) |
  27956. ((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
  27957. return true;
  27958. }
  27959. static uint32_t s_txno;
  27960. static size_t mg_tcpip_driver_stm32h_tx(const void *buf, size_t len,
  27961. struct mg_tcpip_if *ifp) {
  27962. if (len > sizeof(s_txbuf[s_txno])) {
  27963. MG_ERROR(("Frame too big, %ld", (long) len));
  27964. return 0; // Frame is too big
  27965. }
  27966. MG_CACHE_INVAL((uint8_t *) &s_txdesc[s_txno], DESC_SZ);
  27967. if ((s_txdesc[s_txno][3] & MG_BIT(31))) {
  27968. ifp->nerr++;
  27969. MG_ERROR(("No free descriptors: %u %08X %08X %08X", s_txno,
  27970. s_txdesc[s_txno][3], ETH->DMACSR, ETH->DMACTCR));
  27971. MG_CACHE_INVAL((uint8_t *) s_txdesc, sizeof(s_txdesc));
  27972. for (int i = 0; i < ETH_DESC_CNT; i++) MG_ERROR(("%08X", s_txdesc[i][3]));
  27973. len = 0; // All descriptors are busy, fail
  27974. } else {
  27975. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  27976. MG_CACHE_FLUSH((uint8_t *) &s_txbuf[s_txno], BUFF_SZ);
  27977. s_txdesc[s_txno][2] = (uint32_t) len; // Set data len
  27978. s_txdesc[s_txno][3] = MG_BIT(28) | MG_BIT(29); // FD, LD
  27979. s_txdesc[s_txno][3] |= MG_BIT(31); // Set OWN bit - let DMA take over
  27980. MG_CACHE_FLUSH((uint8_t *) &s_txdesc[s_txno], DESC_SZ);
  27981. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  27982. }
  27983. ETH->DMACSR |= MG_BIT(2) | MG_BIT(1); // Clear any prior TBU, TPS
  27984. ETH->DMACTDTPR = (uint32_t) (uintptr_t) &s_txdesc[s_txno]; // and resume
  27985. return len;
  27986. (void) ifp;
  27987. }
  27988. static void mg_tcpip_driver_stm32h_update_hash_table(struct mg_tcpip_if *ifp) {
  27989. #if SYNOPSYS_ENET_NOHASHTABLE
  27990. ETH->MACPFR = MG_BIT(4); // Pass Multicast (pass all multicast frames)
  27991. #else
  27992. // TODO(): read database, rebuild hash table
  27993. // add mDNS / DNS-SD multicast address
  27994. ETH->MACA1LR = (uint32_t) mcast_addr[3] << 24 |
  27995. (uint32_t) mcast_addr[2] << 16 |
  27996. (uint32_t) mcast_addr[1] << 8 | (uint32_t) mcast_addr[0];
  27997. ETH->MACA1HR = (uint32_t) mcast_addr[5] << 8 | (uint32_t) mcast_addr[4];
  27998. ETH->MACA1HR |= MG_BIT(31); // AE
  27999. #endif
  28000. (void) ifp;
  28001. }
  28002. static bool mg_tcpip_driver_stm32h_poll(struct mg_tcpip_if *ifp, bool s1) {
  28003. if (ifp->update_mac_hash_table) {
  28004. mg_tcpip_driver_stm32h_update_hash_table(ifp);
  28005. ifp->update_mac_hash_table = false;
  28006. }
  28007. if (!s1) return false;
  28008. struct mg_tcpip_driver_stm32h_data *d =
  28009. (struct mg_tcpip_driver_stm32h_data *) ifp->driver_data;
  28010. uint8_t phy_addr = d == NULL ? 0 : d->phy_addr;
  28011. uint8_t speed = MG_PHY_SPEED_10M;
  28012. bool up = false, full_duplex = false;
  28013. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  28014. up = mg_phy_up(&phy, phy_addr, &full_duplex, &speed);
  28015. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  28016. // tmp = reg with flags set to the most likely situation: 100M full-duplex
  28017. // if(link is slow or half) set flags otherwise
  28018. // reg = tmp
  28019. uint32_t maccr = ETH->MACCR | MG_BIT(14) | MG_BIT(13); // 100M, Full-duplex
  28020. #if SYNOPSYS_ENET_GbE
  28021. if (speed == MG_PHY_SPEED_1000M) maccr &= ~MG_BIT(15); // 1000M
  28022. #endif
  28023. if (speed == MG_PHY_SPEED_10M) maccr &= ~MG_BIT(14); // 10M
  28024. if (full_duplex == false) maccr &= ~MG_BIT(13); // Half-duplex
  28025. ETH->MACCR = maccr; // IRQ handler does not fiddle with this register
  28026. MG_DEBUG(("Link is %uM %s-duplex", maccr & MG_BIT(14) ? 100 : 10,
  28027. maccr & MG_BIT(13) ? "full" : "half"));
  28028. }
  28029. return up;
  28030. }
  28031. static uint32_t s_rxno;
  28032. #if MG_ENABLE_DRIVER_MCXN
  28033. void ETHERNET_IRQHandler(void);
  28034. void ETHERNET_IRQHandler(void) {
  28035. #elif MG_ENABLE_DRIVER_STM32H
  28036. void ETH_IRQHandler(void);
  28037. void ETH_IRQHandler(void) {
  28038. #else
  28039. void ETH1_IRQHandler(void);
  28040. void ETH1_IRQHandler(void) {
  28041. #endif
  28042. if (ETH->DMACSR & MG_BIT(6)) { // Frame received, loop
  28043. ETH->DMACSR = MG_BIT(15) | MG_BIT(6); // Clear flag
  28044. for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
  28045. MG_CACHE_INVAL((uint8_t *) &s_rxdesc[s_rxno], DESC_SZ);
  28046. if (s_rxdesc[s_rxno][3] & MG_BIT(31)) break; // exit when done
  28047. if (((s_rxdesc[s_rxno][3] & (MG_BIT(28) | MG_BIT(29))) ==
  28048. (MG_BIT(28) | MG_BIT(29))) &&
  28049. !(s_rxdesc[s_rxno][3] & MG_BIT(15))) { // skip partial/errored frames
  28050. uint32_t len = s_rxdesc[s_rxno][3] & (MG_BIT(15) - 1);
  28051. // MG_DEBUG(("%lx %lu %lx %08lx", s_rxno, len, s_rxdesc[s_rxno][3],
  28052. // ETH->DMACSR));
  28053. MG_CACHE_INVAL((uint8_t *) &s_rxbuf[s_rxno], BUFF_SZ);
  28054. mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
  28055. }
  28056. s_rxdesc[s_rxno][3] =
  28057. MG_BIT(31) | MG_BIT(30) | MG_BIT(24); // OWN, IOC, BUF1V
  28058. MG_CACHE_FLUSH((uint8_t *) &s_rxdesc[s_rxno], DESC_SZ);
  28059. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  28060. }
  28061. }
  28062. ETH->DMACSR =
  28063. MG_BIT(7) | MG_BIT(8); // Clear possible RBU RPS while processing
  28064. ETH->DMACRDTPR =
  28065. (uint32_t) (uintptr_t) &s_rxdesc[ETH_DESC_CNT - 1]; // and resume RX
  28066. }
  28067. struct mg_tcpip_driver mg_tcpip_driver_stm32h = {
  28068. mg_tcpip_driver_stm32h_init, mg_tcpip_driver_stm32h_tx, NULL,
  28069. mg_tcpip_driver_stm32h_poll};
  28070. #endif
  28071. #ifdef MG_ENABLE_LINES
  28072. #line 1 "src/drivers/tm4c.c"
  28073. #endif
  28074. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
  28075. struct tm4c_emac {
  28076. volatile uint32_t EMACCFG, EMACFRAMEFLTR, EMACHASHTBLH, EMACHASHTBLL,
  28077. EMACMIIADDR, EMACMIIDATA, EMACFLOWCTL, EMACVLANTG, RESERVED0, EMACSTATUS,
  28078. EMACRWUFF, EMACPMTCTLSTAT, RESERVED1[2], EMACRIS, EMACIM, EMACADDR0H,
  28079. EMACADDR0L, EMACADDR1H, EMACADDR1L, EMACADDR2H, EMACADDR2L, EMACADDR3H,
  28080. EMACADDR3L, RESERVED2[31], EMACWDOGTO, RESERVED3[8], EMACMMCCTRL,
  28081. EMACMMCRXRIS, EMACMMCTXRIS, EMACMMCRXIM, EMACMMCTXIM, RESERVED4,
  28082. EMACTXCNTGB, RESERVED5[12], EMACTXCNTSCOL, EMACTXCNTMCOL, RESERVED6[4],
  28083. EMACTXOCTCNTG, RESERVED7[6], EMACRXCNTGB, RESERVED8[4], EMACRXCNTCRCERR,
  28084. EMACRXCNTALGNERR, RESERVED9[10], EMACRXCNTGUNI, RESERVED10[239],
  28085. EMACVLNINCREP, EMACVLANHASH, RESERVED11[93], EMACTIMSTCTRL, EMACSUBSECINC,
  28086. EMACTIMSEC, EMACTIMNANO, EMACTIMSECU, EMACTIMNANOU, EMACTIMADD,
  28087. EMACTARGSEC, EMACTARGNANO, EMACHWORDSEC, EMACTIMSTAT, EMACPPSCTRL,
  28088. RESERVED12[12], EMACPPS0INTVL, EMACPPS0WIDTH, RESERVED13[294],
  28089. EMACDMABUSMOD, EMACTXPOLLD, EMACRXPOLLD, EMACRXDLADDR, EMACTXDLADDR,
  28090. EMACDMARIS, EMACDMAOPMODE, EMACDMAIM, EMACMFBOC, EMACRXINTWDT,
  28091. RESERVED14[8], EMACHOSTXDESC, EMACHOSRXDESC, EMACHOSTXBA, EMACHOSRXBA,
  28092. RESERVED15[218], EMACPP, EMACPC, EMACCC, RESERVED16, EMACEPHYRIS,
  28093. EMACEPHYIM, EMACEPHYIMSC;
  28094. };
  28095. #undef EMAC
  28096. #define EMAC ((struct tm4c_emac *) (uintptr_t) 0x400EC000)
  28097. #define ETH_PKT_SIZE 1540 // Max frame size
  28098. #define ETH_DESC_CNT 4 // Descriptors count
  28099. #define ETH_DS 4 // Descriptor size (words)
  28100. static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
  28101. static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
  28102. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
  28103. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
  28104. static struct mg_tcpip_if *s_ifp; // MIP interface
  28105. enum {
  28106. EPHY_ADDR = 0,
  28107. EPHYBMCR = 0,
  28108. EPHYBMSR = 1,
  28109. EPHYSTS = 16
  28110. }; // PHY constants
  28111. static inline void tm4cspin(volatile uint32_t count) {
  28112. while (count--) (void) 0;
  28113. }
  28114. static uint32_t emac_read_phy(uint8_t addr, uint8_t reg) {
  28115. EMAC->EMACMIIADDR &= (0xf << 2);
  28116. EMAC->EMACMIIADDR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6);
  28117. EMAC->EMACMIIADDR |= MG_BIT(0);
  28118. while (EMAC->EMACMIIADDR & MG_BIT(0)) tm4cspin(1);
  28119. return EMAC->EMACMIIDATA;
  28120. }
  28121. static void emac_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
  28122. EMAC->EMACMIIDATA = val;
  28123. EMAC->EMACMIIADDR &= (0xf << 2);
  28124. EMAC->EMACMIIADDR |=
  28125. ((uint32_t) addr << 11) | ((uint32_t) reg << 6) | MG_BIT(1);
  28126. EMAC->EMACMIIADDR |= MG_BIT(0);
  28127. while (EMAC->EMACMIIADDR & MG_BIT(0)) tm4cspin(1);
  28128. }
  28129. static uint32_t get_sysclk(void) {
  28130. struct sysctl {
  28131. volatile uint32_t DONTCARE0[44], RSCLKCFG, DONTCARE1[43], PLLFREQ0,
  28132. PLLFREQ1;
  28133. } *sysctl = (struct sysctl *) 0x400FE000;
  28134. uint32_t clk = 0, piosc = 16000000 /* 16 MHz */, mosc = 25000000 /* 25MHz */;
  28135. if (sysctl->RSCLKCFG & (1 << 28)) { // USEPLL
  28136. uint32_t fin, vco, mdiv, n, q, psysdiv;
  28137. uint32_t pllsrc = (sysctl->RSCLKCFG & (0xf << 24)) >> 24;
  28138. if (pllsrc == 0) {
  28139. clk = piosc;
  28140. } else if (pllsrc == 3) {
  28141. clk = mosc;
  28142. } else {
  28143. MG_ERROR(("Unsupported clock source"));
  28144. }
  28145. q = (sysctl->PLLFREQ1 & (0x1f << 8)) >> 8;
  28146. n = (sysctl->PLLFREQ1 & (0x1f << 0)) >> 0;
  28147. fin = clk / ((q + 1) * (n + 1));
  28148. mdiv = (sysctl->PLLFREQ0 & (0x3ff << 0)) >>
  28149. 0; // mint + (mfrac / 1024); MFRAC not supported
  28150. psysdiv = (sysctl->RSCLKCFG & (0x3f << 0)) >> 0;
  28151. vco = (uint32_t) ((uint64_t) fin * mdiv);
  28152. return vco / (psysdiv + 1);
  28153. }
  28154. uint32_t oscsrc = (sysctl->RSCLKCFG & (0xf << 20)) >> 20;
  28155. if (oscsrc == 0) {
  28156. clk = piosc;
  28157. } else if (oscsrc == 3) {
  28158. clk = mosc;
  28159. } else {
  28160. MG_ERROR(("Unsupported clock source"));
  28161. }
  28162. uint32_t osysdiv = (sysctl->RSCLKCFG & (0xf << 16)) >> 16;
  28163. return clk / (osysdiv + 1);
  28164. }
  28165. // Guess CR from SYSCLK. MDC clock is generated from SYSCLK (AHB); as per
  28166. // 802.3, it must not exceed 2.5MHz (also 20.4.2.6) As the AHB clock can be
  28167. // derived from the PIOSC (internal RC), and it can go above specs, the
  28168. // datasheets specify a range of frequencies and activate one of a series of
  28169. // dividers to keep the MDC clock safely below 2.5MHz. We guess a divider
  28170. // setting based on SYSCLK with a +5% drift. If the user uses a different clock
  28171. // from our defaults, needs to set the macros on top Valid for TM4C129x (20.7)
  28172. // (4.5% worst case drift)
  28173. // The PHY receives the main oscillator (MOSC) (20.3.1)
  28174. static int guess_mdc_cr(void) {
  28175. uint8_t crs[] = {2, 3, 0, 1}; // EMAC->MACMIIAR::CR values
  28176. uint8_t div[] = {16, 26, 42, 62}; // Respective HCLK dividers
  28177. uint32_t sysclk = get_sysclk(); // Guess system SYSCLK
  28178. int i, result = -1; // Invalid CR value
  28179. if (sysclk < 25000000) {
  28180. MG_ERROR(("SYSCLK too low"));
  28181. } else {
  28182. for (i = 0; i < 4; i++) {
  28183. if (sysclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) {
  28184. result = crs[i];
  28185. break;
  28186. }
  28187. }
  28188. if (result < 0) MG_ERROR(("SYSCLK too high"));
  28189. }
  28190. MG_DEBUG(("SYSCLK: %u, CR: %d", sysclk, result));
  28191. return result;
  28192. }
  28193. static bool mg_tcpip_driver_tm4c_init(struct mg_tcpip_if *ifp) {
  28194. struct mg_tcpip_driver_tm4c_data *d =
  28195. (struct mg_tcpip_driver_tm4c_data *) ifp->driver_data;
  28196. int i;
  28197. s_ifp = ifp;
  28198. // Init RX descriptors
  28199. for (i = 0; i < ETH_DESC_CNT; i++) {
  28200. s_rxdesc[i][0] = MG_BIT(31); // Own
  28201. s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | MG_BIT(14); // 2nd address chained
  28202. s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
  28203. s_rxdesc[i][3] =
  28204. (uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain
  28205. // MG_DEBUG(("%d %p", i, s_rxdesc[i]));
  28206. }
  28207. // Init TX descriptors
  28208. for (i = 0; i < ETH_DESC_CNT; i++) {
  28209. s_txdesc[i][2] = (uint32_t) (uintptr_t) s_txbuf[i]; // Buf pointer
  28210. s_txdesc[i][3] =
  28211. (uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain
  28212. }
  28213. EMAC->EMACDMABUSMOD |= MG_BIT(0); // Software reset
  28214. while ((EMAC->EMACDMABUSMOD & MG_BIT(0)) != 0)
  28215. tm4cspin(1); // Wait until done
  28216. // Set MDC clock divider. If user told us the value, use it. Otherwise, guess
  28217. int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
  28218. EMAC->EMACMIIADDR = ((uint32_t) cr & 0xf) << 2;
  28219. // NOTE(cpq): we do not use extended descriptor bit 7, and do not use
  28220. // hardware checksum. Therefore, descriptor size is 4, not 8
  28221. // EMAC->EMACDMABUSMOD = MG_BIT(13) | MG_BIT(16) | MG_BIT(22) | MG_BIT(23) |
  28222. // MG_BIT(25);
  28223. EMAC->EMACIM = MG_BIT(3) | MG_BIT(9); // Mask timestamp & PMT IT
  28224. EMAC->EMACFLOWCTL = MG_BIT(7); // Disable zero-quanta pause
  28225. EMAC->EMACFRAMEFLTR = MG_BIT(10); // Perfect filtering
  28226. // EMAC->EMACPC defaults to internal PHY (EPHY) in MMI mode
  28227. emac_write_phy(EPHY_ADDR, EPHYBMCR, MG_BIT(15)); // Reset internal PHY (EPHY)
  28228. emac_write_phy(EPHY_ADDR, EPHYBMCR, MG_BIT(12)); // Set autonegotiation
  28229. EMAC->EMACRXDLADDR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
  28230. EMAC->EMACTXDLADDR = (uint32_t) (uintptr_t) s_txdesc; // TX descriptors
  28231. EMAC->EMACDMAIM = MG_BIT(6) | MG_BIT(16); // RIE, NIE
  28232. EMAC->EMACCFG =
  28233. MG_BIT(2) | MG_BIT(3) | MG_BIT(11) | MG_BIT(14); // RE, TE, Duplex, Fast
  28234. EMAC->EMACDMAOPMODE =
  28235. MG_BIT(1) | MG_BIT(13) | MG_BIT(21) | MG_BIT(25); // SR, ST, TSF, RSF
  28236. EMAC->EMACADDR0H = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
  28237. EMAC->EMACADDR0L = (uint32_t) (ifp->mac[3] << 24) |
  28238. ((uint32_t) ifp->mac[2] << 16) |
  28239. ((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
  28240. return true;
  28241. }
  28242. static uint32_t s_txno;
  28243. static size_t mg_tcpip_driver_tm4c_tx(const void *buf, size_t len,
  28244. struct mg_tcpip_if *ifp) {
  28245. if (len > sizeof(s_txbuf[s_txno])) {
  28246. MG_ERROR(("Frame too big, %ld", (long) len));
  28247. len = 0; // fail
  28248. } else if ((s_txdesc[s_txno][0] & MG_BIT(31))) {
  28249. ifp->nerr++;
  28250. MG_ERROR(("No descriptors available"));
  28251. // printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long)
  28252. // EMAC->EMACDMARIS);
  28253. len = 0; // fail
  28254. } else {
  28255. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  28256. s_txdesc[s_txno][1] = (uint32_t) len; // Set data len
  28257. s_txdesc[s_txno][0] =
  28258. MG_BIT(20) | MG_BIT(28) | MG_BIT(29) | MG_BIT(30); // Chain,FS,LS,IC
  28259. s_txdesc[s_txno][0] |= MG_BIT(31); // Set OWN bit - let DMA take over
  28260. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  28261. }
  28262. EMAC->EMACDMARIS = MG_BIT(2) | MG_BIT(5); // Clear any prior TU/UNF
  28263. EMAC->EMACTXPOLLD = 0; // and resume
  28264. return len;
  28265. }
  28266. static void mg_tcpip_driver_tm4c_update_hash_table(struct mg_tcpip_if *ifp) {
  28267. // TODO(): read database, rebuild hash table
  28268. // add mDNS / DNS-SD multicast address
  28269. EMAC->EMACADDR1L = (uint32_t) mcast_addr[3] << 24 |
  28270. (uint32_t) mcast_addr[2] << 16 |
  28271. (uint32_t) mcast_addr[1] << 8 | (uint32_t) mcast_addr[0];
  28272. EMAC->EMACADDR1H = (uint32_t) mcast_addr[5] << 8 | (uint32_t) mcast_addr[4];
  28273. EMAC->EMACADDR1H |= MG_BIT(31); // AE
  28274. (void) ifp;
  28275. }
  28276. static bool mg_tcpip_driver_tm4c_poll(struct mg_tcpip_if *ifp, bool s1) {
  28277. if (ifp->update_mac_hash_table) {
  28278. mg_tcpip_driver_tm4c_update_hash_table(ifp);
  28279. ifp->update_mac_hash_table = false;
  28280. }
  28281. if (!s1) return false;
  28282. uint32_t bmsr = emac_read_phy(EPHY_ADDR, EPHYBMSR);
  28283. bool up = (bmsr & MG_BIT(2)) ? 1 : 0;
  28284. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  28285. uint32_t sts = emac_read_phy(EPHY_ADDR, EPHYSTS);
  28286. // tmp = reg with flags set to the most likely situation: 100M full-duplex
  28287. // if(link is slow or half) set flags otherwise
  28288. // reg = tmp
  28289. uint32_t emaccfg =
  28290. EMAC->EMACCFG | MG_BIT(14) | MG_BIT(11); // 100M, Full-duplex
  28291. if (sts & MG_BIT(1)) emaccfg &= ~MG_BIT(14); // 10M
  28292. if ((sts & MG_BIT(2)) == 0) emaccfg &= ~MG_BIT(11); // Half-duplex
  28293. EMAC->EMACCFG = emaccfg; // IRQ handler does not fiddle with this register
  28294. MG_DEBUG(("Link is %uM %s-duplex", emaccfg & MG_BIT(14) ? 100 : 10,
  28295. emaccfg & MG_BIT(11) ? "full" : "half"));
  28296. }
  28297. return up;
  28298. }
  28299. void EMAC0_IRQHandler(void);
  28300. static uint32_t s_rxno;
  28301. void EMAC0_IRQHandler(void) {
  28302. int i;
  28303. if (EMAC->EMACDMARIS & MG_BIT(6)) { // Frame received, loop
  28304. EMAC->EMACDMARIS = MG_BIT(16) | MG_BIT(6); // Clear flag
  28305. for (i = 0; i < 10; i++) { // read as they arrive but not forever
  28306. if (s_rxdesc[s_rxno][0] & MG_BIT(31)) break; // exit when done
  28307. if (((s_rxdesc[s_rxno][0] & (MG_BIT(8) | MG_BIT(9))) ==
  28308. (MG_BIT(8) | MG_BIT(9))) &&
  28309. !(s_rxdesc[s_rxno][0] & MG_BIT(15))) { // skip partial/errored frames
  28310. uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (MG_BIT(14) - 1));
  28311. // printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
  28312. // EMAC->EMACDMARIS);
  28313. mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
  28314. }
  28315. s_rxdesc[s_rxno][0] = MG_BIT(31);
  28316. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  28317. }
  28318. }
  28319. EMAC->EMACDMARIS = MG_BIT(7); // Clear possible RU while processing
  28320. EMAC->EMACRXPOLLD = 0; // and resume RX
  28321. }
  28322. struct mg_tcpip_driver mg_tcpip_driver_tm4c = {mg_tcpip_driver_tm4c_init,
  28323. mg_tcpip_driver_tm4c_tx, NULL,
  28324. mg_tcpip_driver_tm4c_poll};
  28325. #endif
  28326. #ifdef MG_ENABLE_LINES
  28327. #line 1 "src/drivers/tms570.c"
  28328. #endif
  28329. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TMS570) && MG_ENABLE_DRIVER_TMS570
  28330. struct tms570_emac_ctrl {
  28331. volatile uint32_t REVID, SOFTRESET, RESERVED1[1], INTCONTROL, C0RXTHRESHEN,
  28332. C0RXEN, C0TXEN, C0MISCEN, RESERVED2[8],
  28333. C0RXTHRESHSTAT, C0RXSTAT, C0TXSTAT, C0MISCSTAT,
  28334. RESERVED3[8],
  28335. C0RXIMAX, C0TXIMAX;
  28336. };
  28337. struct tms570_emac {
  28338. volatile uint32_t TXREVID, TXCONTROL, TXTEARDOWN, RESERVED1[1], RXREVID,
  28339. RXCONTROL, RXTEARDOWN, RESERVED2[25], TXINTSTATRAW,TXINTSTATMASKED,
  28340. TXINTMASKSET, TXINTMASKCLEAR, MACINVECTOR, MACEOIVECTOR, RESERVED8[2], RXINTSTATRAW,
  28341. RXINTSTATMASKED, RXINTMASKSET, RXINTMASKCLEAR, MACINTSTATRAW, MACINTSTATMASKED,
  28342. MACINTMASKSET, MACINTMASKCLEAR, RESERVED3[16], RXMBPENABLE, RXUNICASTSET,
  28343. RXUNICASTCLEAR, RXMAXLEN, RXBUFFEROFFSET, RXFILTERLOWTHRESH, RESERVED9[2], RXFLOWTHRESH[8],
  28344. RXFREEBUFFER[8], MACCONTROL, MACSTATUS, EMCONTROL, FIFOCONTROL, MACCONFIG,
  28345. SOFTRESET, RESERVED4[22], MACSRCADDRLO, MACSRCADDRHI, MACHASH1, MACHASH2,
  28346. BOFFTEST, TPACETEST, RXPAUSE, TXPAUSE, RESERVED5[4], RXGOODFRAMES, RXBCASTFRAMES,
  28347. RXMCASTFRAMES, RXPAUSEFRAMES, RXCRCERRORS, RXALIGNCODEERRORS, RXOVERSIZED,
  28348. RXJABBER, RXUNDERSIZED, RXFRAGMENTS, RXFILTERED, RXQOSFILTERED, RXOCTETS,
  28349. TXGOODFRAMES, TXBCASTFRAMES, TXMCASTFRAMES, TXPAUSEFRAMES, TXDEFERRED,
  28350. TXCOLLISION, TXSINGLECOLL, TXMULTICOLL, TXEXCESSIVECOLL, TXLATECOLL,
  28351. TXUNDERRUN, TXCARRIERSENSE, TXOCTETS, FRAME64, FRAME65T127, FRAME128T255,
  28352. FRAME256T511, FRAME512T1023, FRAME1024TUP, NETOCTETS, RXSOFOVERRUNS,
  28353. RXMOFOVERRUNS, RXDMAOVERRUNS, RESERVED6[156], MACADDRLO, MACADDRHI,
  28354. MACINDEX, RESERVED7[61], TXHDP[8], RXHDP[8], TXCP[8], RXCP[8];
  28355. };
  28356. struct tms570_mdio {
  28357. volatile uint32_t REVID, CONTROL, ALIVE, LINK, LINKINTRAW, LINKINTMASKED,
  28358. RESERVED1[2], USERINTRAW, USERINTMASKED, USERINTMASKSET, USERINTMASKCLEAR,
  28359. RESERVED2[20], USERACCESS0, USERPHYSEL0, USERACCESS1, USERPHYSEL1;
  28360. };
  28361. #define SWAP32(x) ( (((x) & 0x000000FF) << 24) | \
  28362. (((x) & 0x0000FF00) << 8) | \
  28363. (((x) & 0x00FF0000) >> 8) | \
  28364. (((x) & 0xFF000000) >> 24) )
  28365. #undef EMAC
  28366. #undef EMAC_CTRL
  28367. #undef MDIO
  28368. #define EMAC ((struct tms570_emac *) (uintptr_t) 0xFCF78000)
  28369. #define EMAC_CTRL ((struct tms570_emac_ctrl *) (uintptr_t) 0xFCF78800)
  28370. #define MDIO ((struct tms570_mdio *) (uintptr_t) 0xFCF78900)
  28371. #define ETH_PKT_SIZE 1540 // Max frame size
  28372. #define ETH_DESC_CNT 4 // Descriptors count
  28373. #define ETH_DS 4 // Descriptor size (words)
  28374. static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]
  28375. __attribute__((section(".ETH_CPPI"), aligned(4))); // TX descriptors
  28376. static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]
  28377. __attribute__((section(".ETH_CPPI"), aligned(4))); // RX descriptors
  28378. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]
  28379. __attribute__((aligned(4))); // RX ethernet buffers
  28380. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]
  28381. __attribute__((aligned(4))); // TX ethernet buffers
  28382. static struct mg_tcpip_if *s_ifp; // MIP interface
  28383. static uint16_t emac_read_phy(uint8_t addr, uint8_t reg) {
  28384. while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
  28385. MDIO->USERACCESS0 = MG_BIT(31) | ((reg & 0x1f) << 21) |
  28386. ((addr & 0x1f) << 16);
  28387. while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
  28388. return MDIO->USERACCESS0 & 0xffff;
  28389. }
  28390. static void emac_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
  28391. while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
  28392. MDIO->USERACCESS0 = MG_BIT(31) | MG_BIT(30) | ((reg & 0x1f) << 21) |
  28393. ((addr & 0x1f) << 16) | (val & 0xffff);
  28394. while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
  28395. }
  28396. static bool mg_tcpip_driver_tms570_init(struct mg_tcpip_if *ifp) {
  28397. struct mg_tcpip_driver_tms570_data *d =
  28398. (struct mg_tcpip_driver_tms570_data *) ifp->driver_data;
  28399. s_ifp = ifp;
  28400. EMAC_CTRL->SOFTRESET = MG_BIT(0); // Reset the EMAC Control Module
  28401. while(EMAC_CTRL->SOFTRESET & MG_BIT(0)) (void) 0; // wait
  28402. EMAC->SOFTRESET = MG_BIT(0); // Reset the EMAC Module
  28403. while(EMAC->SOFTRESET & MG_BIT(0)) (void) 0;
  28404. EMAC->MACCONTROL = 0;
  28405. EMAC->RXCONTROL = 0;
  28406. EMAC->TXCONTROL = 0;
  28407. // Initialize all the header descriptor pointer registers
  28408. uint32_t i;
  28409. for(i = 0; i < ETH_DESC_CNT; i++) {
  28410. EMAC->RXHDP[i] = 0;
  28411. EMAC->TXHDP[i] = 0;
  28412. EMAC->RXCP[i] = 0;
  28413. EMAC->TXCP[i] = 0;
  28414. ///EMAC->RXFREEBUFFER[i] = 0xff;
  28415. }
  28416. // Clear the interrupt enable for all the channels
  28417. EMAC->TXINTMASKCLEAR = 0xff;
  28418. EMAC->RXINTMASKCLEAR = 0xff;
  28419. EMAC->MACHASH1 = 0;
  28420. EMAC->MACHASH2 = 0;
  28421. EMAC->RXBUFFEROFFSET = 0;
  28422. EMAC->RXUNICASTCLEAR = 0xff;
  28423. EMAC->RXUNICASTSET = 0;
  28424. EMAC->RXMBPENABLE = 0;
  28425. // init MDIO
  28426. // MDIO_CLK frequency = VCLK3/(CLKDIV + 1). (MDIO must be between 1.0 - 2.5Mhz)
  28427. uint32_t clkdiv = 75; // VCLK is configured to 75Mhz
  28428. // CLKDIV, ENABLE, PREAMBLE, FAULTENB
  28429. MDIO->CONTROL = (clkdiv - 1) | MG_BIT(30) | MG_BIT(20) | MG_BIT(18);
  28430. volatile int delay = 0xfff;
  28431. while (delay-- != 0) (void) 0;
  28432. struct mg_phy phy = {emac_read_phy, emac_write_phy};
  28433. mg_phy_init(&phy, d->phy_addr, MG_PHY_CLOCKS_MAC);
  28434. uint32_t channel;
  28435. for (channel = 0; channel < 8; channel++) {
  28436. EMAC->MACINDEX = channel;
  28437. EMAC->MACADDRHI = ifp->mac[0] | (ifp->mac[1] << 8) | (ifp->mac[2] << 16) |
  28438. (ifp->mac[3] << 24);
  28439. EMAC->MACADDRLO = ifp->mac[4] | (ifp->mac[5] << 8) | MG_BIT(20) |
  28440. MG_BIT(19) | (channel << 16);
  28441. }
  28442. EMAC->RXUNICASTSET = 1; // accept unicast frames;
  28443. EMAC->RXMBPENABLE |= MG_BIT(30) | MG_BIT(13); // CRC, broadcast
  28444. // Initialize the descriptors
  28445. for (i = 0; i < ETH_DESC_CNT; i++) {
  28446. if (i < ETH_DESC_CNT - 1) {
  28447. s_txdesc[i][0] = 0;
  28448. s_rxdesc[i][0] = SWAP32(((uint32_t) &s_rxdesc[i + 1][0]));
  28449. }
  28450. s_txdesc[i][1] = SWAP32(((uint32_t) s_txbuf[i]));
  28451. s_rxdesc[i][1] = SWAP32(((uint32_t) s_rxbuf[i]));
  28452. s_txdesc[i][2] = 0;
  28453. s_rxdesc[i][2] = SWAP32(ETH_PKT_SIZE);
  28454. s_txdesc[i][3] = 0;
  28455. s_rxdesc[i][3] = SWAP32(MG_BIT(29)); // OWN
  28456. }
  28457. s_txdesc[ETH_DESC_CNT - 1][0] = 0;
  28458. s_rxdesc[ETH_DESC_CNT - 1][0] = 0;
  28459. EMAC->MACCONTROL = MG_BIT(5) | MG_BIT(0); // Enable MII, Full-duplex
  28460. //EMAC->TXINTMASKSET = 1; // Enable TX interrupt
  28461. EMAC->RXINTMASKSET = 1; // Enable RX interrupt
  28462. //EMAC_CTRL->C0TXEN = 1; // TX completion interrupt
  28463. EMAC_CTRL->C0RXEN = 1; // RX completion interrupt
  28464. EMAC->TXCONTROL = 1; // TXEN
  28465. EMAC->RXCONTROL = 1; // RXEN
  28466. EMAC->RXHDP[0] = (uint32_t) &s_rxdesc[0][0];
  28467. return true;
  28468. }
  28469. static uint32_t s_txno;
  28470. static size_t mg_tcpip_driver_tms570_tx(const void *buf, size_t len,
  28471. struct mg_tcpip_if *ifp) {
  28472. if (len > sizeof(s_txbuf[s_txno])) {
  28473. MG_ERROR(("Frame too big, %ld", (long) len));
  28474. len = 0; // fail
  28475. } else if ((s_txdesc[s_txno][3] & SWAP32(MG_BIT(29)))) {
  28476. ifp->nerr++;
  28477. MG_ERROR(("No descriptors available"));
  28478. len = 0; // fail
  28479. } else {
  28480. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  28481. if (len < 128) {
  28482. memset(s_txbuf[s_txno] + len, 0, 128 - len);
  28483. len = 128;
  28484. }
  28485. s_txdesc[s_txno][2] = SWAP32((uint32_t) len); // Set data len
  28486. s_txdesc[s_txno][3] =
  28487. SWAP32(MG_BIT(31) | MG_BIT(30) | MG_BIT(29) | len); // SOP, EOP, OWN, length
  28488. while(EMAC->TXHDP[0] != 0) (void) 0;
  28489. EMAC->TXHDP[0] = (uint32_t) &s_txdesc[s_txno][0];
  28490. if(++s_txno == ETH_DESC_CNT) {
  28491. s_txno = 0;
  28492. }
  28493. }
  28494. return len;
  28495. (void) ifp;
  28496. }
  28497. static void mg_tcpip_driver_tms570_update_hash_table(struct mg_tcpip_if *ifp) {
  28498. // TODO(): read database, rebuild hash table
  28499. // Setting Hash Index for 01:00:5e:00:00:fb (multicast)
  28500. // using TMS570 XOR method (32.5.37).
  28501. // computed hash is 55, which means bit 23 (55 - 32) in
  28502. // HASH2 register must be set
  28503. EMAC->MACHASH2 = MG_BIT(23);
  28504. EMAC->RXMBPENABLE = MG_BIT(5); // enable hash filtering
  28505. (void) ifp;
  28506. }
  28507. static bool mg_tcpip_driver_tms570_poll(struct mg_tcpip_if *ifp, bool s1) {
  28508. if (ifp->update_mac_hash_table) {
  28509. mg_tcpip_driver_tms570_update_hash_table(ifp);
  28510. ifp->update_mac_hash_table = false;
  28511. }
  28512. if (!s1) return false;
  28513. struct mg_tcpip_driver_tms570_data *d =
  28514. (struct mg_tcpip_driver_tms570_data *) ifp->driver_data;
  28515. uint8_t speed = MG_PHY_SPEED_10M;
  28516. bool up = false, full_duplex = false;
  28517. struct mg_phy phy = {emac_read_phy, emac_write_phy};
  28518. if (!s1) return false;
  28519. up = mg_phy_up(&phy, d->phy_addr, &full_duplex, &speed);
  28520. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) {
  28521. // link state just went up
  28522. MG_DEBUG(("Link is %uM %s-duplex", speed == MG_PHY_SPEED_10M ? 10 : 100,
  28523. full_duplex ? "full" : "half"));
  28524. }
  28525. return up;
  28526. }
  28527. #pragma CODE_STATE(EMAC_TX_IRQHandler, 32)
  28528. #pragma INTERRUPT(EMAC_TX_IRQHandler, IRQ)
  28529. void EMAC_TX_IRQHandler(void) {
  28530. uint32_t status = EMAC_CTRL->C0TXSTAT;
  28531. if (status & 1) { // interrupt caused on channel 0
  28532. while(s_txdesc[s_txno][3] & SWAP32(MG_BIT(29))) (void) 0;
  28533. EMAC->TXCP[0] = (uint32_t) &s_txdesc[s_txno][0];
  28534. }
  28535. //Write the DMA end of interrupt vector
  28536. EMAC->MACEOIVECTOR = 2;
  28537. }
  28538. static uint32_t s_rxno;
  28539. #pragma CODE_STATE(EMAC_RX_IRQHandler, 32)
  28540. #pragma INTERRUPT(EMAC_RX_IRQHandler, IRQ)
  28541. void EMAC_RX_IRQHandler(void) {
  28542. uint32_t status = EMAC_CTRL->C0RXSTAT;
  28543. if (status & 1) { // Frame received, loop
  28544. uint32_t i;
  28545. //MG_INFO(("RX interrupt"));
  28546. for (i = 0; i < 10; i++) { // read as they arrive but not forever
  28547. if (s_rxdesc[s_rxno][3] & SWAP32(MG_BIT(29))) break;
  28548. uint32_t len = SWAP32(s_rxdesc[s_rxno][3]) & 0xffff;
  28549. //MG_INFO(("recv len: %d", len));
  28550. //mg_hexdump(s_rxbuf[s_rxno], len);
  28551. mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
  28552. uint32_t flags = s_rxdesc[s_rxno][3];
  28553. s_rxdesc[s_rxno][3] = SWAP32(MG_BIT(29));
  28554. s_rxdesc[s_rxno][2] = SWAP32(ETH_PKT_SIZE);
  28555. EMAC->RXCP[0] = (uint32_t) &s_rxdesc[s_rxno][0];
  28556. if (flags & SWAP32(MG_BIT(28))) {
  28557. //MG_INFO(("EOQ detected"));
  28558. EMAC->RXHDP[0] = (uint32_t) &s_rxdesc[0][0];
  28559. }
  28560. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  28561. }
  28562. }
  28563. //Write the DMA end of interrupt vector
  28564. EMAC->MACEOIVECTOR = 1;
  28565. }
  28566. struct mg_tcpip_driver mg_tcpip_driver_tms570 = {mg_tcpip_driver_tms570_init,
  28567. mg_tcpip_driver_tms570_tx, NULL,
  28568. mg_tcpip_driver_tms570_poll};
  28569. #endif
  28570. #ifdef MG_ENABLE_LINES
  28571. #line 1 "src/drivers/w5100.c"
  28572. #endif
  28573. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5100) && MG_ENABLE_DRIVER_W5100
  28574. static void w5100_txn(struct mg_tcpip_spi *s, uint16_t addr, bool wr, void *buf,
  28575. size_t len) {
  28576. uint8_t control = wr ? 0xF0 : 0x0F;
  28577. uint8_t cmd[] = {control, (uint8_t) (addr >> 8), (uint8_t) (addr & 255)};
  28578. s->begin(s->spi);
  28579. s->txn(s->spi, cmd, NULL, sizeof(cmd));
  28580. if (wr) s->txn(s->spi, (uint8_t *) buf, NULL, len);
  28581. if (!wr) s->txn(s->spi, NULL, (uint8_t *) buf, len);
  28582. s->end(s->spi);
  28583. }
  28584. // clang-format off
  28585. static void w5100_wn(struct mg_tcpip_spi *s, uint16_t addr, void *buf, size_t len) { w5100_txn(s, addr, true, buf, len); }
  28586. static void w5100_w1(struct mg_tcpip_spi *s, uint16_t addr, uint8_t val) { w5100_wn(s, addr, &val, 1); }
  28587. static void w5100_w2(struct mg_tcpip_spi *s, uint16_t addr, uint16_t val) { uint8_t buf[2] = {(uint8_t) (val >> 8), (uint8_t) (val & 255)}; w5100_wn(s, addr, buf, sizeof(buf)); }
  28588. static void w5100_rn(struct mg_tcpip_spi *s, uint16_t addr, void *buf, size_t len) { w5100_txn(s, addr, false, buf, len); }
  28589. static uint8_t w5100_r1(struct mg_tcpip_spi *s, uint16_t addr) { uint8_t r = 0; w5100_rn(s, addr, &r, 1); return r; }
  28590. static uint16_t w5100_r2(struct mg_tcpip_spi *s, uint16_t addr) { uint8_t buf[2] = {0, 0}; w5100_rn(s, addr, buf, sizeof(buf)); return (uint16_t) ((buf[0] << 8) | buf[1]); }
  28591. // clang-format on
  28592. static size_t w5100_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
  28593. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
  28594. uint16_t r = 0, n = 0, len = (uint16_t) buflen, n2; // Read recv len
  28595. while ((n2 = w5100_r2(s, 0x426)) > n) n = n2; // Until it is stable
  28596. if (n > 0) {
  28597. uint16_t ptr = w5100_r2(s, 0x428); // Get read pointer
  28598. if (n <= len + 2 && n > 1) {
  28599. r = (uint16_t) (n - 2);
  28600. }
  28601. uint16_t rxbuf_size = (1 << (w5100_r1(s, 0x1a) & 3)) * 1024;
  28602. uint16_t rxbuf_addr = 0x6000;
  28603. uint16_t ptr_ofs = (ptr + 2) & (rxbuf_size - 1);
  28604. if (ptr_ofs + r < rxbuf_size) {
  28605. w5100_rn(s, rxbuf_addr + ptr_ofs, buf, r);
  28606. } else {
  28607. uint16_t remaining_len = rxbuf_size - ptr_ofs;
  28608. w5100_rn(s, rxbuf_addr + ptr_ofs, buf, remaining_len);
  28609. w5100_rn(s, rxbuf_addr, buf + remaining_len, r - remaining_len);
  28610. }
  28611. w5100_w2(s, 0x428, (uint16_t) (ptr + n));
  28612. w5100_w1(s, 0x401, 0x40); // Sock0 CR -> RECV
  28613. }
  28614. return r;
  28615. }
  28616. static size_t w5100_tx(const void *buf, size_t buflen,
  28617. struct mg_tcpip_if *ifp) {
  28618. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
  28619. uint16_t i, n = 0, ptr = 0, len = (uint16_t) buflen;
  28620. while (n < len) n = w5100_r2(s, 0x420); // Wait for space
  28621. ptr = w5100_r2(s, 0x424); // Get write pointer
  28622. uint16_t txbuf_size = (1 << (w5100_r1(s, 0x1b) & 3)) * 1024;
  28623. uint16_t ptr_ofs = ptr & (txbuf_size - 1);
  28624. uint16_t txbuf_addr = 0x4000;
  28625. if (ptr_ofs + len > txbuf_size) {
  28626. uint16_t size = txbuf_size - ptr_ofs;
  28627. w5100_wn(s, txbuf_addr + ptr_ofs, (char *) buf, size);
  28628. w5100_wn(s, txbuf_addr, (char *) buf + size, len - size);
  28629. } else {
  28630. w5100_wn(s, txbuf_addr + ptr_ofs, (char *) buf, len);
  28631. }
  28632. w5100_w2(s, 0x424, (uint16_t) (ptr + len)); // Advance write pointer
  28633. w5100_w1(s, 0x401, 0x20); // Sock0 CR -> SEND
  28634. for (i = 0; i < 40; i++) {
  28635. uint8_t ir = w5100_r1(s, 0x402); // Read S0 IR
  28636. if (ir == 0) continue;
  28637. // printf("IR %d, len=%d, free=%d, ptr %d\n", ir, (int) len, (int) n, ptr);
  28638. w5100_w1(s, 0x402, ir); // Write S0 IR: clear it!
  28639. if (ir & 8) len = 0; // Timeout. Report error
  28640. if (ir & (16 | 8)) break; // Stop on SEND_OK or timeout
  28641. }
  28642. return len;
  28643. }
  28644. static bool w5100_init(struct mg_tcpip_if *ifp) {
  28645. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
  28646. s->end(s->spi);
  28647. w5100_w1(s, 0, 0x80); // Reset chip: CR -> 0x80
  28648. w5100_w1(s, 0x72, 0x53); // CR PHYLCKR -> unlock PHY
  28649. w5100_w1(s, 0x46, 0); // CR PHYCR0 -> autonegotiation
  28650. w5100_w1(s, 0x47, 0); // CR PHYCR1 -> reset
  28651. w5100_w1(s, 0x72, 0x00); // CR PHYLCKR -> lock PHY
  28652. w5100_wn(s, 0x09, ifp->mac, 6); // SHAR
  28653. w5100_w1(s, 0x1a, 6); // Sock0 RX buf size - 4KB
  28654. w5100_w1(s, 0x1b, 6); // Sock0 TX buf size - 4KB
  28655. w5100_w1(s, 0x400, 0x44); // Sock0 MR -> MACRAW, MAC filter
  28656. w5100_w1(s, 0x401, 1); // Sock0 CR -> OPEN
  28657. return w5100_r1(s, 0x403) == 0x42; // Sock0 SR == MACRAW
  28658. }
  28659. static bool w5100_poll(struct mg_tcpip_if *ifp, bool s1) {
  28660. struct mg_tcpip_spi *spi = (struct mg_tcpip_spi *) ifp->driver_data;
  28661. return s1 ? w5100_r1(spi, 0x3c /* PHYSR */) & 1
  28662. : false; // Bit 0 of PHYSR is LNK (0 - down, 1 - up)
  28663. }
  28664. struct mg_tcpip_driver mg_tcpip_driver_w5100 = {w5100_init, w5100_tx, w5100_rx,
  28665. w5100_poll};
  28666. #endif
  28667. #ifdef MG_ENABLE_LINES
  28668. #line 1 "src/drivers/w5500.c"
  28669. #endif
  28670. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5500) && MG_ENABLE_DRIVER_W5500
  28671. enum { W5500_CR = 0, W5500_S0 = 1, W5500_TX0 = 2, W5500_RX0 = 3 };
  28672. static void w5500_txn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr,
  28673. bool wr, void *buf, size_t len) {
  28674. uint8_t cmd[] = {(uint8_t) (addr >> 8), (uint8_t) (addr & 255),
  28675. (uint8_t) ((block << 3) | (wr ? 4 : 0))};
  28676. s->begin(s->spi);
  28677. s->txn(s->spi, cmd, NULL, sizeof(cmd));
  28678. if (wr) s->txn(s->spi, (uint8_t *) buf, NULL, len);
  28679. if (!wr) s->txn(s->spi, NULL, (uint8_t *) buf, len);
  28680. s->end(s->spi);
  28681. }
  28682. // clang-format off
  28683. static void w5500_wn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, true, buf, len); }
  28684. static void w5500_w1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint8_t val) { w5500_wn(s, block, addr, &val, 1); }
  28685. static void w5500_w2(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint16_t val) { uint8_t buf[2] = {(uint8_t) (val >> 8), (uint8_t) (val & 255)}; w5500_wn(s, block, addr, buf, sizeof(buf)); }
  28686. static void w5500_rn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, false, buf, len); }
  28687. static uint8_t w5500_r1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t r = 0; w5500_rn(s, block, addr, &r, 1); return r; }
  28688. static uint16_t w5500_r2(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t buf[2] = {0, 0}; w5500_rn(s, block, addr, buf, sizeof(buf)); return (uint16_t) ((buf[0] << 8) | buf[1]); }
  28689. // clang-format on
  28690. static size_t w5500_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
  28691. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
  28692. uint16_t r = 0, n = 0, len = (uint16_t) buflen, n2; // Read recv len
  28693. while ((n2 = w5500_r2(s, W5500_S0, 0x26)) > n) n = n2; // Until it is stable
  28694. // printf("RSR: %d\n", (int) n);
  28695. if (n > 0) {
  28696. uint16_t ptr = w5500_r2(s, W5500_S0, 0x28); // Get read pointer
  28697. n = w5500_r2(s, W5500_RX0, ptr); // Read frame length
  28698. if (n <= len + 2 && n > 1) {
  28699. r = (uint16_t) (n - 2);
  28700. w5500_rn(s, W5500_RX0, (uint16_t) (ptr + 2), buf, r);
  28701. }
  28702. w5500_w2(s, W5500_S0, 0x28, (uint16_t) (ptr + n)); // Advance read pointer
  28703. w5500_w1(s, W5500_S0, 1, 0x40); // Sock0 CR -> RECV
  28704. // printf(" RX_RD: tot=%u n=%u r=%u\n", n2, n, r);
  28705. }
  28706. return r;
  28707. }
  28708. static size_t w5500_tx(const void *buf, size_t buflen,
  28709. struct mg_tcpip_if *ifp) {
  28710. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
  28711. uint16_t i, ptr, n = 0, len = (uint16_t) buflen;
  28712. while (n < len) n = w5500_r2(s, W5500_S0, 0x20); // Wait for space
  28713. ptr = w5500_r2(s, W5500_S0, 0x24); // Get write pointer
  28714. w5500_wn(s, W5500_TX0, ptr, (void *) buf, len); // Write data
  28715. w5500_w2(s, W5500_S0, 0x24, (uint16_t) (ptr + len)); // Advance write pointer
  28716. w5500_w1(s, W5500_S0, 1, 0x20); // Sock0 CR -> SEND
  28717. for (i = 0; i < 40; i++) {
  28718. uint8_t ir = w5500_r1(s, W5500_S0, 2); // Read S0 IR
  28719. if (ir == 0) continue;
  28720. // printf("IR %d, len=%d, free=%d, ptr %d\n", ir, (int) len, (int) n, ptr);
  28721. w5500_w1(s, W5500_S0, 2, ir); // Write S0 IR: clear it!
  28722. if (ir & 8) len = 0; // Timeout. Report error
  28723. if (ir & (16 | 8)) break; // Stop on SEND_OK or timeout
  28724. }
  28725. return len;
  28726. }
  28727. static bool w5500_init(struct mg_tcpip_if *ifp) {
  28728. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
  28729. s->end(s->spi);
  28730. w5500_w1(s, W5500_CR, 0, 0x80); // Reset chip: CR -> 0x80
  28731. w5500_w1(s, W5500_CR, 0x2e, 0); // CR PHYCFGR -> reset
  28732. w5500_w1(s, W5500_CR, 0x2e, 0xf8); // CR PHYCFGR -> set
  28733. // w5500_wn(s, W5500_CR, 9, s->mac, 6); // Set source MAC
  28734. w5500_w1(s, W5500_S0, 0x1e, 16); // Sock0 RX buf size
  28735. w5500_w1(s, W5500_S0, 0x1f, 16); // Sock0 TX buf size
  28736. w5500_w1(s, W5500_S0, 0, 4); // Sock0 MR -> MACRAW
  28737. w5500_w1(s, W5500_S0, 1, 1); // Sock0 CR -> OPEN
  28738. return w5500_r1(s, W5500_S0, 3) == 0x42; // Sock0 SR == MACRAW
  28739. }
  28740. static bool w5500_poll(struct mg_tcpip_if *ifp, bool s1) {
  28741. struct mg_tcpip_spi *spi = (struct mg_tcpip_spi *) ifp->driver_data;
  28742. return s1 ? w5500_r1(spi, W5500_CR, 0x2e /* PHYCFGR */) & 1
  28743. : false; // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up)
  28744. }
  28745. struct mg_tcpip_driver mg_tcpip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx,
  28746. w5500_poll};
  28747. #endif
  28748. #ifdef MG_ENABLE_LINES
  28749. #line 1 "src/drivers/xmc.c"
  28750. #endif
  28751. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC
  28752. struct ETH_GLOBAL_TypeDef {
  28753. volatile uint32_t MAC_CONFIGURATION, MAC_FRAME_FILTER, HASH_TABLE_HIGH,
  28754. HASH_TABLE_LOW, GMII_ADDRESS, GMII_DATA, FLOW_CONTROL, VLAN_TAG, VERSION,
  28755. DEBUG, REMOTE_WAKE_UP_FRAME_FILTER, PMT_CONTROL_STATUS, RESERVED[2],
  28756. INTERRUPT_STATUS, INTERRUPT_MASK, MAC_ADDRESS0_HIGH, MAC_ADDRESS0_LOW,
  28757. MAC_ADDRESS1_HIGH, MAC_ADDRESS1_LOW, MAC_ADDRESS2_HIGH, MAC_ADDRESS2_LOW,
  28758. MAC_ADDRESS3_HIGH, MAC_ADDRESS3_LOW, RESERVED1[40], MMC_CONTROL,
  28759. MMC_RECEIVE_INTERRUPT, MMC_TRANSMIT_INTERRUPT, MMC_RECEIVE_INTERRUPT_MASK,
  28760. MMC_TRANSMIT_INTERRUPT_MASK, TX_STATISTICS[26], RESERVED2,
  28761. RX_STATISTICS_1[26], RESERVED3[6], MMC_IPC_RECEIVE_INTERRUPT_MASK,
  28762. RESERVED4, MMC_IPC_RECEIVE_INTERRUPT, RESERVED5, RX_STATISTICS_2[30],
  28763. RESERVED7[286], TIMESTAMP_CONTROL, SUB_SECOND_INCREMENT,
  28764. SYSTEM_TIME_SECONDS, SYSTEM_TIME_NANOSECONDS, SYSTEM_TIME_SECONDS_UPDATE,
  28765. SYSTEM_TIME_NANOSECONDS_UPDATE, TIMESTAMP_ADDEND, TARGET_TIME_SECONDS,
  28766. TARGET_TIME_NANOSECONDS, SYSTEM_TIME_HIGHER_WORD_SECONDS,
  28767. TIMESTAMP_STATUS, PPS_CONTROL, RESERVED8[564], BUS_MODE,
  28768. TRANSMIT_POLL_DEMAND, RECEIVE_POLL_DEMAND,
  28769. RECEIVE_DESCRIPTOR_LIST_ADDRESS, TRANSMIT_DESCRIPTOR_LIST_ADDRESS, STATUS,
  28770. OPERATION_MODE, INTERRUPT_ENABLE,
  28771. MISSED_FRAME_AND_BUFFER_OVERFLOW_COUNTER,
  28772. RECEIVE_INTERRUPT_WATCHDOG_TIMER, RESERVED9, AHB_STATUS, RESERVED10[6],
  28773. CURRENT_HOST_TRANSMIT_DESCRIPTOR, CURRENT_HOST_RECEIVE_DESCRIPTOR,
  28774. CURRENT_HOST_TRANSMIT_BUFFER_ADDRESS, CURRENT_HOST_RECEIVE_BUFFER_ADDRESS,
  28775. HW_FEATURE;
  28776. };
  28777. #undef ETH0
  28778. #define ETH0 ((struct ETH_GLOBAL_TypeDef *) 0x5000C000UL)
  28779. #define ETH_PKT_SIZE 1536 // Max frame size
  28780. #define ETH_DESC_CNT 4 // Descriptors count
  28781. #define ETH_DS 4 // Descriptor size (words)
  28782. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM;
  28783. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM;
  28784. static uint32_t s_rxdesc[ETH_DESC_CNT]
  28785. [ETH_DS] MG_ETH_RAM; // RX descriptors
  28786. static uint32_t s_txdesc[ETH_DESC_CNT]
  28787. [ETH_DS] MG_ETH_RAM; // TX descriptors
  28788. static uint8_t s_txno; // Current TX descriptor
  28789. static uint8_t s_rxno; // Current RX descriptor
  28790. static struct mg_tcpip_if *s_ifp; // MIP interface
  28791. enum { MG_PHY_ADDR = 0, MG_PHYREG_BCR = 0, MG_PHYREG_BSR = 1 };
  28792. static uint16_t eth_read_phy(uint8_t addr, uint8_t reg) {
  28793. ETH0->GMII_ADDRESS = (ETH0->GMII_ADDRESS & 0x3c) | ((uint32_t) addr << 11) |
  28794. ((uint32_t) reg << 6) | 1;
  28795. while ((ETH0->GMII_ADDRESS & 1) != 0) (void) 0;
  28796. return (uint16_t) (ETH0->GMII_DATA & 0xffff);
  28797. }
  28798. static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
  28799. ETH0->GMII_DATA = val;
  28800. ETH0->GMII_ADDRESS = (ETH0->GMII_ADDRESS & 0x3c) | ((uint32_t) addr << 11) |
  28801. ((uint32_t) reg << 6) | 3;
  28802. while ((ETH0->GMII_ADDRESS & 1) != 0) (void) 0;
  28803. }
  28804. static uint32_t get_clock_rate(struct mg_tcpip_driver_xmc_data *d) {
  28805. if (d->mdc_cr == -1) {
  28806. // assume ETH clock is 60MHz by default
  28807. // then according to 13.2.8.1, we need to set value 3
  28808. return 3;
  28809. }
  28810. return d->mdc_cr;
  28811. }
  28812. static bool mg_tcpip_driver_xmc_init(struct mg_tcpip_if *ifp) {
  28813. struct mg_tcpip_driver_xmc_data *d =
  28814. (struct mg_tcpip_driver_xmc_data *) ifp->driver_data;
  28815. s_ifp = ifp;
  28816. // reset MAC
  28817. ETH0->BUS_MODE |= 1;
  28818. while (ETH0->BUS_MODE & 1) (void) 0;
  28819. // set clock rate
  28820. ETH0->GMII_ADDRESS = get_clock_rate(d) << 2;
  28821. // init phy
  28822. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  28823. mg_phy_init(&phy, d->phy_addr, MG_PHY_CLOCKS_MAC);
  28824. // configure MAC: DO, DM, FES, TC
  28825. ETH0->MAC_CONFIGURATION = MG_BIT(13) | MG_BIT(11) | MG_BIT(14) | MG_BIT(24);
  28826. // set the MAC address
  28827. ETH0->MAC_ADDRESS0_HIGH = MG_U32(0, 0, ifp->mac[5], ifp->mac[4]);
  28828. ETH0->MAC_ADDRESS0_LOW =
  28829. MG_U32(ifp->mac[3], ifp->mac[2], ifp->mac[1], ifp->mac[0]);
  28830. // Configure the receive filter
  28831. ETH0->MAC_FRAME_FILTER = MG_BIT(10); // Perfect filter
  28832. // Disable flow control
  28833. ETH0->FLOW_CONTROL = 0;
  28834. // Enable store and forward mode
  28835. ETH0->OPERATION_MODE = MG_BIT(25) | MG_BIT(21); // RSF, TSF
  28836. // Configure DMA bus mode (AAL, USP, RPBL, PBL)
  28837. ETH0->BUS_MODE = MG_BIT(25) | MG_BIT(23) | (32 << 17) | (32 << 8);
  28838. // init RX descriptors
  28839. for (int i = 0; i < ETH_DESC_CNT; i++) {
  28840. s_rxdesc[i][0] = MG_BIT(31); // OWN descriptor
  28841. s_rxdesc[i][1] = MG_BIT(14) | ETH_PKT_SIZE;
  28842. s_rxdesc[i][2] = (uint32_t) s_rxbuf[i];
  28843. if (i == ETH_DESC_CNT - 1) {
  28844. s_rxdesc[i][3] = (uint32_t) &s_rxdesc[0][0];
  28845. } else {
  28846. s_rxdesc[i][3] = (uint32_t) &s_rxdesc[i + 1][0];
  28847. }
  28848. }
  28849. ETH0->RECEIVE_DESCRIPTOR_LIST_ADDRESS = (uint32_t) &s_rxdesc[0][0];
  28850. // init TX descriptors
  28851. for (int i = 0; i < ETH_DESC_CNT; i++) {
  28852. s_txdesc[i][0] = MG_BIT(30) | MG_BIT(20);
  28853. s_txdesc[i][2] = (uint32_t) s_txbuf[i];
  28854. if (i == ETH_DESC_CNT - 1) {
  28855. s_txdesc[i][3] = (uint32_t) &s_txdesc[0][0];
  28856. } else {
  28857. s_txdesc[i][3] = (uint32_t) &s_txdesc[i + 1][0];
  28858. }
  28859. }
  28860. ETH0->TRANSMIT_DESCRIPTOR_LIST_ADDRESS = (uint32_t) &s_txdesc[0][0];
  28861. // Clear interrupts
  28862. ETH0->STATUS = 0xFFFFFFFF;
  28863. // Disable MAC interrupts
  28864. ETH0->MMC_TRANSMIT_INTERRUPT_MASK = 0xFFFFFFFF;
  28865. ETH0->MMC_RECEIVE_INTERRUPT_MASK = 0xFFFFFFFF;
  28866. ETH0->MMC_IPC_RECEIVE_INTERRUPT_MASK = 0xFFFFFFFF;
  28867. ETH0->INTERRUPT_MASK = MG_BIT(9) | MG_BIT(3); // TSIM, PMTIM
  28868. // Enable interrupts (NIE, RIE, TIE)
  28869. ETH0->INTERRUPT_ENABLE = MG_BIT(16) | MG_BIT(6) | MG_BIT(0);
  28870. // Enable MAC transmission and reception (TE, RE)
  28871. ETH0->MAC_CONFIGURATION |= MG_BIT(3) | MG_BIT(2);
  28872. // Enable DMA transmission and reception (ST, SR)
  28873. ETH0->OPERATION_MODE |= MG_BIT(13) | MG_BIT(1);
  28874. return true;
  28875. }
  28876. static size_t mg_tcpip_driver_xmc_tx(const void *buf, size_t len,
  28877. struct mg_tcpip_if *ifp) {
  28878. if (len > sizeof(s_txbuf[s_txno])) {
  28879. MG_ERROR(("Frame too big, %ld", (long) len));
  28880. len = 0; // Frame is too big
  28881. } else if ((s_txdesc[s_txno][0] & MG_BIT(31))) {
  28882. ifp->nerr++;
  28883. MG_ERROR(("No free descriptors"));
  28884. len = 0; // All descriptors are busy, fail
  28885. } else {
  28886. memcpy(s_txbuf[s_txno], buf, len);
  28887. s_txdesc[s_txno][1] = len;
  28888. // Table 13-19 Transmit Descriptor Word 0 (IC, LS, FS, TCH)
  28889. s_txdesc[s_txno][0] = MG_BIT(30) | MG_BIT(29) | MG_BIT(28) | MG_BIT(20);
  28890. s_txdesc[s_txno][0] |= MG_BIT(31); // OWN bit: handle control to DMA
  28891. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  28892. }
  28893. // Resume processing
  28894. ETH0->STATUS = MG_BIT(2); // clear Transmit unavailable
  28895. ETH0->TRANSMIT_POLL_DEMAND = 0;
  28896. return len;
  28897. }
  28898. static void mg_tcpip_driver_xmc_update_hash_table(struct mg_tcpip_if *ifp) {
  28899. // TODO(): read database, rebuild hash table
  28900. // set the multicast address filter
  28901. ETH0->MAC_ADDRESS1_HIGH =
  28902. MG_U32(0, 0, mcast_addr[5], mcast_addr[4]) | MG_BIT(31);
  28903. ETH0->MAC_ADDRESS1_LOW =
  28904. MG_U32(mcast_addr[3], mcast_addr[2], mcast_addr[1], mcast_addr[0]);
  28905. (void) ifp;
  28906. }
  28907. static bool mg_tcpip_driver_xmc_poll(struct mg_tcpip_if *ifp, bool s1) {
  28908. if (ifp->update_mac_hash_table) {
  28909. mg_tcpip_driver_xmc_update_hash_table(ifp);
  28910. ifp->update_mac_hash_table = false;
  28911. }
  28912. if (!s1) return false;
  28913. struct mg_tcpip_driver_xmc_data *d =
  28914. (struct mg_tcpip_driver_xmc_data *) ifp->driver_data;
  28915. uint8_t speed = MG_PHY_SPEED_10M;
  28916. bool up = false, full_duplex = false;
  28917. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  28918. up = mg_phy_up(&phy, d->phy_addr, &full_duplex, &speed);
  28919. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  28920. MG_DEBUG(("Link is %uM %s-duplex", speed == MG_PHY_SPEED_10M ? 10 : 100,
  28921. full_duplex ? "full" : "half"));
  28922. }
  28923. return up;
  28924. }
  28925. void ETH0_0_IRQHandler(void);
  28926. void ETH0_0_IRQHandler(void) {
  28927. uint32_t irq_status = ETH0->STATUS;
  28928. // check if a frame was received
  28929. if (irq_status & MG_BIT(6)) {
  28930. for (uint8_t i = 0; i < 10; i++) { // read as they arrive, but not forever
  28931. if (s_rxdesc[s_rxno][0] & MG_BIT(31)) break;
  28932. size_t len = (s_rxdesc[s_rxno][0] & 0x3fff0000) >> 16;
  28933. mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
  28934. s_rxdesc[s_rxno][0] = MG_BIT(31); // OWN bit: handle control to DMA
  28935. // Resume processing
  28936. ETH0->STATUS = MG_BIT(7) | MG_BIT(6); // clear RU and RI
  28937. ETH0->RECEIVE_POLL_DEMAND = 0;
  28938. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  28939. }
  28940. ETH0->STATUS = MG_BIT(6);
  28941. }
  28942. // clear Successful transmission interrupt
  28943. if (irq_status & 1) {
  28944. ETH0->STATUS = 1;
  28945. }
  28946. // clear normal interrupt
  28947. if (irq_status & MG_BIT(16)) {
  28948. ETH0->STATUS = MG_BIT(16);
  28949. }
  28950. }
  28951. struct mg_tcpip_driver mg_tcpip_driver_xmc = {mg_tcpip_driver_xmc_init,
  28952. mg_tcpip_driver_xmc_tx, NULL,
  28953. mg_tcpip_driver_xmc_poll};
  28954. #endif
  28955. #ifdef MG_ENABLE_LINES
  28956. #line 1 "src/drivers/xmc7.c"
  28957. #endif
  28958. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7
  28959. struct ETH_Type {
  28960. volatile uint32_t CTL, STATUS, RESERVED[1022], NETWORK_CONTROL,
  28961. NETWORK_CONFIG, NETWORK_STATUS, USER_IO_REGISTER, DMA_CONFIG,
  28962. TRANSMIT_STATUS, RECEIVE_Q_PTR, TRANSMIT_Q_PTR, RECEIVE_STATUS,
  28963. INT_STATUS, INT_ENABLE, INT_DISABLE, INT_MASK, PHY_MANAGEMENT, PAUSE_TIME,
  28964. TX_PAUSE_QUANTUM, PBUF_TXCUTTHRU, PBUF_RXCUTTHRU, JUMBO_MAX_LENGTH,
  28965. EXTERNAL_FIFO_INTERFACE, RESERVED1, AXI_MAX_PIPELINE, RSC_CONTROL,
  28966. INT_MODERATION, SYS_WAKE_TIME, RESERVED2[7], HASH_BOTTOM, HASH_TOP,
  28967. SPEC_ADD1_BOTTOM, SPEC_ADD1_TOP, SPEC_ADD2_BOTTOM, SPEC_ADD2_TOP,
  28968. SPEC_ADD3_BOTTOM, SPEC_ADD3_TOP, SPEC_ADD4_BOTTOM, SPEC_ADD4_TOP,
  28969. SPEC_TYPE1, SPEC_TYPE2, SPEC_TYPE3, SPEC_TYPE4, WOL_REGISTER,
  28970. STRETCH_RATIO, STACKED_VLAN, TX_PFC_PAUSE, MASK_ADD1_BOTTOM,
  28971. MASK_ADD1_TOP, DMA_ADDR_OR_MASK, RX_PTP_UNICAST, TX_PTP_UNICAST,
  28972. TSU_NSEC_CMP, TSU_SEC_CMP, TSU_MSB_SEC_CMP, TSU_PTP_TX_MSB_SEC,
  28973. TSU_PTP_RX_MSB_SEC, TSU_PEER_TX_MSB_SEC, TSU_PEER_RX_MSB_SEC,
  28974. DPRAM_FILL_DBG, REVISION_REG, OCTETS_TXED_BOTTOM, OCTETS_TXED_TOP,
  28975. FRAMES_TXED_OK, BROADCAST_TXED, MULTICAST_TXED, PAUSE_FRAMES_TXED,
  28976. FRAMES_TXED_64, FRAMES_TXED_65, FRAMES_TXED_128, FRAMES_TXED_256,
  28977. FRAMES_TXED_512, FRAMES_TXED_1024, FRAMES_TXED_1519, TX_UNDERRUNS,
  28978. SINGLE_COLLISIONS, MULTIPLE_COLLISIONS, EXCESSIVE_COLLISIONS,
  28979. LATE_COLLISIONS, DEFERRED_FRAMES, CRS_ERRORS, OCTETS_RXED_BOTTOM,
  28980. OCTETS_RXED_TOP, FRAMES_RXED_OK, BROADCAST_RXED, MULTICAST_RXED,
  28981. PAUSE_FRAMES_RXED, FRAMES_RXED_64, FRAMES_RXED_65, FRAMES_RXED_128,
  28982. FRAMES_RXED_256, FRAMES_RXED_512, FRAMES_RXED_1024, FRAMES_RXED_1519,
  28983. UNDERSIZE_FRAMES, EXCESSIVE_RX_LENGTH, RX_JABBERS, FCS_ERRORS,
  28984. RX_LENGTH_ERRORS, RX_SYMBOL_ERRORS, ALIGNMENT_ERRORS, RX_RESOURCE_ERRORS,
  28985. RX_OVERRUNS, RX_IP_CK_ERRORS, RX_TCP_CK_ERRORS, RX_UDP_CK_ERRORS,
  28986. AUTO_FLUSHED_PKTS, RESERVED3, TSU_TIMER_INCR_SUB_NSEC, TSU_TIMER_MSB_SEC,
  28987. TSU_STROBE_MSB_SEC, TSU_STROBE_SEC, TSU_STROBE_NSEC, TSU_TIMER_SEC,
  28988. TSU_TIMER_NSEC, TSU_TIMER_ADJUST, TSU_TIMER_INCR, TSU_PTP_TX_SEC,
  28989. TSU_PTP_TX_NSEC, TSU_PTP_RX_SEC, TSU_PTP_RX_NSEC, TSU_PEER_TX_SEC,
  28990. TSU_PEER_TX_NSEC, TSU_PEER_RX_SEC, TSU_PEER_RX_NSEC, PCS_CONTROL,
  28991. PCS_STATUS, RESERVED4[2], PCS_AN_ADV, PCS_AN_LP_BASE, PCS_AN_EXP,
  28992. PCS_AN_NP_TX, PCS_AN_LP_NP, RESERVED5[6], PCS_AN_EXT_STATUS, RESERVED6[8],
  28993. TX_PAUSE_QUANTUM1, TX_PAUSE_QUANTUM2, TX_PAUSE_QUANTUM3, RESERVED7,
  28994. RX_LPI, RX_LPI_TIME, TX_LPI, TX_LPI_TIME, DESIGNCFG_DEBUG1,
  28995. DESIGNCFG_DEBUG2, DESIGNCFG_DEBUG3, DESIGNCFG_DEBUG4, DESIGNCFG_DEBUG5,
  28996. DESIGNCFG_DEBUG6, DESIGNCFG_DEBUG7, DESIGNCFG_DEBUG8, DESIGNCFG_DEBUG9,
  28997. DESIGNCFG_DEBUG10, RESERVED8[22], SPEC_ADD5_BOTTOM, SPEC_ADD5_TOP,
  28998. RESERVED9[60], SPEC_ADD36_BOTTOM, SPEC_ADD36_TOP, INT_Q1_STATUS,
  28999. INT_Q2_STATUS, INT_Q3_STATUS, RESERVED10[11], INT_Q15_STATUS, RESERVED11,
  29000. TRANSMIT_Q1_PTR, TRANSMIT_Q2_PTR, TRANSMIT_Q3_PTR, RESERVED12[11],
  29001. TRANSMIT_Q15_PTR, RESERVED13, RECEIVE_Q1_PTR, RECEIVE_Q2_PTR,
  29002. RECEIVE_Q3_PTR, RESERVED14[3], RECEIVE_Q7_PTR, RESERVED15,
  29003. DMA_RXBUF_SIZE_Q1, DMA_RXBUF_SIZE_Q2, DMA_RXBUF_SIZE_Q3, RESERVED16[3],
  29004. DMA_RXBUF_SIZE_Q7, CBS_CONTROL, CBS_IDLESLOPE_Q_A, CBS_IDLESLOPE_Q_B,
  29005. UPPER_TX_Q_BASE_ADDR, TX_BD_CONTROL, RX_BD_CONTROL, UPPER_RX_Q_BASE_ADDR,
  29006. RESERVED17[2], HIDDEN_REG0, HIDDEN_REG1, HIDDEN_REG2, HIDDEN_REG3,
  29007. RESERVED18[2], HIDDEN_REG4, HIDDEN_REG5;
  29008. };
  29009. #define ETH0 ((struct ETH_Type *) 0x40490000)
  29010. #define ETH_PKT_SIZE 1536 // Max frame size
  29011. #define ETH_DESC_CNT 4 // Descriptors count
  29012. #define ETH_DS 2 // Descriptor size (words)
  29013. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM;
  29014. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE] MG_ETH_RAM;
  29015. static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS] MG_ETH_RAM MG_8BYTE_ALIGNED;
  29016. static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS] MG_ETH_RAM MG_8BYTE_ALIGNED;
  29017. static uint8_t s_txno; // Current TX descriptor
  29018. static uint8_t s_rxno; // Current RX descriptor
  29019. static struct mg_tcpip_if *s_ifp; // MIP interface
  29020. enum { MG_PHY_ADDR = 0, MG_PHYREG_BCR = 0, MG_PHYREG_BSR = 1 };
  29021. static uint16_t eth_read_phy(uint8_t addr, uint8_t reg) {
  29022. // WRITE1, READ OPERATION, PHY, REG, WRITE10
  29023. ETH0->PHY_MANAGEMENT = MG_BIT(30) | MG_BIT(29) | ((addr & 0xf) << 24) |
  29024. ((reg & 0x1f) << 18) | MG_BIT(17);
  29025. while ((ETH0->NETWORK_STATUS & MG_BIT(2)) == 0) (void) 0;
  29026. return ETH0->PHY_MANAGEMENT & 0xffff;
  29027. }
  29028. static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
  29029. ETH0->PHY_MANAGEMENT = MG_BIT(30) | MG_BIT(28) | ((addr & 0xf) << 24) |
  29030. ((reg & 0x1f) << 18) | MG_BIT(17) | val;
  29031. while ((ETH0->NETWORK_STATUS & MG_BIT(2)) == 0) (void) 0;
  29032. }
  29033. static uint32_t get_clock_rate(struct mg_tcpip_driver_xmc7_data *d) {
  29034. // see ETH0 -> NETWORK_CONFIG register
  29035. (void) d;
  29036. return 3;
  29037. }
  29038. static bool mg_tcpip_driver_xmc7_init(struct mg_tcpip_if *ifp) {
  29039. struct mg_tcpip_driver_xmc7_data *d =
  29040. (struct mg_tcpip_driver_xmc7_data *) ifp->driver_data;
  29041. s_ifp = ifp;
  29042. // enable controller, set RGMII mode
  29043. ETH0->CTL = MG_BIT(31) | (4 << 8) | 2;
  29044. uint32_t cr = get_clock_rate(d);
  29045. // set NSP change, ignore RX FCS, data bus width, clock rate
  29046. // frame length 1536, full duplex, speed
  29047. ETH0->NETWORK_CONFIG = MG_BIT(29) | MG_BIT(26) | MG_BIT(21) |
  29048. ((cr & 7) << 18) | MG_BIT(8) | MG_BIT(1) | MG_BIT(0);
  29049. // config DMA settings: Force TX burst, Discard on Error, set RX buffer size
  29050. // to 1536, TX_PBUF_SIZE, RX_PBUF_SIZE, AMBA_BURST_LENGTH
  29051. ETH0->DMA_CONFIG =
  29052. MG_BIT(26) | MG_BIT(24) | (0x18 << 16) | MG_BIT(10) | (3 << 8) | 4;
  29053. // initialize descriptors
  29054. for (int i = 0; i < ETH_DESC_CNT; i++) {
  29055. s_rxdesc[i][0] = (uint32_t) s_rxbuf[i];
  29056. if (i == ETH_DESC_CNT - 1) {
  29057. s_rxdesc[i][0] |= MG_BIT(1); // mark last descriptor
  29058. }
  29059. s_txdesc[i][0] = (uint32_t) s_txbuf[i];
  29060. s_txdesc[i][1] = MG_BIT(31); // OWN descriptor
  29061. if (i == ETH_DESC_CNT - 1) {
  29062. s_txdesc[i][1] |= MG_BIT(30); // mark last descriptor
  29063. }
  29064. }
  29065. ETH0->RECEIVE_Q_PTR = (uint32_t) s_rxdesc;
  29066. ETH0->TRANSMIT_Q_PTR = (uint32_t) s_txdesc;
  29067. // disable other queues
  29068. ETH0->TRANSMIT_Q2_PTR = 1;
  29069. ETH0->TRANSMIT_Q1_PTR = 1;
  29070. ETH0->RECEIVE_Q2_PTR = 1;
  29071. ETH0->RECEIVE_Q1_PTR = 1;
  29072. // enable interrupts (RX complete)
  29073. ETH0->INT_ENABLE = MG_BIT(1);
  29074. // set MAC address
  29075. ETH0->SPEC_ADD1_BOTTOM =
  29076. ifp->mac[3] << 24 | ifp->mac[2] << 16 | ifp->mac[1] << 8 | ifp->mac[0];
  29077. ETH0->SPEC_ADD1_TOP = ifp->mac[5] << 8 | ifp->mac[4];
  29078. // enable MDIO, TX, RX
  29079. ETH0->NETWORK_CONTROL = MG_BIT(4) | MG_BIT(3) | MG_BIT(2);
  29080. // start transmission
  29081. ETH0->NETWORK_CONTROL |= MG_BIT(9);
  29082. // init phy
  29083. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  29084. mg_phy_init(&phy, d->phy_addr, MG_PHY_CLOCKS_MAC);
  29085. (void) d;
  29086. return true;
  29087. }
  29088. static size_t mg_tcpip_driver_xmc7_tx(const void *buf, size_t len,
  29089. struct mg_tcpip_if *ifp) {
  29090. if (len > sizeof(s_txbuf[s_txno])) {
  29091. MG_ERROR(("Frame too big, %ld", (long) len));
  29092. len = 0; // Frame is too big
  29093. } else if (((s_txdesc[s_txno][1] & MG_BIT(31)) == 0)) {
  29094. ifp->nerr++;
  29095. MG_ERROR(("No free descriptors"));
  29096. len = 0; // All descriptors are busy, fail
  29097. } else {
  29098. memcpy(s_txbuf[s_txno], buf, len);
  29099. s_txdesc[s_txno][1] = (s_txno == ETH_DESC_CNT - 1 ? MG_BIT(30) : 0) |
  29100. MG_BIT(15) | len; // Last buffer and length
  29101. ETH0->NETWORK_CONTROL |= MG_BIT(9); // enable transmission
  29102. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  29103. }
  29104. MG_DSB();
  29105. ETH0->TRANSMIT_STATUS = ETH0->TRANSMIT_STATUS;
  29106. ETH0->NETWORK_CONTROL |= MG_BIT(9); // enable transmission
  29107. return len;
  29108. }
  29109. static void mg_tcpip_driver_xmc7_update_hash_table(struct mg_tcpip_if *ifp) {
  29110. // TODO(): read database, rebuild hash table
  29111. // set multicast MAC address
  29112. ETH0->SPEC_ADD2_BOTTOM = mcast_addr[3] << 24 | mcast_addr[2] << 16 |
  29113. mcast_addr[1] << 8 | mcast_addr[0];
  29114. ETH0->SPEC_ADD2_TOP = mcast_addr[5] << 8 | mcast_addr[4];
  29115. (void) ifp;
  29116. }
  29117. static bool mg_tcpip_driver_xmc7_poll(struct mg_tcpip_if *ifp, bool s1) {
  29118. if (ifp->update_mac_hash_table) {
  29119. mg_tcpip_driver_xmc7_update_hash_table(ifp);
  29120. ifp->update_mac_hash_table = false;
  29121. }
  29122. if (!s1) return false;
  29123. struct mg_tcpip_driver_xmc7_data *d =
  29124. (struct mg_tcpip_driver_xmc7_data *) ifp->driver_data;
  29125. uint8_t speed = MG_PHY_SPEED_10M;
  29126. bool up = false, full_duplex = false;
  29127. struct mg_phy phy = {eth_read_phy, eth_write_phy};
  29128. up = mg_phy_up(&phy, d->phy_addr, &full_duplex, &speed);
  29129. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  29130. // tmp = reg with flags set to the most likely situation: 100M full-duplex
  29131. // if(link is slow or half) set flags otherwise
  29132. // reg = tmp
  29133. uint32_t netconf = ETH0->NETWORK_CONFIG;
  29134. MG_SET_BITS(netconf, MG_BIT(10),
  29135. MG_BIT(1) | MG_BIT(0)); // 100M, Full-duplex
  29136. uint32_t ctl = ETH0->CTL;
  29137. MG_SET_BITS(ctl, 0xFF00, 4 << 8); // /5 for 25M clock
  29138. if (speed == MG_PHY_SPEED_1000M) {
  29139. netconf |= MG_BIT(10); // 1000M
  29140. MG_SET_BITS(ctl, 0xFF00, 0); // /1 for 125M clock TODO() IS THIS NEEDED ?
  29141. } else if (speed == MG_PHY_SPEED_10M) {
  29142. netconf &= ~MG_BIT(0); // 10M
  29143. MG_SET_BITS(ctl, 0xFF00, 49); // /50 for 2.5M clock
  29144. }
  29145. if (full_duplex == false) netconf &= ~MG_BIT(1); // Half-duplex
  29146. ETH0->NETWORK_CONFIG = netconf; // IRQ handler does not fiddle with these
  29147. ETH0->CTL = ctl;
  29148. MG_DEBUG(("Link is %uM %s-duplex",
  29149. speed == MG_PHY_SPEED_10M
  29150. ? 10
  29151. : (speed == MG_PHY_SPEED_100M ? 100 : 1000),
  29152. full_duplex ? "full" : "half"));
  29153. }
  29154. return up;
  29155. }
  29156. void ETH_IRQHandler(void) {
  29157. uint32_t irq_status = ETH0->INT_STATUS;
  29158. if (irq_status & MG_BIT(1)) {
  29159. for (uint8_t i = 0; i < 10; i++) { // read as they arrive, but not forever
  29160. if ((s_rxdesc[s_rxno][0] & MG_BIT(0)) == 0) break;
  29161. size_t len = s_rxdesc[s_rxno][1] & (MG_BIT(13) - 1);
  29162. mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
  29163. s_rxdesc[s_rxno][0] &= ~MG_BIT(0); // OWN bit: handle control to DMA
  29164. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  29165. }
  29166. }
  29167. ETH0->INT_STATUS = irq_status;
  29168. }
  29169. struct mg_tcpip_driver mg_tcpip_driver_xmc7 = {mg_tcpip_driver_xmc7_init,
  29170. mg_tcpip_driver_xmc7_tx, NULL,
  29171. mg_tcpip_driver_xmc7_poll};
  29172. #endif