dpp.c 203 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516
  1. /*
  2. * DPP functionality shared between hostapd and wpa_supplicant
  3. * Copyright (c) 2017, Qualcomm Atheros, Inc.
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "utils/includes.h"
  9. #include <openssl/opensslv.h>
  10. #include <openssl/err.h>
  11. #include <openssl/asn1.h>
  12. #include <openssl/asn1t.h>
  13. #include "utils/common.h"
  14. #include "utils/base64.h"
  15. #include "utils/json.h"
  16. #include "common/ieee802_11_common.h"
  17. #include "common/ieee802_11_defs.h"
  18. #include "common/wpa_ctrl.h"
  19. #include "crypto/crypto.h"
  20. #include "crypto/random.h"
  21. #include "crypto/aes.h"
  22. #include "crypto/aes_siv.h"
  23. #include "crypto/sha384.h"
  24. #include "crypto/sha512.h"
  25. #include "drivers/driver.h"
  26. #include "dpp.h"
  27. #ifdef CONFIG_TESTING_OPTIONS
  28. enum dpp_test_behavior dpp_test = DPP_TEST_DISABLED;
  29. u8 dpp_pkex_own_mac_override[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
  30. u8 dpp_pkex_peer_mac_override[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
  31. u8 dpp_pkex_ephemeral_key_override[600];
  32. size_t dpp_pkex_ephemeral_key_override_len = 0;
  33. static int dpp_test_gen_invalid_key(struct wpabuf *msg,
  34. const struct dpp_curve_params *curve);
  35. #endif /* CONFIG_TESTING_OPTIONS */
  36. #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(OPENSSL_IS_BORINGSSL)
  37. /* Compatibility wrappers for older versions. */
  38. static int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
  39. {
  40. sig->r = r;
  41. sig->s = s;
  42. return 1;
  43. }
  44. static void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr,
  45. const BIGNUM **ps)
  46. {
  47. if (pr)
  48. *pr = sig->r;
  49. if (ps)
  50. *ps = sig->s;
  51. }
  52. #endif
  53. static const struct dpp_curve_params dpp_curves[] = {
  54. /* The mandatory to support and the default NIST P-256 curve needs to
  55. * be the first entry on this list. */
  56. { "prime256v1", 32, 32, 16, 32, "P-256", 19, "ES256" },
  57. { "secp384r1", 48, 48, 24, 48, "P-384", 20, "ES384" },
  58. { "secp521r1", 64, 64, 32, 66, "P-521", 21, "ES512" },
  59. { "brainpoolP256r1", 32, 32, 16, 32, "BP-256", 28, "BS256" },
  60. { "brainpoolP384r1", 48, 48, 24, 48, "BP-384", 29, "BS384" },
  61. { "brainpoolP512r1", 64, 64, 32, 64, "BP-512", 30, "BS512" },
  62. { NULL, 0, 0, 0, 0, NULL, 0, NULL }
  63. };
  64. /* Role-specific elements for PKEX */
  65. /* NIST P-256 */
  66. static const u8 pkex_init_x_p256[32] = {
  67. 0x56, 0x26, 0x12, 0xcf, 0x36, 0x48, 0xfe, 0x0b,
  68. 0x07, 0x04, 0xbb, 0x12, 0x22, 0x50, 0xb2, 0x54,
  69. 0xb1, 0x94, 0x64, 0x7e, 0x54, 0xce, 0x08, 0x07,
  70. 0x2e, 0xec, 0xca, 0x74, 0x5b, 0x61, 0x2d, 0x25
  71. };
  72. static const u8 pkex_init_y_p256[32] = {
  73. 0x3e, 0x44, 0xc7, 0xc9, 0x8c, 0x1c, 0xa1, 0x0b,
  74. 0x20, 0x09, 0x93, 0xb2, 0xfd, 0xe5, 0x69, 0xdc,
  75. 0x75, 0xbc, 0xad, 0x33, 0xc1, 0xe7, 0xc6, 0x45,
  76. 0x4d, 0x10, 0x1e, 0x6a, 0x3d, 0x84, 0x3c, 0xa4
  77. };
  78. static const u8 pkex_resp_x_p256[32] = {
  79. 0x1e, 0xa4, 0x8a, 0xb1, 0xa4, 0xe8, 0x42, 0x39,
  80. 0xad, 0x73, 0x07, 0xf2, 0x34, 0xdf, 0x57, 0x4f,
  81. 0xc0, 0x9d, 0x54, 0xbe, 0x36, 0x1b, 0x31, 0x0f,
  82. 0x59, 0x91, 0x52, 0x33, 0xac, 0x19, 0x9d, 0x76
  83. };
  84. static const u8 pkex_resp_y_p256[32] = {
  85. 0x26, 0x04, 0x09, 0x45, 0x0a, 0x05, 0x20, 0xe7,
  86. 0xa7, 0x27, 0xc1, 0x36, 0x76, 0x85, 0xca, 0x3e,
  87. 0x42, 0x16, 0xf4, 0x89, 0x85, 0x34, 0x6e, 0xd5,
  88. 0x17, 0xde, 0xc0, 0xb8, 0xad, 0xfd, 0xb2, 0x98
  89. };
  90. /* NIST P-384 */
  91. static const u8 pkex_init_x_p384[48] = {
  92. 0x95, 0x3f, 0x42, 0x9e, 0x50, 0x7f, 0xf9, 0xaa,
  93. 0xac, 0x1a, 0xf2, 0x85, 0x2e, 0x64, 0x91, 0x68,
  94. 0x64, 0xc4, 0x3c, 0xb7, 0x5c, 0xf8, 0xc9, 0x53,
  95. 0x6e, 0x58, 0x4c, 0x7f, 0xc4, 0x64, 0x61, 0xac,
  96. 0x51, 0x8a, 0x6f, 0xfe, 0xab, 0x74, 0xe6, 0x12,
  97. 0x81, 0xac, 0x38, 0x5d, 0x41, 0xe6, 0xb9, 0xa3
  98. };
  99. static const u8 pkex_init_y_p384[48] = {
  100. 0x89, 0xd0, 0x97, 0x7b, 0x59, 0x4f, 0xa6, 0xd6,
  101. 0x7c, 0x5d, 0x93, 0x5b, 0x93, 0xc4, 0x07, 0xa9,
  102. 0x89, 0xee, 0xd5, 0xcd, 0x6f, 0x42, 0xf8, 0x38,
  103. 0xc8, 0xc6, 0x62, 0x24, 0x69, 0x0c, 0xd4, 0x48,
  104. 0xd8, 0x44, 0xd6, 0xc2, 0xe8, 0xcc, 0x62, 0x6b,
  105. 0x3c, 0x25, 0x53, 0xba, 0x4f, 0x71, 0xf8, 0xe7
  106. };
  107. static const u8 pkex_resp_x_p384[48] = {
  108. 0xad, 0xbe, 0xd7, 0x1d, 0x3a, 0x71, 0x64, 0x98,
  109. 0x5f, 0xb4, 0xd6, 0x4b, 0x50, 0xd0, 0x84, 0x97,
  110. 0x4b, 0x7e, 0x57, 0x70, 0xd2, 0xd9, 0xf4, 0x92,
  111. 0x2a, 0x3f, 0xce, 0x99, 0xc5, 0x77, 0x33, 0x44,
  112. 0x14, 0x56, 0x92, 0xcb, 0xae, 0x46, 0x64, 0xdf,
  113. 0xe0, 0xbb, 0xd7, 0xb1, 0x29, 0x20, 0x72, 0xdf
  114. };
  115. static const u8 pkex_resp_y_p384[48] = {
  116. 0x54, 0x58, 0x20, 0xad, 0x55, 0x1d, 0xca, 0xf3,
  117. 0x1c, 0x8a, 0xcd, 0x19, 0x40, 0xf9, 0x37, 0x83,
  118. 0xc7, 0xd6, 0xb3, 0x13, 0x7d, 0x53, 0x28, 0x5c,
  119. 0xf6, 0x2d, 0xf1, 0xdd, 0xa5, 0x8b, 0xad, 0x5d,
  120. 0x81, 0xab, 0xb1, 0x00, 0x39, 0xd6, 0xcc, 0x9c,
  121. 0xea, 0x1e, 0x84, 0x1d, 0xbf, 0xe3, 0x35, 0xf9
  122. };
  123. /* NIST P-521 */
  124. static const u8 pkex_init_x_p521[66] = {
  125. 0x00, 0x16, 0x20, 0x45, 0x19, 0x50, 0x95, 0x23,
  126. 0x0d, 0x24, 0xbe, 0x00, 0x87, 0xdc, 0xfa, 0xf0,
  127. 0x58, 0x9a, 0x01, 0x60, 0x07, 0x7a, 0xca, 0x76,
  128. 0x01, 0xab, 0x2d, 0x5a, 0x46, 0xcd, 0x2c, 0xb5,
  129. 0x11, 0x9a, 0xff, 0xaa, 0x48, 0x04, 0x91, 0x38,
  130. 0xcf, 0x86, 0xfc, 0xa4, 0xa5, 0x0f, 0x47, 0x01,
  131. 0x80, 0x1b, 0x30, 0xa3, 0xae, 0xe8, 0x1c, 0x2e,
  132. 0xea, 0xcc, 0xf0, 0x03, 0x9f, 0x77, 0x4c, 0x8d,
  133. 0x97, 0x76
  134. };
  135. static const u8 pkex_init_y_p521[66] = {
  136. 0x01, 0x4c, 0x71, 0xfd, 0x1b, 0xd5, 0x9c, 0xa6,
  137. 0xed, 0x39, 0xef, 0x45, 0xc5, 0x06, 0xfd, 0x66,
  138. 0xc0, 0xeb, 0x0f, 0xbf, 0x21, 0xa3, 0x36, 0x74,
  139. 0xfd, 0xaa, 0x05, 0x6e, 0x4e, 0x33, 0x95, 0x42,
  140. 0x1a, 0x9d, 0x3f, 0x3a, 0x1c, 0x5e, 0xa8, 0x60,
  141. 0xf7, 0xe5, 0x59, 0x1d, 0x07, 0xaa, 0x6f, 0x40,
  142. 0x0a, 0x59, 0x3c, 0x27, 0xad, 0xe0, 0x48, 0xfd,
  143. 0xd1, 0x83, 0x37, 0x4c, 0xdf, 0xe1, 0x86, 0x72,
  144. 0xfc, 0x57
  145. };
  146. static const u8 pkex_resp_x_p521[66] = {
  147. 0x00, 0x79, 0xe4, 0x4d, 0x6b, 0x5e, 0x12, 0x0a,
  148. 0x18, 0x2c, 0xb3, 0x05, 0x77, 0x0f, 0xc3, 0x44,
  149. 0x1a, 0xcd, 0x78, 0x46, 0x14, 0xee, 0x46, 0x3f,
  150. 0xab, 0xc9, 0x59, 0x7c, 0x85, 0xa0, 0xc2, 0xfb,
  151. 0x02, 0x32, 0x99, 0xde, 0x5d, 0xe1, 0x0d, 0x48,
  152. 0x2d, 0x71, 0x7d, 0x8d, 0x3f, 0x61, 0x67, 0x9e,
  153. 0x2b, 0x8b, 0x12, 0xde, 0x10, 0x21, 0x55, 0x0a,
  154. 0x5b, 0x2d, 0xe8, 0x05, 0x09, 0xf6, 0x20, 0x97,
  155. 0x84, 0xb4
  156. };
  157. static const u8 pkex_resp_y_p521[66] = {
  158. 0x01, 0xb9, 0x9c, 0xc6, 0x41, 0x32, 0x5b, 0xd2,
  159. 0x35, 0xd8, 0x8b, 0x2b, 0xe4, 0x6e, 0xcc, 0xdf,
  160. 0x7c, 0x38, 0xc4, 0x5b, 0xf6, 0x74, 0x71, 0x5c,
  161. 0x77, 0x16, 0x8a, 0x80, 0xa9, 0x84, 0xc7, 0x7b,
  162. 0x9d, 0xfd, 0x83, 0x6f, 0xae, 0xf8, 0x24, 0x16,
  163. 0x2f, 0x21, 0x25, 0x65, 0xa2, 0x1a, 0x6b, 0x2d,
  164. 0x30, 0x62, 0xb3, 0xcc, 0x6e, 0x59, 0x3c, 0x7f,
  165. 0x58, 0x91, 0x81, 0x72, 0x07, 0x8c, 0x91, 0xac,
  166. 0x31, 0x1e
  167. };
  168. /* Brainpool P-256r1 */
  169. static const u8 pkex_init_x_bp_p256r1[32] = {
  170. 0x46, 0x98, 0x18, 0x6c, 0x27, 0xcd, 0x4b, 0x10,
  171. 0x7d, 0x55, 0xa3, 0xdd, 0x89, 0x1f, 0x9f, 0xca,
  172. 0xc7, 0x42, 0x5b, 0x8a, 0x23, 0xed, 0xf8, 0x75,
  173. 0xac, 0xc7, 0xe9, 0x8d, 0xc2, 0x6f, 0xec, 0xd8
  174. };
  175. static const u8 pkex_init_y_bp_p256r1[32] = {
  176. 0x16, 0x30, 0x68, 0x32, 0x3b, 0xb0, 0x21, 0xee,
  177. 0xeb, 0xf7, 0xb6, 0x7c, 0xae, 0x52, 0x26, 0x42,
  178. 0x59, 0x28, 0x58, 0xb6, 0x14, 0x90, 0xed, 0x69,
  179. 0xd0, 0x67, 0xea, 0x25, 0x60, 0x0f, 0xa9, 0x6c
  180. };
  181. static const u8 pkex_resp_x_bp_p256r1[32] = {
  182. 0x90, 0x18, 0x84, 0xc9, 0xdc, 0xcc, 0xb5, 0x2f,
  183. 0x4a, 0x3f, 0x4f, 0x18, 0x0a, 0x22, 0x56, 0x6a,
  184. 0xa9, 0xef, 0xd4, 0xe6, 0xc3, 0x53, 0xc2, 0x1a,
  185. 0x23, 0x54, 0xdd, 0x08, 0x7e, 0x10, 0xd8, 0xe3
  186. };
  187. static const u8 pkex_resp_y_bp_p256r1[32] = {
  188. 0x2a, 0xfa, 0x98, 0x9b, 0xe3, 0xda, 0x30, 0xfd,
  189. 0x32, 0x28, 0xcb, 0x66, 0xfb, 0x40, 0x7f, 0xf2,
  190. 0xb2, 0x25, 0x80, 0x82, 0x44, 0x85, 0x13, 0x7e,
  191. 0x4b, 0xb5, 0x06, 0xc0, 0x03, 0x69, 0x23, 0x64
  192. };
  193. /* Brainpool P-384r1 */
  194. static const u8 pkex_init_x_bp_p384r1[48] = {
  195. 0x0a, 0x2c, 0xeb, 0x49, 0x5e, 0xb7, 0x23, 0xbd,
  196. 0x20, 0x5b, 0xe0, 0x49, 0xdf, 0xcf, 0xcf, 0x19,
  197. 0x37, 0x36, 0xe1, 0x2f, 0x59, 0xdb, 0x07, 0x06,
  198. 0xb5, 0xeb, 0x2d, 0xae, 0xc2, 0xb2, 0x38, 0x62,
  199. 0xa6, 0x73, 0x09, 0xa0, 0x6c, 0x0a, 0xa2, 0x30,
  200. 0x99, 0xeb, 0xf7, 0x1e, 0x47, 0xb9, 0x5e, 0xbe
  201. };
  202. static const u8 pkex_init_y_bp_p384r1[48] = {
  203. 0x54, 0x76, 0x61, 0x65, 0x75, 0x5a, 0x2f, 0x99,
  204. 0x39, 0x73, 0xca, 0x6c, 0xf9, 0xf7, 0x12, 0x86,
  205. 0x54, 0xd5, 0xd4, 0xad, 0x45, 0x7b, 0xbf, 0x32,
  206. 0xee, 0x62, 0x8b, 0x9f, 0x52, 0xe8, 0xa0, 0xc9,
  207. 0xb7, 0x9d, 0xd1, 0x09, 0xb4, 0x79, 0x1c, 0x3e,
  208. 0x1a, 0xbf, 0x21, 0x45, 0x66, 0x6b, 0x02, 0x52
  209. };
  210. static const u8 pkex_resp_x_bp_p384r1[48] = {
  211. 0x03, 0xa2, 0x57, 0xef, 0xe8, 0x51, 0x21, 0xa0,
  212. 0xc8, 0x9e, 0x21, 0x02, 0xb5, 0x9a, 0x36, 0x25,
  213. 0x74, 0x22, 0xd1, 0xf2, 0x1b, 0xa8, 0x9a, 0x9b,
  214. 0x97, 0xbc, 0x5a, 0xeb, 0x26, 0x15, 0x09, 0x71,
  215. 0x77, 0x59, 0xec, 0x8b, 0xb7, 0xe1, 0xe8, 0xce,
  216. 0x65, 0xb8, 0xaf, 0xf8, 0x80, 0xae, 0x74, 0x6c
  217. };
  218. static const u8 pkex_resp_y_bp_p384r1[48] = {
  219. 0x2f, 0xd9, 0x6a, 0xc7, 0x3e, 0xec, 0x76, 0x65,
  220. 0x2d, 0x38, 0x7f, 0xec, 0x63, 0x26, 0x3f, 0x04,
  221. 0xd8, 0x4e, 0xff, 0xe1, 0x0a, 0x51, 0x74, 0x70,
  222. 0xe5, 0x46, 0x63, 0x7f, 0x5c, 0xc0, 0xd1, 0x7c,
  223. 0xfb, 0x2f, 0xea, 0xe2, 0xd8, 0x0f, 0x84, 0xcb,
  224. 0xe9, 0x39, 0x5c, 0x64, 0xfe, 0xcb, 0x2f, 0xf1
  225. };
  226. /* Brainpool P-512r1 */
  227. static const u8 pkex_init_x_bp_p512r1[64] = {
  228. 0x4c, 0xe9, 0xb6, 0x1c, 0xe2, 0x00, 0x3c, 0x9c,
  229. 0xa9, 0xc8, 0x56, 0x52, 0xaf, 0x87, 0x3e, 0x51,
  230. 0x9c, 0xbb, 0x15, 0x31, 0x1e, 0xc1, 0x05, 0xfc,
  231. 0x7c, 0x77, 0xd7, 0x37, 0x61, 0x27, 0xd0, 0x95,
  232. 0x98, 0xee, 0x5d, 0xa4, 0x3d, 0x09, 0xdb, 0x3d,
  233. 0xfa, 0x89, 0x9e, 0x7f, 0xa6, 0xa6, 0x9c, 0xff,
  234. 0x83, 0x5c, 0x21, 0x6c, 0x3e, 0xf2, 0xfe, 0xdc,
  235. 0x63, 0xe4, 0xd1, 0x0e, 0x75, 0x45, 0x69, 0x0f
  236. };
  237. static const u8 pkex_init_y_bp_p512r1[64] = {
  238. 0x5a, 0x28, 0x01, 0xbe, 0x96, 0x82, 0x4e, 0xf6,
  239. 0xfa, 0xed, 0x7d, 0xfd, 0x48, 0x8b, 0x48, 0x4e,
  240. 0xd1, 0x97, 0x87, 0xc4, 0x05, 0x5d, 0x15, 0x2a,
  241. 0xf4, 0x91, 0x4b, 0x75, 0x90, 0xd9, 0x34, 0x2c,
  242. 0x3c, 0x12, 0xf2, 0xf5, 0x25, 0x94, 0x24, 0x34,
  243. 0xa7, 0x6d, 0x66, 0xbc, 0x27, 0xa4, 0xa0, 0x8d,
  244. 0xd5, 0xe1, 0x54, 0xa3, 0x55, 0x26, 0xd4, 0x14,
  245. 0x17, 0x0f, 0xc1, 0xc7, 0x3d, 0x68, 0x7f, 0x5a
  246. };
  247. static const u8 pkex_resp_x_bp_p512r1[64] = {
  248. 0x2a, 0x60, 0x32, 0x27, 0xa1, 0xe6, 0x94, 0x72,
  249. 0x1c, 0x48, 0xbe, 0xc5, 0x77, 0x14, 0x30, 0x76,
  250. 0xe4, 0xbf, 0xf7, 0x7b, 0xc5, 0xfd, 0xdf, 0x19,
  251. 0x1e, 0x0f, 0xdf, 0x1c, 0x40, 0xfa, 0x34, 0x9e,
  252. 0x1f, 0x42, 0x24, 0xa3, 0x2c, 0xd5, 0xc7, 0xc9,
  253. 0x7b, 0x47, 0x78, 0x96, 0xf1, 0x37, 0x0e, 0x88,
  254. 0xcb, 0xa6, 0x52, 0x29, 0xd7, 0xa8, 0x38, 0x29,
  255. 0x8e, 0x6e, 0x23, 0x47, 0xd4, 0x4b, 0x70, 0x3e
  256. };
  257. static const u8 pkex_resp_y_bp_p512r1[64] = {
  258. 0x2a, 0xbe, 0x59, 0xe6, 0xc4, 0xb3, 0xd8, 0x09,
  259. 0x66, 0x89, 0x0a, 0x2d, 0x19, 0xf0, 0x9c, 0x9f,
  260. 0xb4, 0xab, 0x8f, 0x50, 0x68, 0x3c, 0x74, 0x64,
  261. 0x4e, 0x19, 0x55, 0x81, 0x9b, 0x48, 0x5c, 0xf4,
  262. 0x12, 0x8d, 0xb9, 0xd8, 0x02, 0x5b, 0xe1, 0x26,
  263. 0x7e, 0x19, 0x5c, 0xfd, 0x70, 0xf7, 0x4b, 0xdc,
  264. 0xb5, 0x5d, 0xc1, 0x7a, 0xe9, 0xd1, 0x05, 0x2e,
  265. 0xd1, 0xfd, 0x2f, 0xce, 0x63, 0x77, 0x48, 0x2c
  266. };
  267. static void dpp_debug_print_point(const char *title, const EC_GROUP *group,
  268. const EC_POINT *point)
  269. {
  270. BIGNUM *x, *y;
  271. BN_CTX *ctx;
  272. char *x_str = NULL, *y_str = NULL;
  273. if (!wpa_debug_show_keys)
  274. return;
  275. ctx = BN_CTX_new();
  276. x = BN_new();
  277. y = BN_new();
  278. if (!ctx || !x || !y ||
  279. EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx) != 1)
  280. goto fail;
  281. x_str = BN_bn2hex(x);
  282. y_str = BN_bn2hex(y);
  283. if (!x_str || !y_str)
  284. goto fail;
  285. wpa_printf(MSG_DEBUG, "%s (%s,%s)", title, x_str, y_str);
  286. fail:
  287. OPENSSL_free(x_str);
  288. OPENSSL_free(y_str);
  289. BN_free(x);
  290. BN_free(y);
  291. BN_CTX_free(ctx);
  292. }
  293. static int dpp_hash_vector(const struct dpp_curve_params *curve,
  294. size_t num_elem, const u8 *addr[], const size_t *len,
  295. u8 *mac)
  296. {
  297. if (curve->hash_len == 32)
  298. return sha256_vector(num_elem, addr, len, mac);
  299. if (curve->hash_len == 48)
  300. return sha384_vector(num_elem, addr, len, mac);
  301. if (curve->hash_len == 64)
  302. return sha512_vector(num_elem, addr, len, mac);
  303. return -1;
  304. }
  305. static int dpp_hkdf_expand(size_t hash_len, const u8 *secret, size_t secret_len,
  306. const char *label, u8 *out, size_t outlen)
  307. {
  308. if (hash_len == 32)
  309. return hmac_sha256_kdf(secret, secret_len, NULL,
  310. (const u8 *) label, os_strlen(label),
  311. out, outlen);
  312. if (hash_len == 48)
  313. return hmac_sha384_kdf(secret, secret_len, NULL,
  314. (const u8 *) label, os_strlen(label),
  315. out, outlen);
  316. if (hash_len == 64)
  317. return hmac_sha512_kdf(secret, secret_len, NULL,
  318. (const u8 *) label, os_strlen(label),
  319. out, outlen);
  320. return -1;
  321. }
  322. static int dpp_hmac_vector(size_t hash_len, const u8 *key, size_t key_len,
  323. size_t num_elem, const u8 *addr[],
  324. const size_t *len, u8 *mac)
  325. {
  326. if (hash_len == 32)
  327. return hmac_sha256_vector(key, key_len, num_elem, addr, len,
  328. mac);
  329. if (hash_len == 48)
  330. return hmac_sha384_vector(key, key_len, num_elem, addr, len,
  331. mac);
  332. if (hash_len == 64)
  333. return hmac_sha512_vector(key, key_len, num_elem, addr, len,
  334. mac);
  335. return -1;
  336. }
  337. static int dpp_hmac(size_t hash_len, const u8 *key, size_t key_len,
  338. const u8 *data, size_t data_len, u8 *mac)
  339. {
  340. if (hash_len == 32)
  341. return hmac_sha256(key, key_len, data, data_len, mac);
  342. if (hash_len == 48)
  343. return hmac_sha384(key, key_len, data, data_len, mac);
  344. if (hash_len == 64)
  345. return hmac_sha512(key, key_len, data, data_len, mac);
  346. return -1;
  347. }
  348. static int dpp_bn2bin_pad(const BIGNUM *bn, u8 *pos, size_t len)
  349. {
  350. int num_bytes, offset;
  351. num_bytes = BN_num_bytes(bn);
  352. if ((size_t) num_bytes > len)
  353. return -1;
  354. offset = len - num_bytes;
  355. os_memset(pos, 0, offset);
  356. BN_bn2bin(bn, pos + offset);
  357. return 0;
  358. }
  359. static struct wpabuf * dpp_get_pubkey_point(EVP_PKEY *pkey, int prefix)
  360. {
  361. int len, res;
  362. EC_KEY *eckey;
  363. struct wpabuf *buf;
  364. unsigned char *pos;
  365. eckey = EVP_PKEY_get1_EC_KEY(pkey);
  366. if (!eckey)
  367. return NULL;
  368. EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED);
  369. len = i2o_ECPublicKey(eckey, NULL);
  370. if (len <= 0) {
  371. wpa_printf(MSG_ERROR,
  372. "DDP: Failed to determine public key encoding length");
  373. EC_KEY_free(eckey);
  374. return NULL;
  375. }
  376. buf = wpabuf_alloc(len);
  377. if (!buf) {
  378. EC_KEY_free(eckey);
  379. return NULL;
  380. }
  381. pos = wpabuf_put(buf, len);
  382. res = i2o_ECPublicKey(eckey, &pos);
  383. EC_KEY_free(eckey);
  384. if (res != len) {
  385. wpa_printf(MSG_ERROR,
  386. "DDP: Failed to encode public key (res=%d/%d)",
  387. res, len);
  388. wpabuf_free(buf);
  389. return NULL;
  390. }
  391. if (!prefix) {
  392. /* Remove 0x04 prefix to match DPP definition */
  393. pos = wpabuf_mhead(buf);
  394. os_memmove(pos, pos + 1, len - 1);
  395. buf->used--;
  396. }
  397. return buf;
  398. }
  399. static EVP_PKEY * dpp_set_pubkey_point_group(const EC_GROUP *group,
  400. const u8 *buf_x, const u8 *buf_y,
  401. size_t len)
  402. {
  403. EC_KEY *eckey = NULL;
  404. BN_CTX *ctx;
  405. EC_POINT *point = NULL;
  406. BIGNUM *x = NULL, *y = NULL;
  407. EVP_PKEY *pkey = NULL;
  408. ctx = BN_CTX_new();
  409. if (!ctx) {
  410. wpa_printf(MSG_ERROR, "DPP: Out of memory");
  411. return NULL;
  412. }
  413. point = EC_POINT_new(group);
  414. x = BN_bin2bn(buf_x, len, NULL);
  415. y = BN_bin2bn(buf_y, len, NULL);
  416. if (!point || !x || !y) {
  417. wpa_printf(MSG_ERROR, "DPP: Out of memory");
  418. goto fail;
  419. }
  420. if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
  421. wpa_printf(MSG_ERROR,
  422. "DPP: OpenSSL: EC_POINT_set_affine_coordinates_GFp failed: %s",
  423. ERR_error_string(ERR_get_error(), NULL));
  424. goto fail;
  425. }
  426. if (!EC_POINT_is_on_curve(group, point, ctx) ||
  427. EC_POINT_is_at_infinity(group, point)) {
  428. wpa_printf(MSG_ERROR, "DPP: Invalid point");
  429. goto fail;
  430. }
  431. dpp_debug_print_point("DPP: dpp_set_pubkey_point_group", group, point);
  432. eckey = EC_KEY_new();
  433. if (!eckey ||
  434. EC_KEY_set_group(eckey, group) != 1 ||
  435. EC_KEY_set_public_key(eckey, point) != 1) {
  436. wpa_printf(MSG_ERROR,
  437. "DPP: Failed to set EC_KEY: %s",
  438. ERR_error_string(ERR_get_error(), NULL));
  439. goto fail;
  440. }
  441. EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
  442. pkey = EVP_PKEY_new();
  443. if (!pkey || EVP_PKEY_set1_EC_KEY(pkey, eckey) != 1) {
  444. wpa_printf(MSG_ERROR, "DPP: Could not create EVP_PKEY");
  445. goto fail;
  446. }
  447. out:
  448. BN_free(x);
  449. BN_free(y);
  450. EC_KEY_free(eckey);
  451. EC_POINT_free(point);
  452. BN_CTX_free(ctx);
  453. return pkey;
  454. fail:
  455. EVP_PKEY_free(pkey);
  456. pkey = NULL;
  457. goto out;
  458. }
  459. static EVP_PKEY * dpp_set_pubkey_point(EVP_PKEY *group_key,
  460. const u8 *buf, size_t len)
  461. {
  462. EC_KEY *eckey;
  463. const EC_GROUP *group;
  464. EVP_PKEY *pkey = NULL;
  465. if (len & 1)
  466. return NULL;
  467. eckey = EVP_PKEY_get1_EC_KEY(group_key);
  468. if (!eckey) {
  469. wpa_printf(MSG_ERROR,
  470. "DPP: Could not get EC_KEY from group_key");
  471. return NULL;
  472. }
  473. group = EC_KEY_get0_group(eckey);
  474. if (group)
  475. pkey = dpp_set_pubkey_point_group(group, buf, buf + len / 2,
  476. len / 2);
  477. else
  478. wpa_printf(MSG_ERROR, "DPP: Could not get EC group");
  479. EC_KEY_free(eckey);
  480. return pkey;
  481. }
  482. static void dpp_auth_fail(struct dpp_authentication *auth, const char *txt)
  483. {
  484. wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_FAIL "%s", txt);
  485. }
  486. struct wpabuf * dpp_alloc_msg(enum dpp_public_action_frame_type type,
  487. size_t len)
  488. {
  489. struct wpabuf *msg;
  490. msg = wpabuf_alloc(8 + len);
  491. if (!msg)
  492. return NULL;
  493. wpabuf_put_u8(msg, WLAN_ACTION_PUBLIC);
  494. wpabuf_put_u8(msg, WLAN_PA_VENDOR_SPECIFIC);
  495. wpabuf_put_be24(msg, OUI_WFA);
  496. wpabuf_put_u8(msg, DPP_OUI_TYPE);
  497. wpabuf_put_u8(msg, 1); /* Crypto Suite */
  498. wpabuf_put_u8(msg, type);
  499. return msg;
  500. }
  501. const u8 * dpp_get_attr(const u8 *buf, size_t len, u16 req_id, u16 *ret_len)
  502. {
  503. u16 id, alen;
  504. const u8 *pos = buf, *end = buf + len;
  505. while (end - pos >= 4) {
  506. id = WPA_GET_LE16(pos);
  507. pos += 2;
  508. alen = WPA_GET_LE16(pos);
  509. pos += 2;
  510. if (alen > end - pos)
  511. return NULL;
  512. if (id == req_id) {
  513. *ret_len = alen;
  514. return pos;
  515. }
  516. pos += alen;
  517. }
  518. return NULL;
  519. }
  520. int dpp_check_attrs(const u8 *buf, size_t len)
  521. {
  522. const u8 *pos, *end;
  523. int wrapped_data = 0;
  524. pos = buf;
  525. end = buf + len;
  526. while (end - pos >= 4) {
  527. u16 id, alen;
  528. id = WPA_GET_LE16(pos);
  529. pos += 2;
  530. alen = WPA_GET_LE16(pos);
  531. pos += 2;
  532. wpa_printf(MSG_MSGDUMP, "DPP: Attribute ID %04x len %u",
  533. id, alen);
  534. if (alen > end - pos) {
  535. wpa_printf(MSG_DEBUG,
  536. "DPP: Truncated message - not enough room for the attribute - dropped");
  537. return -1;
  538. }
  539. if (wrapped_data) {
  540. wpa_printf(MSG_DEBUG,
  541. "DPP: An unexpected attribute included after the Wrapped Data attribute");
  542. return -1;
  543. }
  544. if (id == DPP_ATTR_WRAPPED_DATA)
  545. wrapped_data = 1;
  546. pos += alen;
  547. }
  548. if (end != pos) {
  549. wpa_printf(MSG_DEBUG,
  550. "DPP: Unexpected octets (%d) after the last attribute",
  551. (int) (end - pos));
  552. return -1;
  553. }
  554. return 0;
  555. }
  556. void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info)
  557. {
  558. if (!info)
  559. return;
  560. os_free(info->uri);
  561. os_free(info->info);
  562. EVP_PKEY_free(info->pubkey);
  563. os_free(info);
  564. }
  565. const char * dpp_bootstrap_type_txt(enum dpp_bootstrap_type type)
  566. {
  567. switch (type) {
  568. case DPP_BOOTSTRAP_QR_CODE:
  569. return "QRCODE";
  570. case DPP_BOOTSTRAP_PKEX:
  571. return "PKEX";
  572. }
  573. return "??";
  574. }
  575. static int dpp_uri_valid_info(const char *info)
  576. {
  577. while (*info) {
  578. unsigned char val = *info++;
  579. if (val < 0x20 || val > 0x7e || val == 0x3b)
  580. return 0;
  581. }
  582. return 1;
  583. }
  584. static int dpp_clone_uri(struct dpp_bootstrap_info *bi, const char *uri)
  585. {
  586. bi->uri = os_strdup(uri);
  587. return bi->uri ? 0 : -1;
  588. }
  589. int dpp_parse_uri_chan_list(struct dpp_bootstrap_info *bi,
  590. const char *chan_list)
  591. {
  592. const char *pos = chan_list;
  593. int opclass, channel, freq;
  594. while (pos && *pos && *pos != ';') {
  595. opclass = atoi(pos);
  596. if (opclass <= 0)
  597. goto fail;
  598. pos = os_strchr(pos, '/');
  599. if (!pos)
  600. goto fail;
  601. pos++;
  602. channel = atoi(pos);
  603. if (channel <= 0)
  604. goto fail;
  605. while (*pos >= '0' && *pos <= '9')
  606. pos++;
  607. freq = ieee80211_chan_to_freq(NULL, opclass, channel);
  608. wpa_printf(MSG_DEBUG,
  609. "DPP: URI channel-list: opclass=%d channel=%d ==> freq=%d",
  610. opclass, channel, freq);
  611. if (freq < 0) {
  612. wpa_printf(MSG_DEBUG,
  613. "DPP: Ignore unknown URI channel-list channel (opclass=%d channel=%d)",
  614. opclass, channel);
  615. } else if (bi->num_freq == DPP_BOOTSTRAP_MAX_FREQ) {
  616. wpa_printf(MSG_DEBUG,
  617. "DPP: Too many channels in URI channel-list - ignore list");
  618. bi->num_freq = 0;
  619. break;
  620. } else {
  621. bi->freq[bi->num_freq++] = freq;
  622. }
  623. if (*pos == ';' || *pos == '\0')
  624. break;
  625. if (*pos != ',')
  626. goto fail;
  627. pos++;
  628. }
  629. return 0;
  630. fail:
  631. wpa_printf(MSG_DEBUG, "DPP: Invalid URI channel-list");
  632. return -1;
  633. }
  634. int dpp_parse_uri_mac(struct dpp_bootstrap_info *bi, const char *mac)
  635. {
  636. if (!mac)
  637. return 0;
  638. if (hwaddr_aton2(mac, bi->mac_addr) < 0) {
  639. wpa_printf(MSG_DEBUG, "DPP: Invalid URI mac");
  640. return -1;
  641. }
  642. wpa_printf(MSG_DEBUG, "DPP: URI mac: " MACSTR, MAC2STR(bi->mac_addr));
  643. return 0;
  644. }
  645. int dpp_parse_uri_info(struct dpp_bootstrap_info *bi, const char *info)
  646. {
  647. const char *end;
  648. if (!info)
  649. return 0;
  650. end = os_strchr(info, ';');
  651. if (!end)
  652. end = info + os_strlen(info);
  653. bi->info = os_malloc(end - info + 1);
  654. if (!bi->info)
  655. return -1;
  656. os_memcpy(bi->info, info, end - info);
  657. bi->info[end - info] = '\0';
  658. wpa_printf(MSG_DEBUG, "DPP: URI(information): %s", bi->info);
  659. if (!dpp_uri_valid_info(bi->info)) {
  660. wpa_printf(MSG_DEBUG, "DPP: Invalid URI information payload");
  661. return -1;
  662. }
  663. return 0;
  664. }
  665. static const struct dpp_curve_params *
  666. dpp_get_curve_oid(const ASN1_OBJECT *poid)
  667. {
  668. ASN1_OBJECT *oid;
  669. int i;
  670. for (i = 0; dpp_curves[i].name; i++) {
  671. oid = OBJ_txt2obj(dpp_curves[i].name, 0);
  672. if (oid && OBJ_cmp(poid, oid) == 0)
  673. return &dpp_curves[i];
  674. }
  675. return NULL;
  676. }
  677. static const struct dpp_curve_params * dpp_get_curve_nid(int nid)
  678. {
  679. int i, tmp;
  680. if (!nid)
  681. return NULL;
  682. for (i = 0; dpp_curves[i].name; i++) {
  683. tmp = OBJ_txt2nid(dpp_curves[i].name);
  684. if (tmp == nid)
  685. return &dpp_curves[i];
  686. }
  687. return NULL;
  688. }
  689. static int dpp_parse_uri_pk(struct dpp_bootstrap_info *bi, const char *info)
  690. {
  691. const char *end;
  692. u8 *data;
  693. size_t data_len;
  694. EVP_PKEY *pkey;
  695. const unsigned char *p;
  696. int res;
  697. X509_PUBKEY *pub = NULL;
  698. ASN1_OBJECT *ppkalg;
  699. const unsigned char *pk;
  700. int ppklen;
  701. X509_ALGOR *pa;
  702. #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(OPENSSL_IS_BORINGSSL)
  703. ASN1_OBJECT *pa_oid;
  704. #else
  705. const ASN1_OBJECT *pa_oid;
  706. #endif
  707. const void *pval;
  708. int ptype;
  709. const ASN1_OBJECT *poid;
  710. char buf[100];
  711. end = os_strchr(info, ';');
  712. if (!end)
  713. return -1;
  714. data = base64_decode((const unsigned char *) info, end - info,
  715. &data_len);
  716. if (!data) {
  717. wpa_printf(MSG_DEBUG,
  718. "DPP: Invalid base64 encoding on URI public-key");
  719. return -1;
  720. }
  721. wpa_hexdump(MSG_DEBUG, "DPP: Base64 decoded URI public-key",
  722. data, data_len);
  723. if (sha256_vector(1, (const u8 **) &data, &data_len,
  724. bi->pubkey_hash) < 0) {
  725. wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key");
  726. return -1;
  727. }
  728. wpa_hexdump(MSG_DEBUG, "DPP: Public key hash",
  729. bi->pubkey_hash, SHA256_MAC_LEN);
  730. /* DER encoded ASN.1 SubjectPublicKeyInfo
  731. *
  732. * SubjectPublicKeyInfo ::= SEQUENCE {
  733. * algorithm AlgorithmIdentifier,
  734. * subjectPublicKey BIT STRING }
  735. *
  736. * AlgorithmIdentifier ::= SEQUENCE {
  737. * algorithm OBJECT IDENTIFIER,
  738. * parameters ANY DEFINED BY algorithm OPTIONAL }
  739. *
  740. * subjectPublicKey = compressed format public key per ANSI X9.63
  741. * algorithm = ecPublicKey (1.2.840.10045.2.1)
  742. * parameters = shall be present and shall be OBJECT IDENTIFIER; e.g.,
  743. * prime256v1 (1.2.840.10045.3.1.7)
  744. */
  745. p = data;
  746. pkey = d2i_PUBKEY(NULL, &p, data_len);
  747. os_free(data);
  748. if (!pkey) {
  749. wpa_printf(MSG_DEBUG,
  750. "DPP: Could not parse URI public-key SubjectPublicKeyInfo");
  751. return -1;
  752. }
  753. if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_EC) {
  754. wpa_printf(MSG_DEBUG,
  755. "DPP: SubjectPublicKeyInfo does not describe an EC key");
  756. EVP_PKEY_free(pkey);
  757. return -1;
  758. }
  759. res = X509_PUBKEY_set(&pub, pkey);
  760. if (res != 1) {
  761. wpa_printf(MSG_DEBUG, "DPP: Could not set pubkey");
  762. goto fail;
  763. }
  764. res = X509_PUBKEY_get0_param(&ppkalg, &pk, &ppklen, &pa, pub);
  765. if (res != 1) {
  766. wpa_printf(MSG_DEBUG,
  767. "DPP: Could not extract SubjectPublicKeyInfo parameters");
  768. goto fail;
  769. }
  770. res = OBJ_obj2txt(buf, sizeof(buf), ppkalg, 0);
  771. if (res < 0 || (size_t) res >= sizeof(buf)) {
  772. wpa_printf(MSG_DEBUG,
  773. "DPP: Could not extract SubjectPublicKeyInfo algorithm");
  774. goto fail;
  775. }
  776. wpa_printf(MSG_DEBUG, "DPP: URI subjectPublicKey algorithm: %s", buf);
  777. if (os_strcmp(buf, "id-ecPublicKey") != 0) {
  778. wpa_printf(MSG_DEBUG,
  779. "DPP: Unsupported SubjectPublicKeyInfo algorithm");
  780. goto fail;
  781. }
  782. X509_ALGOR_get0(&pa_oid, &ptype, (void *) &pval, pa);
  783. if (ptype != V_ASN1_OBJECT) {
  784. wpa_printf(MSG_DEBUG,
  785. "DPP: SubjectPublicKeyInfo parameters did not contain an OID");
  786. goto fail;
  787. }
  788. poid = pval;
  789. res = OBJ_obj2txt(buf, sizeof(buf), poid, 0);
  790. if (res < 0 || (size_t) res >= sizeof(buf)) {
  791. wpa_printf(MSG_DEBUG,
  792. "DPP: Could not extract SubjectPublicKeyInfo parameters OID");
  793. goto fail;
  794. }
  795. wpa_printf(MSG_DEBUG, "DPP: URI subjectPublicKey parameters: %s", buf);
  796. bi->curve = dpp_get_curve_oid(poid);
  797. if (!bi->curve) {
  798. wpa_printf(MSG_DEBUG,
  799. "DPP: Unsupported SubjectPublicKeyInfo curve: %s",
  800. buf);
  801. goto fail;
  802. }
  803. wpa_hexdump(MSG_DEBUG, "DPP: URI subjectPublicKey", pk, ppklen);
  804. X509_PUBKEY_free(pub);
  805. bi->pubkey = pkey;
  806. return 0;
  807. fail:
  808. X509_PUBKEY_free(pub);
  809. EVP_PKEY_free(pkey);
  810. return -1;
  811. }
  812. static struct dpp_bootstrap_info * dpp_parse_uri(const char *uri)
  813. {
  814. const char *pos = uri;
  815. const char *end;
  816. const char *chan_list = NULL, *mac = NULL, *info = NULL, *pk = NULL;
  817. struct dpp_bootstrap_info *bi;
  818. wpa_hexdump_ascii(MSG_DEBUG, "DPP: URI", uri, os_strlen(uri));
  819. if (os_strncmp(pos, "DPP:", 4) != 0) {
  820. wpa_printf(MSG_INFO, "DPP: Not a DPP URI");
  821. return NULL;
  822. }
  823. pos += 4;
  824. for (;;) {
  825. end = os_strchr(pos, ';');
  826. if (!end)
  827. break;
  828. if (end == pos) {
  829. /* Handle terminating ";;" and ignore unexpected ";"
  830. * for parsing robustness. */
  831. pos++;
  832. continue;
  833. }
  834. if (pos[0] == 'C' && pos[1] == ':' && !chan_list)
  835. chan_list = pos + 2;
  836. else if (pos[0] == 'M' && pos[1] == ':' && !mac)
  837. mac = pos + 2;
  838. else if (pos[0] == 'I' && pos[1] == ':' && !info)
  839. info = pos + 2;
  840. else if (pos[0] == 'K' && pos[1] == ':' && !pk)
  841. pk = pos + 2;
  842. else
  843. wpa_hexdump_ascii(MSG_DEBUG,
  844. "DPP: Ignore unrecognized URI parameter",
  845. pos, end - pos);
  846. pos = end + 1;
  847. }
  848. if (!pk) {
  849. wpa_printf(MSG_INFO, "DPP: URI missing public-key");
  850. return NULL;
  851. }
  852. bi = os_zalloc(sizeof(*bi));
  853. if (!bi)
  854. return NULL;
  855. if (dpp_clone_uri(bi, uri) < 0 ||
  856. dpp_parse_uri_chan_list(bi, chan_list) < 0 ||
  857. dpp_parse_uri_mac(bi, mac) < 0 ||
  858. dpp_parse_uri_info(bi, info) < 0 ||
  859. dpp_parse_uri_pk(bi, pk) < 0) {
  860. dpp_bootstrap_info_free(bi);
  861. bi = NULL;
  862. }
  863. return bi;
  864. }
  865. struct dpp_bootstrap_info * dpp_parse_qr_code(const char *uri)
  866. {
  867. struct dpp_bootstrap_info *bi;
  868. bi = dpp_parse_uri(uri);
  869. if (bi)
  870. bi->type = DPP_BOOTSTRAP_QR_CODE;
  871. return bi;
  872. }
  873. static void dpp_debug_print_key(const char *title, EVP_PKEY *key)
  874. {
  875. EC_KEY *eckey;
  876. BIO *out;
  877. size_t rlen;
  878. char *txt;
  879. int res;
  880. unsigned char *der = NULL;
  881. int der_len;
  882. const EC_GROUP *group;
  883. const EC_POINT *point;
  884. out = BIO_new(BIO_s_mem());
  885. if (!out)
  886. return;
  887. EVP_PKEY_print_private(out, key, 0, NULL);
  888. rlen = BIO_ctrl_pending(out);
  889. txt = os_malloc(rlen + 1);
  890. if (txt) {
  891. res = BIO_read(out, txt, rlen);
  892. if (res > 0) {
  893. txt[res] = '\0';
  894. wpa_printf(MSG_DEBUG, "%s: %s", title, txt);
  895. }
  896. os_free(txt);
  897. }
  898. BIO_free(out);
  899. eckey = EVP_PKEY_get1_EC_KEY(key);
  900. if (!eckey)
  901. return;
  902. group = EC_KEY_get0_group(eckey);
  903. point = EC_KEY_get0_public_key(eckey);
  904. if (group && point)
  905. dpp_debug_print_point(title, group, point);
  906. der_len = i2d_ECPrivateKey(eckey, &der);
  907. if (der_len > 0)
  908. wpa_hexdump_key(MSG_DEBUG, "DPP: ECPrivateKey", der, der_len);
  909. OPENSSL_free(der);
  910. if (der_len <= 0) {
  911. der = NULL;
  912. der_len = i2d_EC_PUBKEY(eckey, &der);
  913. if (der_len > 0)
  914. wpa_hexdump(MSG_DEBUG, "DPP: EC_PUBKEY", der, der_len);
  915. OPENSSL_free(der);
  916. }
  917. EC_KEY_free(eckey);
  918. }
  919. static EVP_PKEY * dpp_gen_keypair(const struct dpp_curve_params *curve)
  920. {
  921. #ifdef OPENSSL_IS_BORINGSSL
  922. EVP_PKEY_CTX *kctx = NULL;
  923. const EC_GROUP *group;
  924. EC_KEY *ec_params;
  925. #else
  926. EVP_PKEY_CTX *pctx, *kctx = NULL;
  927. #endif
  928. EVP_PKEY *params = NULL, *key = NULL;
  929. int nid;
  930. wpa_printf(MSG_DEBUG, "DPP: Generating a keypair");
  931. nid = OBJ_txt2nid(curve->name);
  932. if (nid == NID_undef) {
  933. wpa_printf(MSG_INFO, "DPP: Unsupported curve %s", curve->name);
  934. return NULL;
  935. }
  936. #ifdef OPENSSL_IS_BORINGSSL
  937. group = EC_GROUP_new_by_curve_name(nid);
  938. ec_params = EC_KEY_new();
  939. if (!ec_params || EC_KEY_set_group(ec_params, group) != 1) {
  940. wpa_printf(MSG_ERROR,
  941. "DPP: Failed to generate EC_KEY parameters");
  942. goto fail;
  943. }
  944. EC_KEY_set_asn1_flag(ec_params, OPENSSL_EC_NAMED_CURVE);
  945. params = EVP_PKEY_new();
  946. if (!params || EVP_PKEY_set1_EC_KEY(params, ec_params) != 1) {
  947. wpa_printf(MSG_ERROR,
  948. "DPP: Failed to generate EVP_PKEY parameters");
  949. goto fail;
  950. }
  951. #else
  952. pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
  953. if (!pctx ||
  954. EVP_PKEY_paramgen_init(pctx) != 1 ||
  955. EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) != 1 ||
  956. #ifdef EVP_PKEY_CTX_set_ec_param_enc
  957. EVP_PKEY_CTX_set_ec_param_enc(pctx, OPENSSL_EC_NAMED_CURVE) != 1 ||
  958. #endif
  959. EVP_PKEY_paramgen(pctx, &params) != 1) {
  960. wpa_printf(MSG_ERROR,
  961. "DPP: Failed to generate EVP_PKEY parameters");
  962. EVP_PKEY_CTX_free(pctx);
  963. goto fail;
  964. }
  965. EVP_PKEY_CTX_free(pctx);
  966. #endif
  967. kctx = EVP_PKEY_CTX_new(params, NULL);
  968. if (!kctx ||
  969. EVP_PKEY_keygen_init(kctx) != 1 ||
  970. EVP_PKEY_keygen(kctx, &key) != 1) {
  971. wpa_printf(MSG_ERROR, "DPP: Failed to generate EC key");
  972. goto fail;
  973. }
  974. if (wpa_debug_show_keys)
  975. dpp_debug_print_key("Own generated key", key);
  976. EVP_PKEY_free(params);
  977. EVP_PKEY_CTX_free(kctx);
  978. return key;
  979. fail:
  980. EVP_PKEY_CTX_free(kctx);
  981. EVP_PKEY_free(params);
  982. return NULL;
  983. }
  984. static const struct dpp_curve_params *
  985. dpp_get_curve_name(const char *name)
  986. {
  987. int i;
  988. for (i = 0; dpp_curves[i].name; i++) {
  989. if (os_strcmp(name, dpp_curves[i].name) == 0 ||
  990. (dpp_curves[i].jwk_crv &&
  991. os_strcmp(name, dpp_curves[i].jwk_crv) == 0))
  992. return &dpp_curves[i];
  993. }
  994. return NULL;
  995. }
  996. static const struct dpp_curve_params *
  997. dpp_get_curve_jwk_crv(const char *name)
  998. {
  999. int i;
  1000. for (i = 0; dpp_curves[i].name; i++) {
  1001. if (dpp_curves[i].jwk_crv &&
  1002. os_strcmp(name, dpp_curves[i].jwk_crv) == 0)
  1003. return &dpp_curves[i];
  1004. }
  1005. return NULL;
  1006. }
  1007. static EVP_PKEY * dpp_set_keypair(const struct dpp_curve_params **curve,
  1008. const u8 *privkey, size_t privkey_len)
  1009. {
  1010. EVP_PKEY *pkey;
  1011. EC_KEY *eckey;
  1012. const EC_GROUP *group;
  1013. int nid;
  1014. pkey = EVP_PKEY_new();
  1015. if (!pkey)
  1016. return NULL;
  1017. eckey = d2i_ECPrivateKey(NULL, &privkey, privkey_len);
  1018. if (!eckey) {
  1019. wpa_printf(MSG_INFO,
  1020. "DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
  1021. ERR_error_string(ERR_get_error(), NULL));
  1022. EVP_PKEY_free(pkey);
  1023. return NULL;
  1024. }
  1025. group = EC_KEY_get0_group(eckey);
  1026. if (!group) {
  1027. EC_KEY_free(eckey);
  1028. EVP_PKEY_free(pkey);
  1029. return NULL;
  1030. }
  1031. nid = EC_GROUP_get_curve_name(group);
  1032. *curve = dpp_get_curve_nid(nid);
  1033. if (!*curve) {
  1034. wpa_printf(MSG_INFO,
  1035. "DPP: Unsupported curve (nid=%d) in pre-assigned key",
  1036. nid);
  1037. EC_KEY_free(eckey);
  1038. EVP_PKEY_free(pkey);
  1039. return NULL;
  1040. }
  1041. if (EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
  1042. EC_KEY_free(eckey);
  1043. EVP_PKEY_free(pkey);
  1044. return NULL;
  1045. }
  1046. return pkey;
  1047. }
  1048. typedef struct {
  1049. /* AlgorithmIdentifier ecPublicKey with optional parameters present
  1050. * as an OID identifying the curve */
  1051. X509_ALGOR *alg;
  1052. /* Compressed format public key per ANSI X9.63 */
  1053. ASN1_BIT_STRING *pub_key;
  1054. } DPP_BOOTSTRAPPING_KEY;
  1055. ASN1_SEQUENCE(DPP_BOOTSTRAPPING_KEY) = {
  1056. ASN1_SIMPLE(DPP_BOOTSTRAPPING_KEY, alg, X509_ALGOR),
  1057. ASN1_SIMPLE(DPP_BOOTSTRAPPING_KEY, pub_key, ASN1_BIT_STRING)
  1058. } ASN1_SEQUENCE_END(DPP_BOOTSTRAPPING_KEY);
  1059. IMPLEMENT_ASN1_FUNCTIONS(DPP_BOOTSTRAPPING_KEY);
  1060. static struct wpabuf * dpp_bootstrap_key_der(EVP_PKEY *key)
  1061. {
  1062. unsigned char *der = NULL;
  1063. int der_len;
  1064. EC_KEY *eckey;
  1065. struct wpabuf *ret = NULL;
  1066. size_t len;
  1067. const EC_GROUP *group;
  1068. const EC_POINT *point;
  1069. BN_CTX *ctx;
  1070. DPP_BOOTSTRAPPING_KEY *bootstrap = NULL;
  1071. int nid;
  1072. ctx = BN_CTX_new();
  1073. eckey = EVP_PKEY_get1_EC_KEY(key);
  1074. if (!ctx || !eckey)
  1075. goto fail;
  1076. group = EC_KEY_get0_group(eckey);
  1077. point = EC_KEY_get0_public_key(eckey);
  1078. if (!group || !point)
  1079. goto fail;
  1080. dpp_debug_print_point("DPP: bootstrap public key", group, point);
  1081. nid = EC_GROUP_get_curve_name(group);
  1082. bootstrap = DPP_BOOTSTRAPPING_KEY_new();
  1083. if (!bootstrap ||
  1084. X509_ALGOR_set0(bootstrap->alg, OBJ_nid2obj(EVP_PKEY_EC),
  1085. V_ASN1_OBJECT, (void *) OBJ_nid2obj(nid)) != 1)
  1086. goto fail;
  1087. len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
  1088. NULL, 0, ctx);
  1089. if (len == 0)
  1090. goto fail;
  1091. der = OPENSSL_malloc(len);
  1092. if (!der)
  1093. goto fail;
  1094. len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
  1095. der, len, ctx);
  1096. OPENSSL_free(bootstrap->pub_key->data);
  1097. bootstrap->pub_key->data = der;
  1098. der = NULL;
  1099. bootstrap->pub_key->length = len;
  1100. /* No unused bits */
  1101. bootstrap->pub_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
  1102. bootstrap->pub_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
  1103. der_len = i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der);
  1104. if (der_len <= 0) {
  1105. wpa_printf(MSG_ERROR,
  1106. "DDP: Failed to build DER encoded public key");
  1107. goto fail;
  1108. }
  1109. ret = wpabuf_alloc_copy(der, der_len);
  1110. fail:
  1111. DPP_BOOTSTRAPPING_KEY_free(bootstrap);
  1112. OPENSSL_free(der);
  1113. EC_KEY_free(eckey);
  1114. BN_CTX_free(ctx);
  1115. return ret;
  1116. }
  1117. int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi)
  1118. {
  1119. struct wpabuf *der;
  1120. int res;
  1121. const u8 *addr[1];
  1122. size_t len[1];
  1123. der = dpp_bootstrap_key_der(bi->pubkey);
  1124. if (!der)
  1125. return -1;
  1126. wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)",
  1127. der);
  1128. addr[0] = wpabuf_head(der);
  1129. len[0] = wpabuf_len(der);
  1130. res = sha256_vector(1, addr, len, bi->pubkey_hash);
  1131. if (res < 0)
  1132. wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key");
  1133. else
  1134. wpa_hexdump(MSG_DEBUG, "DPP: Public key hash", bi->pubkey_hash,
  1135. SHA256_MAC_LEN);
  1136. wpabuf_free(der);
  1137. return res;
  1138. }
  1139. char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
  1140. const u8 *privkey, size_t privkey_len)
  1141. {
  1142. unsigned char *base64 = NULL;
  1143. char *pos, *end;
  1144. size_t len;
  1145. struct wpabuf *der = NULL;
  1146. const u8 *addr[1];
  1147. int res;
  1148. if (!curve) {
  1149. bi->curve = &dpp_curves[0];
  1150. } else {
  1151. bi->curve = dpp_get_curve_name(curve);
  1152. if (!bi->curve) {
  1153. wpa_printf(MSG_INFO, "DPP: Unsupported curve: %s",
  1154. curve);
  1155. return NULL;
  1156. }
  1157. }
  1158. if (privkey)
  1159. bi->pubkey = dpp_set_keypair(&bi->curve, privkey, privkey_len);
  1160. else
  1161. bi->pubkey = dpp_gen_keypair(bi->curve);
  1162. if (!bi->pubkey)
  1163. goto fail;
  1164. bi->own = 1;
  1165. der = dpp_bootstrap_key_der(bi->pubkey);
  1166. if (!der)
  1167. goto fail;
  1168. wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)",
  1169. der);
  1170. addr[0] = wpabuf_head(der);
  1171. len = wpabuf_len(der);
  1172. res = sha256_vector(1, addr, &len, bi->pubkey_hash);
  1173. if (res < 0) {
  1174. wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key");
  1175. goto fail;
  1176. }
  1177. wpa_hexdump(MSG_DEBUG, "DPP: Public key hash", bi->pubkey_hash,
  1178. SHA256_MAC_LEN);
  1179. base64 = base64_encode(wpabuf_head(der), wpabuf_len(der), &len);
  1180. wpabuf_free(der);
  1181. der = NULL;
  1182. if (!base64)
  1183. goto fail;
  1184. pos = (char *) base64;
  1185. end = pos + len;
  1186. for (;;) {
  1187. pos = os_strchr(pos, '\n');
  1188. if (!pos)
  1189. break;
  1190. os_memmove(pos, pos + 1, end - pos);
  1191. }
  1192. return (char *) base64;
  1193. fail:
  1194. os_free(base64);
  1195. wpabuf_free(der);
  1196. return NULL;
  1197. }
  1198. static int dpp_derive_k1(const u8 *Mx, size_t Mx_len, u8 *k1,
  1199. unsigned int hash_len)
  1200. {
  1201. u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN];
  1202. const char *info = "first intermediate key";
  1203. int res;
  1204. /* k1 = HKDF(<>, "first intermediate key", M.x) */
  1205. /* HKDF-Extract(<>, M.x) */
  1206. os_memset(salt, 0, hash_len);
  1207. if (dpp_hmac(hash_len, salt, hash_len, Mx, Mx_len, prk) < 0)
  1208. return -1;
  1209. wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM=M.x)",
  1210. prk, hash_len);
  1211. /* HKDF-Expand(PRK, info, L) */
  1212. res = dpp_hkdf_expand(hash_len, prk, hash_len, info, k1, hash_len);
  1213. os_memset(prk, 0, hash_len);
  1214. if (res < 0)
  1215. return -1;
  1216. wpa_hexdump_key(MSG_DEBUG, "DPP: k1 = HKDF-Expand(PRK, info, L)",
  1217. k1, hash_len);
  1218. return 0;
  1219. }
  1220. static int dpp_derive_k2(const u8 *Nx, size_t Nx_len, u8 *k2,
  1221. unsigned int hash_len)
  1222. {
  1223. u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN];
  1224. const char *info = "second intermediate key";
  1225. int res;
  1226. /* k2 = HKDF(<>, "second intermediate key", N.x) */
  1227. /* HKDF-Extract(<>, N.x) */
  1228. os_memset(salt, 0, hash_len);
  1229. res = dpp_hmac(hash_len, salt, hash_len, Nx, Nx_len, prk);
  1230. if (res < 0)
  1231. return -1;
  1232. wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM=N.x)",
  1233. prk, hash_len);
  1234. /* HKDF-Expand(PRK, info, L) */
  1235. res = dpp_hkdf_expand(hash_len, prk, hash_len, info, k2, hash_len);
  1236. os_memset(prk, 0, hash_len);
  1237. if (res < 0)
  1238. return -1;
  1239. wpa_hexdump_key(MSG_DEBUG, "DPP: k2 = HKDF-Expand(PRK, info, L)",
  1240. k2, hash_len);
  1241. return 0;
  1242. }
  1243. static int dpp_derive_ke(struct dpp_authentication *auth, u8 *ke,
  1244. unsigned int hash_len)
  1245. {
  1246. size_t nonce_len;
  1247. u8 nonces[2 * DPP_MAX_NONCE_LEN];
  1248. const char *info_ke = "DPP Key";
  1249. u8 prk[DPP_MAX_HASH_LEN];
  1250. int res;
  1251. const u8 *addr[3];
  1252. size_t len[3];
  1253. size_t num_elem = 0;
  1254. /* ke = HKDF(I-nonce | R-nonce, "DPP Key", M.x | N.x [| L.x]) */
  1255. /* HKDF-Extract(I-nonce | R-nonce, M.x | N.x [| L.x]) */
  1256. nonce_len = auth->curve->nonce_len;
  1257. os_memcpy(nonces, auth->i_nonce, nonce_len);
  1258. os_memcpy(&nonces[nonce_len], auth->r_nonce, nonce_len);
  1259. addr[num_elem] = auth->Mx;
  1260. len[num_elem] = auth->secret_len;
  1261. num_elem++;
  1262. addr[num_elem] = auth->Nx;
  1263. len[num_elem] = auth->secret_len;
  1264. num_elem++;
  1265. if (auth->peer_bi && auth->own_bi) {
  1266. addr[num_elem] = auth->Lx;
  1267. len[num_elem] = auth->secret_len;
  1268. num_elem++;
  1269. }
  1270. res = dpp_hmac_vector(hash_len, nonces, 2 * nonce_len,
  1271. num_elem, addr, len, prk);
  1272. if (res < 0)
  1273. return -1;
  1274. wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM)",
  1275. prk, hash_len);
  1276. /* HKDF-Expand(PRK, info, L) */
  1277. res = dpp_hkdf_expand(hash_len, prk, hash_len, info_ke, ke, hash_len);
  1278. os_memset(prk, 0, hash_len);
  1279. if (res < 0)
  1280. return -1;
  1281. wpa_hexdump_key(MSG_DEBUG, "DPP: ke = HKDF-Expand(PRK, info, L)",
  1282. ke, hash_len);
  1283. return 0;
  1284. }
  1285. static void dpp_build_attr_status(struct wpabuf *msg,
  1286. enum dpp_status_error status)
  1287. {
  1288. wpa_printf(MSG_DEBUG, "DPP: Status %d", status);
  1289. wpabuf_put_le16(msg, DPP_ATTR_STATUS);
  1290. wpabuf_put_le16(msg, 1);
  1291. wpabuf_put_u8(msg, status);
  1292. }
  1293. static void dpp_build_attr_r_bootstrap_key_hash(struct wpabuf *msg,
  1294. const u8 *hash)
  1295. {
  1296. if (hash) {
  1297. wpa_printf(MSG_DEBUG, "DPP: R-Bootstrap Key Hash");
  1298. wpabuf_put_le16(msg, DPP_ATTR_R_BOOTSTRAP_KEY_HASH);
  1299. wpabuf_put_le16(msg, SHA256_MAC_LEN);
  1300. wpabuf_put_data(msg, hash, SHA256_MAC_LEN);
  1301. }
  1302. }
  1303. static void dpp_build_attr_i_bootstrap_key_hash(struct wpabuf *msg,
  1304. const u8 *hash)
  1305. {
  1306. if (hash) {
  1307. wpa_printf(MSG_DEBUG, "DPP: I-Bootstrap Key Hash");
  1308. wpabuf_put_le16(msg, DPP_ATTR_I_BOOTSTRAP_KEY_HASH);
  1309. wpabuf_put_le16(msg, SHA256_MAC_LEN);
  1310. wpabuf_put_data(msg, hash, SHA256_MAC_LEN);
  1311. }
  1312. }
  1313. static struct wpabuf * dpp_auth_build_req(struct dpp_authentication *auth,
  1314. const struct wpabuf *pi,
  1315. size_t nonce_len,
  1316. const u8 *r_pubkey_hash,
  1317. const u8 *i_pubkey_hash,
  1318. unsigned int neg_freq)
  1319. {
  1320. struct wpabuf *msg;
  1321. u8 clear[4 + DPP_MAX_NONCE_LEN + 4 + 1];
  1322. u8 wrapped_data[4 + DPP_MAX_NONCE_LEN + 4 + 1 + AES_BLOCK_SIZE];
  1323. u8 *pos;
  1324. const u8 *addr[2];
  1325. size_t len[2], siv_len, attr_len;
  1326. u8 *attr_start, *attr_end;
  1327. /* Build DPP Authentication Request frame attributes */
  1328. attr_len = 2 * (4 + SHA256_MAC_LEN) + 4 + (pi ? wpabuf_len(pi) : 0) +
  1329. 4 + sizeof(wrapped_data);
  1330. if (neg_freq > 0)
  1331. attr_len += 4 + 2;
  1332. #ifdef CONFIG_TESTING_OPTIONS
  1333. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ)
  1334. attr_len += 5;
  1335. #endif /* CONFIG_TESTING_OPTIONS */
  1336. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ, attr_len);
  1337. if (!msg)
  1338. return NULL;
  1339. attr_start = wpabuf_put(msg, 0);
  1340. /* Responder Bootstrapping Key Hash */
  1341. dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash);
  1342. /* Initiator Bootstrapping Key Hash */
  1343. dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash);
  1344. /* Initiator Protocol Key */
  1345. if (pi) {
  1346. wpabuf_put_le16(msg, DPP_ATTR_I_PROTOCOL_KEY);
  1347. wpabuf_put_le16(msg, wpabuf_len(pi));
  1348. wpabuf_put_buf(msg, pi);
  1349. }
  1350. /* Channel */
  1351. if (neg_freq > 0) {
  1352. u8 op_class, channel;
  1353. if (ieee80211_freq_to_channel_ext(neg_freq, 0, 0, &op_class,
  1354. &channel) ==
  1355. NUM_HOSTAPD_MODES) {
  1356. wpa_printf(MSG_INFO,
  1357. "DPP: Unsupported negotiation frequency request: %d",
  1358. neg_freq);
  1359. wpabuf_free(msg);
  1360. return NULL;
  1361. }
  1362. wpabuf_put_le16(msg, DPP_ATTR_CHANNEL);
  1363. wpabuf_put_le16(msg, 2);
  1364. wpabuf_put_u8(msg, op_class);
  1365. wpabuf_put_u8(msg, channel);
  1366. }
  1367. #ifdef CONFIG_TESTING_OPTIONS
  1368. if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_REQ) {
  1369. wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data");
  1370. goto skip_wrapped_data;
  1371. }
  1372. #endif /* CONFIG_TESTING_OPTIONS */
  1373. /* Wrapped data ({I-nonce, I-capabilities}k1) */
  1374. pos = clear;
  1375. #ifdef CONFIG_TESTING_OPTIONS
  1376. if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_REQ) {
  1377. wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce");
  1378. goto skip_i_nonce;
  1379. }
  1380. if (dpp_test == DPP_TEST_INVALID_I_NONCE_AUTH_REQ) {
  1381. wpa_printf(MSG_INFO, "DPP: TESTING - invalid I-nonce");
  1382. WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
  1383. pos += 2;
  1384. WPA_PUT_LE16(pos, nonce_len - 1);
  1385. pos += 2;
  1386. os_memcpy(pos, auth->i_nonce, nonce_len - 1);
  1387. pos += nonce_len - 1;
  1388. goto skip_i_nonce;
  1389. }
  1390. #endif /* CONFIG_TESTING_OPTIONS */
  1391. /* I-nonce */
  1392. WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
  1393. pos += 2;
  1394. WPA_PUT_LE16(pos, nonce_len);
  1395. pos += 2;
  1396. os_memcpy(pos, auth->i_nonce, nonce_len);
  1397. pos += nonce_len;
  1398. #ifdef CONFIG_TESTING_OPTIONS
  1399. skip_i_nonce:
  1400. if (dpp_test == DPP_TEST_NO_I_CAPAB_AUTH_REQ) {
  1401. wpa_printf(MSG_INFO, "DPP: TESTING - no I-capab");
  1402. goto skip_i_capab;
  1403. }
  1404. #endif /* CONFIG_TESTING_OPTIONS */
  1405. /* I-capabilities */
  1406. WPA_PUT_LE16(pos, DPP_ATTR_I_CAPABILITIES);
  1407. pos += 2;
  1408. WPA_PUT_LE16(pos, 1);
  1409. pos += 2;
  1410. auth->i_capab = auth->allowed_roles;
  1411. *pos++ = auth->i_capab;
  1412. #ifdef CONFIG_TESTING_OPTIONS
  1413. if (dpp_test == DPP_TEST_ZERO_I_CAPAB) {
  1414. wpa_printf(MSG_INFO, "DPP: TESTING - zero I-capabilities");
  1415. pos[-1] = 0;
  1416. }
  1417. skip_i_capab:
  1418. #endif /* CONFIG_TESTING_OPTIONS */
  1419. attr_end = wpabuf_put(msg, 0);
  1420. /* OUI, OUI type, Crypto Suite, DPP frame type */
  1421. addr[0] = wpabuf_head_u8(msg) + 2;
  1422. len[0] = 3 + 1 + 1 + 1;
  1423. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  1424. /* Attributes before Wrapped Data */
  1425. addr[1] = attr_start;
  1426. len[1] = attr_end - attr_start;
  1427. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  1428. siv_len = pos - clear;
  1429. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
  1430. if (aes_siv_encrypt(auth->k1, auth->curve->hash_len, clear, siv_len,
  1431. 2, addr, len, wrapped_data) < 0) {
  1432. wpabuf_free(msg);
  1433. return NULL;
  1434. }
  1435. siv_len += AES_BLOCK_SIZE;
  1436. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  1437. wrapped_data, siv_len);
  1438. wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
  1439. wpabuf_put_le16(msg, siv_len);
  1440. wpabuf_put_data(msg, wrapped_data, siv_len);
  1441. #ifdef CONFIG_TESTING_OPTIONS
  1442. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ) {
  1443. wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
  1444. dpp_build_attr_status(msg, DPP_STATUS_OK);
  1445. }
  1446. skip_wrapped_data:
  1447. #endif /* CONFIG_TESTING_OPTIONS */
  1448. wpa_hexdump_buf(MSG_DEBUG,
  1449. "DPP: Authentication Request frame attributes", msg);
  1450. return msg;
  1451. }
  1452. static struct wpabuf * dpp_auth_build_resp(struct dpp_authentication *auth,
  1453. enum dpp_status_error status,
  1454. const struct wpabuf *pr,
  1455. size_t nonce_len,
  1456. const u8 *r_pubkey_hash,
  1457. const u8 *i_pubkey_hash,
  1458. const u8 *r_nonce, const u8 *i_nonce,
  1459. const u8 *wrapped_r_auth,
  1460. size_t wrapped_r_auth_len,
  1461. const u8 *siv_key)
  1462. {
  1463. struct wpabuf *msg;
  1464. #define DPP_AUTH_RESP_CLEAR_LEN 2 * (4 + DPP_MAX_NONCE_LEN) + 4 + 1 + \
  1465. 4 + 4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE
  1466. u8 clear[DPP_AUTH_RESP_CLEAR_LEN];
  1467. u8 wrapped_data[DPP_AUTH_RESP_CLEAR_LEN + AES_BLOCK_SIZE];
  1468. const u8 *addr[2];
  1469. size_t len[2], siv_len, attr_len;
  1470. u8 *attr_start, *attr_end, *pos;
  1471. auth->waiting_auth_conf = 1;
  1472. auth->auth_resp_tries = 0;
  1473. /* Build DPP Authentication Response frame attributes */
  1474. attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
  1475. 4 + (pr ? wpabuf_len(pr) : 0) + 4 + sizeof(wrapped_data);
  1476. #ifdef CONFIG_TESTING_OPTIONS
  1477. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP)
  1478. attr_len += 5;
  1479. #endif /* CONFIG_TESTING_OPTIONS */
  1480. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
  1481. if (!msg)
  1482. return NULL;
  1483. attr_start = wpabuf_put(msg, 0);
  1484. /* DPP Status */
  1485. if (status != 255)
  1486. dpp_build_attr_status(msg, status);
  1487. /* Responder Bootstrapping Key Hash */
  1488. dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash);
  1489. /* Initiator Bootstrapping Key Hash (mutual authentication) */
  1490. dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash);
  1491. /* Responder Protocol Key */
  1492. if (pr) {
  1493. wpabuf_put_le16(msg, DPP_ATTR_R_PROTOCOL_KEY);
  1494. wpabuf_put_le16(msg, wpabuf_len(pr));
  1495. wpabuf_put_buf(msg, pr);
  1496. }
  1497. attr_end = wpabuf_put(msg, 0);
  1498. #ifdef CONFIG_TESTING_OPTIONS
  1499. if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_RESP) {
  1500. wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data");
  1501. goto skip_wrapped_data;
  1502. }
  1503. #endif /* CONFIG_TESTING_OPTIONS */
  1504. /* Wrapped data ({R-nonce, I-nonce, R-capabilities, {R-auth}ke}k2) */
  1505. pos = clear;
  1506. if (r_nonce) {
  1507. /* R-nonce */
  1508. WPA_PUT_LE16(pos, DPP_ATTR_R_NONCE);
  1509. pos += 2;
  1510. WPA_PUT_LE16(pos, nonce_len);
  1511. pos += 2;
  1512. os_memcpy(pos, r_nonce, nonce_len);
  1513. pos += nonce_len;
  1514. }
  1515. if (i_nonce) {
  1516. /* I-nonce */
  1517. WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
  1518. pos += 2;
  1519. WPA_PUT_LE16(pos, nonce_len);
  1520. pos += 2;
  1521. os_memcpy(pos, i_nonce, nonce_len);
  1522. #ifdef CONFIG_TESTING_OPTIONS
  1523. if (dpp_test == DPP_TEST_I_NONCE_MISMATCH_AUTH_RESP) {
  1524. wpa_printf(MSG_INFO, "DPP: TESTING - I-nonce mismatch");
  1525. pos[nonce_len / 2] ^= 0x01;
  1526. }
  1527. #endif /* CONFIG_TESTING_OPTIONS */
  1528. pos += nonce_len;
  1529. }
  1530. #ifdef CONFIG_TESTING_OPTIONS
  1531. if (dpp_test == DPP_TEST_NO_R_CAPAB_AUTH_RESP) {
  1532. wpa_printf(MSG_INFO, "DPP: TESTING - no R-capab");
  1533. goto skip_r_capab;
  1534. }
  1535. #endif /* CONFIG_TESTING_OPTIONS */
  1536. /* R-capabilities */
  1537. WPA_PUT_LE16(pos, DPP_ATTR_R_CAPABILITIES);
  1538. pos += 2;
  1539. WPA_PUT_LE16(pos, 1);
  1540. pos += 2;
  1541. auth->r_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR :
  1542. DPP_CAPAB_ENROLLEE;
  1543. *pos++ = auth->r_capab;
  1544. #ifdef CONFIG_TESTING_OPTIONS
  1545. if (dpp_test == DPP_TEST_ZERO_R_CAPAB) {
  1546. wpa_printf(MSG_INFO, "DPP: TESTING - zero R-capabilities");
  1547. pos[-1] = 0;
  1548. } else if (dpp_test == DPP_TEST_INCOMPATIBLE_R_CAPAB_AUTH_RESP) {
  1549. wpa_printf(MSG_INFO,
  1550. "DPP: TESTING - incompatible R-capabilities");
  1551. if ((auth->i_capab & DPP_CAPAB_ROLE_MASK) ==
  1552. (DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE))
  1553. pos[-1] = 0;
  1554. else
  1555. pos[-1] = auth->configurator ? DPP_CAPAB_ENROLLEE :
  1556. DPP_CAPAB_CONFIGURATOR;
  1557. }
  1558. skip_r_capab:
  1559. #endif /* CONFIG_TESTING_OPTIONS */
  1560. if (wrapped_r_auth) {
  1561. /* {R-auth}ke */
  1562. WPA_PUT_LE16(pos, DPP_ATTR_WRAPPED_DATA);
  1563. pos += 2;
  1564. WPA_PUT_LE16(pos, wrapped_r_auth_len);
  1565. pos += 2;
  1566. os_memcpy(pos, wrapped_r_auth, wrapped_r_auth_len);
  1567. pos += wrapped_r_auth_len;
  1568. }
  1569. /* OUI, OUI type, Crypto Suite, DPP frame type */
  1570. addr[0] = wpabuf_head_u8(msg) + 2;
  1571. len[0] = 3 + 1 + 1 + 1;
  1572. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  1573. /* Attributes before Wrapped Data */
  1574. addr[1] = attr_start;
  1575. len[1] = attr_end - attr_start;
  1576. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  1577. siv_len = pos - clear;
  1578. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
  1579. if (aes_siv_encrypt(siv_key, auth->curve->hash_len, clear, siv_len,
  1580. 2, addr, len, wrapped_data) < 0) {
  1581. wpabuf_free(msg);
  1582. return NULL;
  1583. }
  1584. siv_len += AES_BLOCK_SIZE;
  1585. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  1586. wrapped_data, siv_len);
  1587. wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
  1588. wpabuf_put_le16(msg, siv_len);
  1589. wpabuf_put_data(msg, wrapped_data, siv_len);
  1590. #ifdef CONFIG_TESTING_OPTIONS
  1591. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP) {
  1592. wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
  1593. dpp_build_attr_status(msg, DPP_STATUS_OK);
  1594. }
  1595. skip_wrapped_data:
  1596. #endif /* CONFIG_TESTING_OPTIONS */
  1597. wpa_hexdump_buf(MSG_DEBUG,
  1598. "DPP: Authentication Response frame attributes", msg);
  1599. return msg;
  1600. }
  1601. static int dpp_channel_ok_init(struct hostapd_hw_modes *own_modes,
  1602. u16 num_modes, unsigned int freq)
  1603. {
  1604. u16 m;
  1605. int c, flag;
  1606. if (!own_modes || !num_modes)
  1607. return 1;
  1608. for (m = 0; m < num_modes; m++) {
  1609. for (c = 0; c < own_modes[m].num_channels; c++) {
  1610. if ((unsigned int) own_modes[m].channels[c].freq !=
  1611. freq)
  1612. continue;
  1613. flag = own_modes[m].channels[c].flag;
  1614. if (!(flag & (HOSTAPD_CHAN_DISABLED |
  1615. HOSTAPD_CHAN_NO_IR |
  1616. HOSTAPD_CHAN_RADAR)))
  1617. return 1;
  1618. }
  1619. }
  1620. wpa_printf(MSG_DEBUG, "DPP: Peer channel %u MHz not supported", freq);
  1621. return 0;
  1622. }
  1623. static int freq_included(const unsigned int freqs[], unsigned int num,
  1624. unsigned int freq)
  1625. {
  1626. while (num > 0) {
  1627. if (freqs[--num] == freq)
  1628. return 1;
  1629. }
  1630. return 0;
  1631. }
  1632. static void freq_to_start(unsigned int freqs[], unsigned int num,
  1633. unsigned int freq)
  1634. {
  1635. unsigned int i;
  1636. for (i = 0; i < num; i++) {
  1637. if (freqs[i] == freq)
  1638. break;
  1639. }
  1640. if (i == 0 || i >= num)
  1641. return;
  1642. os_memmove(&freqs[1], &freqs[0], i * sizeof(freqs[0]));
  1643. freqs[0] = freq;
  1644. }
  1645. static int dpp_channel_intersect(struct dpp_authentication *auth,
  1646. struct hostapd_hw_modes *own_modes,
  1647. u16 num_modes)
  1648. {
  1649. struct dpp_bootstrap_info *peer_bi = auth->peer_bi;
  1650. unsigned int i, freq;
  1651. for (i = 0; i < peer_bi->num_freq; i++) {
  1652. freq = peer_bi->freq[i];
  1653. if (freq_included(auth->freq, auth->num_freq, freq))
  1654. continue;
  1655. if (dpp_channel_ok_init(own_modes, num_modes, freq))
  1656. auth->freq[auth->num_freq++] = freq;
  1657. }
  1658. if (!auth->num_freq) {
  1659. wpa_printf(MSG_INFO,
  1660. "DPP: No available channels for initiating DPP Authentication");
  1661. return -1;
  1662. }
  1663. auth->curr_freq = auth->freq[0];
  1664. return 0;
  1665. }
  1666. static int dpp_channel_local_list(struct dpp_authentication *auth,
  1667. struct hostapd_hw_modes *own_modes,
  1668. u16 num_modes)
  1669. {
  1670. u16 m;
  1671. int c, flag;
  1672. unsigned int freq;
  1673. auth->num_freq = 0;
  1674. if (!own_modes || !num_modes) {
  1675. auth->freq[0] = 2412;
  1676. auth->freq[1] = 2437;
  1677. auth->freq[2] = 2462;
  1678. auth->num_freq = 3;
  1679. return 0;
  1680. }
  1681. for (m = 0; m < num_modes; m++) {
  1682. for (c = 0; c < own_modes[m].num_channels; c++) {
  1683. freq = own_modes[m].channels[c].freq;
  1684. flag = own_modes[m].channels[c].flag;
  1685. if (flag & (HOSTAPD_CHAN_DISABLED |
  1686. HOSTAPD_CHAN_NO_IR |
  1687. HOSTAPD_CHAN_RADAR))
  1688. continue;
  1689. if (freq_included(auth->freq, auth->num_freq, freq))
  1690. continue;
  1691. auth->freq[auth->num_freq++] = freq;
  1692. if (auth->num_freq == DPP_BOOTSTRAP_MAX_FREQ) {
  1693. m = num_modes;
  1694. break;
  1695. }
  1696. }
  1697. }
  1698. return auth->num_freq == 0 ? -1 : 0;
  1699. }
  1700. static int dpp_prepare_channel_list(struct dpp_authentication *auth,
  1701. struct hostapd_hw_modes *own_modes,
  1702. u16 num_modes)
  1703. {
  1704. int res;
  1705. char freqs[DPP_BOOTSTRAP_MAX_FREQ * 6 + 10], *pos, *end;
  1706. unsigned int i;
  1707. if (auth->peer_bi->num_freq > 0)
  1708. res = dpp_channel_intersect(auth, own_modes, num_modes);
  1709. else
  1710. res = dpp_channel_local_list(auth, own_modes, num_modes);
  1711. if (res < 0)
  1712. return res;
  1713. /* Prioritize 2.4 GHz channels 6, 1, 11 (in this order) to hit the most
  1714. * likely channels first. */
  1715. freq_to_start(auth->freq, auth->num_freq, 2462);
  1716. freq_to_start(auth->freq, auth->num_freq, 2412);
  1717. freq_to_start(auth->freq, auth->num_freq, 2437);
  1718. auth->freq_idx = 0;
  1719. auth->curr_freq = auth->freq[0];
  1720. pos = freqs;
  1721. end = pos + sizeof(freqs);
  1722. for (i = 0; i < auth->num_freq; i++) {
  1723. res = os_snprintf(pos, end - pos, " %u", auth->freq[i]);
  1724. if (os_snprintf_error(end - pos, res))
  1725. break;
  1726. pos += res;
  1727. }
  1728. *pos = '\0';
  1729. wpa_printf(MSG_DEBUG, "DPP: Possible frequencies for initiating:%s",
  1730. freqs);
  1731. return 0;
  1732. }
  1733. static int dpp_autogen_bootstrap_key(struct dpp_authentication *auth)
  1734. {
  1735. struct dpp_bootstrap_info *bi;
  1736. char *pk = NULL;
  1737. size_t len;
  1738. if (auth->own_bi)
  1739. return 0; /* already generated */
  1740. bi = os_zalloc(sizeof(*bi));
  1741. if (!bi)
  1742. return -1;
  1743. bi->type = DPP_BOOTSTRAP_QR_CODE;
  1744. pk = dpp_keygen(bi, auth->peer_bi->curve->name, NULL, 0);
  1745. if (!pk)
  1746. goto fail;
  1747. len = 4; /* "DPP:" */
  1748. len += 4 + os_strlen(pk);
  1749. bi->uri = os_malloc(len + 1);
  1750. if (!bi->uri)
  1751. goto fail;
  1752. os_snprintf(bi->uri, len + 1, "DPP:K:%s;;", pk);
  1753. wpa_printf(MSG_DEBUG,
  1754. "DPP: Auto-generated own bootstrapping key info: URI %s",
  1755. bi->uri);
  1756. auth->tmp_own_bi = auth->own_bi = bi;
  1757. os_free(pk);
  1758. return 0;
  1759. fail:
  1760. os_free(pk);
  1761. dpp_bootstrap_info_free(bi);
  1762. return -1;
  1763. }
  1764. struct dpp_authentication * dpp_auth_init(void *msg_ctx,
  1765. struct dpp_bootstrap_info *peer_bi,
  1766. struct dpp_bootstrap_info *own_bi,
  1767. u8 dpp_allowed_roles,
  1768. unsigned int neg_freq,
  1769. struct hostapd_hw_modes *own_modes,
  1770. u16 num_modes)
  1771. {
  1772. struct dpp_authentication *auth;
  1773. size_t nonce_len;
  1774. EVP_PKEY_CTX *ctx = NULL;
  1775. size_t secret_len;
  1776. struct wpabuf *pi = NULL;
  1777. const u8 *r_pubkey_hash, *i_pubkey_hash;
  1778. #ifdef CONFIG_TESTING_OPTIONS
  1779. u8 test_hash[SHA256_MAC_LEN];
  1780. #endif /* CONFIG_TESTING_OPTIONS */
  1781. auth = os_zalloc(sizeof(*auth));
  1782. if (!auth)
  1783. return NULL;
  1784. auth->msg_ctx = msg_ctx;
  1785. auth->initiator = 1;
  1786. auth->waiting_auth_resp = 1;
  1787. auth->allowed_roles = dpp_allowed_roles;
  1788. auth->configurator = !!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR);
  1789. auth->peer_bi = peer_bi;
  1790. auth->own_bi = own_bi;
  1791. auth->curve = peer_bi->curve;
  1792. if (dpp_autogen_bootstrap_key(auth) < 0 ||
  1793. dpp_prepare_channel_list(auth, own_modes, num_modes) < 0)
  1794. goto fail;
  1795. nonce_len = auth->curve->nonce_len;
  1796. if (random_get_bytes(auth->i_nonce, nonce_len)) {
  1797. wpa_printf(MSG_ERROR, "DPP: Failed to generate I-nonce");
  1798. goto fail;
  1799. }
  1800. wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", auth->i_nonce, nonce_len);
  1801. auth->own_protocol_key = dpp_gen_keypair(auth->curve);
  1802. if (!auth->own_protocol_key)
  1803. goto fail;
  1804. pi = dpp_get_pubkey_point(auth->own_protocol_key, 0);
  1805. if (!pi)
  1806. goto fail;
  1807. /* ECDH: M = pI * BR */
  1808. ctx = EVP_PKEY_CTX_new(auth->own_protocol_key, NULL);
  1809. if (!ctx ||
  1810. EVP_PKEY_derive_init(ctx) != 1 ||
  1811. EVP_PKEY_derive_set_peer(ctx, auth->peer_bi->pubkey) != 1 ||
  1812. EVP_PKEY_derive(ctx, NULL, &secret_len) != 1 ||
  1813. secret_len > DPP_MAX_SHARED_SECRET_LEN ||
  1814. EVP_PKEY_derive(ctx, auth->Mx, &secret_len) != 1) {
  1815. wpa_printf(MSG_ERROR,
  1816. "DPP: Failed to derive ECDH shared secret: %s",
  1817. ERR_error_string(ERR_get_error(), NULL));
  1818. goto fail;
  1819. }
  1820. auth->secret_len = secret_len;
  1821. EVP_PKEY_CTX_free(ctx);
  1822. ctx = NULL;
  1823. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)",
  1824. auth->Mx, auth->secret_len);
  1825. if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1,
  1826. auth->curve->hash_len) < 0)
  1827. goto fail;
  1828. r_pubkey_hash = auth->peer_bi->pubkey_hash;
  1829. i_pubkey_hash = auth->own_bi->pubkey_hash;
  1830. #ifdef CONFIG_TESTING_OPTIONS
  1831. if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
  1832. wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
  1833. r_pubkey_hash = NULL;
  1834. } else if (dpp_test == DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
  1835. wpa_printf(MSG_INFO,
  1836. "DPP: TESTING - invalid R-Bootstrap Key Hash");
  1837. os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
  1838. test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
  1839. r_pubkey_hash = test_hash;
  1840. } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
  1841. wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
  1842. i_pubkey_hash = NULL;
  1843. } else if (dpp_test == DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
  1844. wpa_printf(MSG_INFO,
  1845. "DPP: TESTING - invalid I-Bootstrap Key Hash");
  1846. os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
  1847. test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
  1848. i_pubkey_hash = test_hash;
  1849. } else if (dpp_test == DPP_TEST_NO_I_PROTO_KEY_AUTH_REQ) {
  1850. wpa_printf(MSG_INFO, "DPP: TESTING - no I-Proto Key");
  1851. wpabuf_free(pi);
  1852. pi = NULL;
  1853. } else if (dpp_test == DPP_TEST_INVALID_I_PROTO_KEY_AUTH_REQ) {
  1854. wpa_printf(MSG_INFO, "DPP: TESTING - invalid I-Proto Key");
  1855. wpabuf_free(pi);
  1856. pi = wpabuf_alloc(2 * auth->curve->prime_len);
  1857. if (!pi || dpp_test_gen_invalid_key(pi, auth->curve) < 0)
  1858. goto fail;
  1859. }
  1860. #endif /* CONFIG_TESTING_OPTIONS */
  1861. auth->req_msg = dpp_auth_build_req(auth, pi, nonce_len, r_pubkey_hash,
  1862. i_pubkey_hash, neg_freq);
  1863. if (!auth->req_msg)
  1864. goto fail;
  1865. out:
  1866. wpabuf_free(pi);
  1867. EVP_PKEY_CTX_free(ctx);
  1868. return auth;
  1869. fail:
  1870. dpp_auth_deinit(auth);
  1871. auth = NULL;
  1872. goto out;
  1873. }
  1874. struct wpabuf * dpp_build_conf_req(struct dpp_authentication *auth,
  1875. const char *json)
  1876. {
  1877. size_t nonce_len;
  1878. size_t json_len, clear_len;
  1879. struct wpabuf *clear = NULL, *msg = NULL;
  1880. u8 *wrapped;
  1881. size_t attr_len;
  1882. wpa_printf(MSG_DEBUG, "DPP: Build configuration request");
  1883. nonce_len = auth->curve->nonce_len;
  1884. if (random_get_bytes(auth->e_nonce, nonce_len)) {
  1885. wpa_printf(MSG_ERROR, "DPP: Failed to generate E-nonce");
  1886. goto fail;
  1887. }
  1888. wpa_hexdump(MSG_DEBUG, "DPP: E-nonce", auth->e_nonce, nonce_len);
  1889. json_len = os_strlen(json);
  1890. wpa_hexdump_ascii(MSG_DEBUG, "DPP: configAttr JSON", json, json_len);
  1891. /* { E-nonce, configAttrib }ke */
  1892. clear_len = 4 + nonce_len + 4 + json_len;
  1893. clear = wpabuf_alloc(clear_len);
  1894. attr_len = 4 + clear_len + AES_BLOCK_SIZE;
  1895. #ifdef CONFIG_TESTING_OPTIONS
  1896. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_CONF_REQ)
  1897. attr_len += 5;
  1898. #endif /* CONFIG_TESTING_OPTIONS */
  1899. msg = wpabuf_alloc(attr_len);
  1900. if (!clear || !msg)
  1901. goto fail;
  1902. #ifdef CONFIG_TESTING_OPTIONS
  1903. if (dpp_test == DPP_TEST_NO_E_NONCE_CONF_REQ) {
  1904. wpa_printf(MSG_INFO, "DPP: TESTING - no E-nonce");
  1905. goto skip_e_nonce;
  1906. }
  1907. if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_CONF_REQ) {
  1908. wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data");
  1909. goto skip_wrapped_data;
  1910. }
  1911. #endif /* CONFIG_TESTING_OPTIONS */
  1912. /* E-nonce */
  1913. wpabuf_put_le16(clear, DPP_ATTR_ENROLLEE_NONCE);
  1914. wpabuf_put_le16(clear, nonce_len);
  1915. wpabuf_put_data(clear, auth->e_nonce, nonce_len);
  1916. #ifdef CONFIG_TESTING_OPTIONS
  1917. skip_e_nonce:
  1918. if (dpp_test == DPP_TEST_NO_CONFIG_ATTR_OBJ_CONF_REQ) {
  1919. wpa_printf(MSG_INFO, "DPP: TESTING - no configAttrib");
  1920. goto skip_conf_attr_obj;
  1921. }
  1922. #endif /* CONFIG_TESTING_OPTIONS */
  1923. /* configAttrib */
  1924. wpabuf_put_le16(clear, DPP_ATTR_CONFIG_ATTR_OBJ);
  1925. wpabuf_put_le16(clear, json_len);
  1926. wpabuf_put_data(clear, json, json_len);
  1927. #ifdef CONFIG_TESTING_OPTIONS
  1928. skip_conf_attr_obj:
  1929. #endif /* CONFIG_TESTING_OPTIONS */
  1930. wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
  1931. wpabuf_put_le16(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
  1932. wrapped = wpabuf_put(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
  1933. /* No AES-SIV AD */
  1934. wpa_hexdump_buf(MSG_DEBUG, "DPP: AES-SIV cleartext", clear);
  1935. if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
  1936. wpabuf_head(clear), wpabuf_len(clear),
  1937. 0, NULL, NULL, wrapped) < 0)
  1938. goto fail;
  1939. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  1940. wrapped, wpabuf_len(clear) + AES_BLOCK_SIZE);
  1941. #ifdef CONFIG_TESTING_OPTIONS
  1942. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_CONF_REQ) {
  1943. wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
  1944. dpp_build_attr_status(msg, DPP_STATUS_OK);
  1945. }
  1946. skip_wrapped_data:
  1947. #endif /* CONFIG_TESTING_OPTIONS */
  1948. wpa_hexdump_buf(MSG_DEBUG,
  1949. "DPP: Configuration Request frame attributes", msg);
  1950. wpabuf_free(clear);
  1951. return msg;
  1952. fail:
  1953. wpabuf_free(clear);
  1954. wpabuf_free(msg);
  1955. return NULL;
  1956. }
  1957. static void dpp_auth_success(struct dpp_authentication *auth)
  1958. {
  1959. wpa_printf(MSG_DEBUG,
  1960. "DPP: Authentication success - clear temporary keys");
  1961. os_memset(auth->Mx, 0, sizeof(auth->Mx));
  1962. os_memset(auth->Nx, 0, sizeof(auth->Nx));
  1963. os_memset(auth->Lx, 0, sizeof(auth->Lx));
  1964. os_memset(auth->k1, 0, sizeof(auth->k1));
  1965. os_memset(auth->k2, 0, sizeof(auth->k2));
  1966. auth->auth_success = 1;
  1967. }
  1968. static int dpp_gen_r_auth(struct dpp_authentication *auth, u8 *r_auth)
  1969. {
  1970. struct wpabuf *pix, *prx, *bix, *brx;
  1971. const u8 *addr[7];
  1972. size_t len[7];
  1973. size_t i, num_elem = 0;
  1974. size_t nonce_len;
  1975. u8 zero = 0;
  1976. int res = -1;
  1977. /* R-auth = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */
  1978. nonce_len = auth->curve->nonce_len;
  1979. if (auth->initiator) {
  1980. pix = dpp_get_pubkey_point(auth->own_protocol_key, 0);
  1981. prx = dpp_get_pubkey_point(auth->peer_protocol_key, 0);
  1982. if (auth->own_bi)
  1983. bix = dpp_get_pubkey_point(auth->own_bi->pubkey, 0);
  1984. else
  1985. bix = NULL;
  1986. brx = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0);
  1987. } else {
  1988. pix = dpp_get_pubkey_point(auth->peer_protocol_key, 0);
  1989. prx = dpp_get_pubkey_point(auth->own_protocol_key, 0);
  1990. if (auth->peer_bi)
  1991. bix = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0);
  1992. else
  1993. bix = NULL;
  1994. brx = dpp_get_pubkey_point(auth->own_bi->pubkey, 0);
  1995. }
  1996. if (!pix || !prx || !brx)
  1997. goto fail;
  1998. addr[num_elem] = auth->i_nonce;
  1999. len[num_elem] = nonce_len;
  2000. num_elem++;
  2001. addr[num_elem] = auth->r_nonce;
  2002. len[num_elem] = nonce_len;
  2003. num_elem++;
  2004. addr[num_elem] = wpabuf_head(pix);
  2005. len[num_elem] = wpabuf_len(pix) / 2;
  2006. num_elem++;
  2007. addr[num_elem] = wpabuf_head(prx);
  2008. len[num_elem] = wpabuf_len(prx) / 2;
  2009. num_elem++;
  2010. if (bix) {
  2011. addr[num_elem] = wpabuf_head(bix);
  2012. len[num_elem] = wpabuf_len(bix) / 2;
  2013. num_elem++;
  2014. }
  2015. addr[num_elem] = wpabuf_head(brx);
  2016. len[num_elem] = wpabuf_len(brx) / 2;
  2017. num_elem++;
  2018. addr[num_elem] = &zero;
  2019. len[num_elem] = 1;
  2020. num_elem++;
  2021. wpa_printf(MSG_DEBUG, "DPP: R-auth hash components");
  2022. for (i = 0; i < num_elem; i++)
  2023. wpa_hexdump(MSG_DEBUG, "DPP: hash component", addr[i], len[i]);
  2024. res = dpp_hash_vector(auth->curve, num_elem, addr, len, r_auth);
  2025. if (res == 0)
  2026. wpa_hexdump(MSG_DEBUG, "DPP: R-auth", r_auth,
  2027. auth->curve->hash_len);
  2028. fail:
  2029. wpabuf_free(pix);
  2030. wpabuf_free(prx);
  2031. wpabuf_free(bix);
  2032. wpabuf_free(brx);
  2033. return res;
  2034. }
  2035. static int dpp_gen_i_auth(struct dpp_authentication *auth, u8 *i_auth)
  2036. {
  2037. struct wpabuf *pix = NULL, *prx = NULL, *bix = NULL, *brx = NULL;
  2038. const u8 *addr[7];
  2039. size_t len[7];
  2040. size_t i, num_elem = 0;
  2041. size_t nonce_len;
  2042. u8 one = 1;
  2043. int res = -1;
  2044. /* I-auth = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |] 1) */
  2045. nonce_len = auth->curve->nonce_len;
  2046. if (auth->initiator) {
  2047. pix = dpp_get_pubkey_point(auth->own_protocol_key, 0);
  2048. prx = dpp_get_pubkey_point(auth->peer_protocol_key, 0);
  2049. if (auth->own_bi)
  2050. bix = dpp_get_pubkey_point(auth->own_bi->pubkey, 0);
  2051. else
  2052. bix = NULL;
  2053. if (!auth->peer_bi)
  2054. goto fail;
  2055. brx = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0);
  2056. } else {
  2057. pix = dpp_get_pubkey_point(auth->peer_protocol_key, 0);
  2058. prx = dpp_get_pubkey_point(auth->own_protocol_key, 0);
  2059. if (auth->peer_bi)
  2060. bix = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0);
  2061. else
  2062. bix = NULL;
  2063. if (!auth->own_bi)
  2064. goto fail;
  2065. brx = dpp_get_pubkey_point(auth->own_bi->pubkey, 0);
  2066. }
  2067. if (!pix || !prx || !brx)
  2068. goto fail;
  2069. addr[num_elem] = auth->r_nonce;
  2070. len[num_elem] = nonce_len;
  2071. num_elem++;
  2072. addr[num_elem] = auth->i_nonce;
  2073. len[num_elem] = nonce_len;
  2074. num_elem++;
  2075. addr[num_elem] = wpabuf_head(prx);
  2076. len[num_elem] = wpabuf_len(prx) / 2;
  2077. num_elem++;
  2078. addr[num_elem] = wpabuf_head(pix);
  2079. len[num_elem] = wpabuf_len(pix) / 2;
  2080. num_elem++;
  2081. addr[num_elem] = wpabuf_head(brx);
  2082. len[num_elem] = wpabuf_len(brx) / 2;
  2083. num_elem++;
  2084. if (bix) {
  2085. addr[num_elem] = wpabuf_head(bix);
  2086. len[num_elem] = wpabuf_len(bix) / 2;
  2087. num_elem++;
  2088. }
  2089. addr[num_elem] = &one;
  2090. len[num_elem] = 1;
  2091. num_elem++;
  2092. wpa_printf(MSG_DEBUG, "DPP: I-auth hash components");
  2093. for (i = 0; i < num_elem; i++)
  2094. wpa_hexdump(MSG_DEBUG, "DPP: hash component", addr[i], len[i]);
  2095. res = dpp_hash_vector(auth->curve, num_elem, addr, len, i_auth);
  2096. if (res == 0)
  2097. wpa_hexdump(MSG_DEBUG, "DPP: I-auth", i_auth,
  2098. auth->curve->hash_len);
  2099. fail:
  2100. wpabuf_free(pix);
  2101. wpabuf_free(prx);
  2102. wpabuf_free(bix);
  2103. wpabuf_free(brx);
  2104. return res;
  2105. }
  2106. static int dpp_auth_derive_l_responder(struct dpp_authentication *auth)
  2107. {
  2108. const EC_GROUP *group;
  2109. EC_POINT *l = NULL;
  2110. EC_KEY *BI = NULL, *bR = NULL, *pR = NULL;
  2111. const EC_POINT *BI_point;
  2112. BN_CTX *bnctx;
  2113. BIGNUM *lx, *sum, *q;
  2114. const BIGNUM *bR_bn, *pR_bn;
  2115. int ret = -1;
  2116. /* L = ((bR + pR) modulo q) * BI */
  2117. bnctx = BN_CTX_new();
  2118. sum = BN_new();
  2119. q = BN_new();
  2120. lx = BN_new();
  2121. if (!bnctx || !sum || !q || !lx)
  2122. goto fail;
  2123. BI = EVP_PKEY_get1_EC_KEY(auth->peer_bi->pubkey);
  2124. if (!BI)
  2125. goto fail;
  2126. BI_point = EC_KEY_get0_public_key(BI);
  2127. group = EC_KEY_get0_group(BI);
  2128. if (!group)
  2129. goto fail;
  2130. bR = EVP_PKEY_get1_EC_KEY(auth->own_bi->pubkey);
  2131. pR = EVP_PKEY_get1_EC_KEY(auth->own_protocol_key);
  2132. if (!bR || !pR)
  2133. goto fail;
  2134. bR_bn = EC_KEY_get0_private_key(bR);
  2135. pR_bn = EC_KEY_get0_private_key(pR);
  2136. if (!bR_bn || !pR_bn)
  2137. goto fail;
  2138. if (EC_GROUP_get_order(group, q, bnctx) != 1 ||
  2139. BN_mod_add(sum, bR_bn, pR_bn, q, bnctx) != 1)
  2140. goto fail;
  2141. l = EC_POINT_new(group);
  2142. if (!l ||
  2143. EC_POINT_mul(group, l, NULL, BI_point, sum, bnctx) != 1 ||
  2144. EC_POINT_get_affine_coordinates_GFp(group, l, lx, NULL,
  2145. bnctx) != 1) {
  2146. wpa_printf(MSG_ERROR,
  2147. "OpenSSL: failed: %s",
  2148. ERR_error_string(ERR_get_error(), NULL));
  2149. goto fail;
  2150. }
  2151. if (dpp_bn2bin_pad(lx, auth->Lx, auth->secret_len) < 0)
  2152. goto fail;
  2153. wpa_hexdump_key(MSG_DEBUG, "DPP: L.x", auth->Lx, auth->secret_len);
  2154. ret = 0;
  2155. fail:
  2156. EC_POINT_clear_free(l);
  2157. EC_KEY_free(BI);
  2158. EC_KEY_free(bR);
  2159. EC_KEY_free(pR);
  2160. BN_clear_free(lx);
  2161. BN_clear_free(sum);
  2162. BN_free(q);
  2163. BN_CTX_free(bnctx);
  2164. return ret;
  2165. }
  2166. static int dpp_auth_derive_l_initiator(struct dpp_authentication *auth)
  2167. {
  2168. const EC_GROUP *group;
  2169. EC_POINT *l = NULL, *sum = NULL;
  2170. EC_KEY *bI = NULL, *BR = NULL, *PR = NULL;
  2171. const EC_POINT *BR_point, *PR_point;
  2172. BN_CTX *bnctx;
  2173. BIGNUM *lx;
  2174. const BIGNUM *bI_bn;
  2175. int ret = -1;
  2176. /* L = bI * (BR + PR) */
  2177. bnctx = BN_CTX_new();
  2178. lx = BN_new();
  2179. if (!bnctx || !lx)
  2180. goto fail;
  2181. BR = EVP_PKEY_get1_EC_KEY(auth->peer_bi->pubkey);
  2182. PR = EVP_PKEY_get1_EC_KEY(auth->peer_protocol_key);
  2183. if (!BR || !PR)
  2184. goto fail;
  2185. BR_point = EC_KEY_get0_public_key(BR);
  2186. PR_point = EC_KEY_get0_public_key(PR);
  2187. bI = EVP_PKEY_get1_EC_KEY(auth->own_bi->pubkey);
  2188. if (!bI)
  2189. goto fail;
  2190. group = EC_KEY_get0_group(bI);
  2191. bI_bn = EC_KEY_get0_private_key(bI);
  2192. if (!group || !bI_bn)
  2193. goto fail;
  2194. sum = EC_POINT_new(group);
  2195. l = EC_POINT_new(group);
  2196. if (!sum || !l ||
  2197. EC_POINT_add(group, sum, BR_point, PR_point, bnctx) != 1 ||
  2198. EC_POINT_mul(group, l, NULL, sum, bI_bn, bnctx) != 1 ||
  2199. EC_POINT_get_affine_coordinates_GFp(group, l, lx, NULL,
  2200. bnctx) != 1) {
  2201. wpa_printf(MSG_ERROR,
  2202. "OpenSSL: failed: %s",
  2203. ERR_error_string(ERR_get_error(), NULL));
  2204. goto fail;
  2205. }
  2206. if (dpp_bn2bin_pad(lx, auth->Lx, auth->secret_len) < 0)
  2207. goto fail;
  2208. wpa_hexdump_key(MSG_DEBUG, "DPP: L.x", auth->Lx, auth->secret_len);
  2209. ret = 0;
  2210. fail:
  2211. EC_POINT_clear_free(l);
  2212. EC_KEY_free(bI);
  2213. EC_KEY_free(BR);
  2214. EC_KEY_free(PR);
  2215. BN_clear_free(lx);
  2216. BN_CTX_free(bnctx);
  2217. return ret;
  2218. }
  2219. static int dpp_auth_build_resp_ok(struct dpp_authentication *auth)
  2220. {
  2221. size_t nonce_len;
  2222. EVP_PKEY_CTX *ctx = NULL;
  2223. size_t secret_len;
  2224. struct wpabuf *msg, *pr = NULL;
  2225. u8 r_auth[4 + DPP_MAX_HASH_LEN];
  2226. u8 wrapped_r_auth[4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE], *w_r_auth;
  2227. size_t wrapped_r_auth_len;
  2228. int ret = -1;
  2229. const u8 *r_pubkey_hash, *i_pubkey_hash, *r_nonce, *i_nonce;
  2230. enum dpp_status_error status = DPP_STATUS_OK;
  2231. #ifdef CONFIG_TESTING_OPTIONS
  2232. u8 test_hash[SHA256_MAC_LEN];
  2233. #endif /* CONFIG_TESTING_OPTIONS */
  2234. wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
  2235. if (!auth->own_bi)
  2236. return -1;
  2237. nonce_len = auth->curve->nonce_len;
  2238. if (random_get_bytes(auth->r_nonce, nonce_len)) {
  2239. wpa_printf(MSG_ERROR, "DPP: Failed to generate R-nonce");
  2240. goto fail;
  2241. }
  2242. wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", auth->r_nonce, nonce_len);
  2243. auth->own_protocol_key = dpp_gen_keypair(auth->curve);
  2244. if (!auth->own_protocol_key)
  2245. goto fail;
  2246. pr = dpp_get_pubkey_point(auth->own_protocol_key, 0);
  2247. if (!pr)
  2248. goto fail;
  2249. /* ECDH: N = pR * PI */
  2250. ctx = EVP_PKEY_CTX_new(auth->own_protocol_key, NULL);
  2251. if (!ctx ||
  2252. EVP_PKEY_derive_init(ctx) != 1 ||
  2253. EVP_PKEY_derive_set_peer(ctx, auth->peer_protocol_key) != 1 ||
  2254. EVP_PKEY_derive(ctx, NULL, &secret_len) != 1 ||
  2255. secret_len > DPP_MAX_SHARED_SECRET_LEN ||
  2256. EVP_PKEY_derive(ctx, auth->Nx, &secret_len) != 1) {
  2257. wpa_printf(MSG_ERROR,
  2258. "DPP: Failed to derive ECDH shared secret: %s",
  2259. ERR_error_string(ERR_get_error(), NULL));
  2260. goto fail;
  2261. }
  2262. EVP_PKEY_CTX_free(ctx);
  2263. ctx = NULL;
  2264. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)",
  2265. auth->Nx, auth->secret_len);
  2266. if (dpp_derive_k2(auth->Nx, auth->secret_len, auth->k2,
  2267. auth->curve->hash_len) < 0)
  2268. goto fail;
  2269. if (auth->own_bi && auth->peer_bi) {
  2270. /* Mutual authentication */
  2271. if (dpp_auth_derive_l_responder(auth) < 0)
  2272. goto fail;
  2273. }
  2274. if (dpp_derive_ke(auth, auth->ke, auth->curve->hash_len) < 0)
  2275. goto fail;
  2276. /* R-auth = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */
  2277. WPA_PUT_LE16(r_auth, DPP_ATTR_R_AUTH_TAG);
  2278. WPA_PUT_LE16(&r_auth[2], auth->curve->hash_len);
  2279. if (dpp_gen_r_auth(auth, r_auth + 4) < 0)
  2280. goto fail;
  2281. #ifdef CONFIG_TESTING_OPTIONS
  2282. if (dpp_test == DPP_TEST_R_AUTH_MISMATCH_AUTH_RESP) {
  2283. wpa_printf(MSG_INFO, "DPP: TESTING - R-auth mismatch");
  2284. r_auth[4 + auth->curve->hash_len / 2] ^= 0x01;
  2285. }
  2286. #endif /* CONFIG_TESTING_OPTIONS */
  2287. if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
  2288. r_auth, 4 + auth->curve->hash_len,
  2289. 0, NULL, NULL, wrapped_r_auth) < 0)
  2290. goto fail;
  2291. wrapped_r_auth_len = 4 + auth->curve->hash_len + AES_BLOCK_SIZE;
  2292. wpa_hexdump(MSG_DEBUG, "DPP: {R-auth}ke",
  2293. wrapped_r_auth, wrapped_r_auth_len);
  2294. w_r_auth = wrapped_r_auth;
  2295. r_pubkey_hash = auth->own_bi->pubkey_hash;
  2296. if (auth->peer_bi)
  2297. i_pubkey_hash = auth->peer_bi->pubkey_hash;
  2298. else
  2299. i_pubkey_hash = NULL;
  2300. i_nonce = auth->i_nonce;
  2301. r_nonce = auth->r_nonce;
  2302. #ifdef CONFIG_TESTING_OPTIONS
  2303. if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
  2304. wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
  2305. r_pubkey_hash = NULL;
  2306. } else if (dpp_test ==
  2307. DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
  2308. wpa_printf(MSG_INFO,
  2309. "DPP: TESTING - invalid R-Bootstrap Key Hash");
  2310. os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
  2311. test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
  2312. r_pubkey_hash = test_hash;
  2313. } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
  2314. wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
  2315. i_pubkey_hash = NULL;
  2316. } else if (dpp_test ==
  2317. DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
  2318. wpa_printf(MSG_INFO,
  2319. "DPP: TESTING - invalid I-Bootstrap Key Hash");
  2320. if (i_pubkey_hash)
  2321. os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
  2322. else
  2323. os_memset(test_hash, 0, SHA256_MAC_LEN);
  2324. test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
  2325. i_pubkey_hash = test_hash;
  2326. } else if (dpp_test == DPP_TEST_NO_R_PROTO_KEY_AUTH_RESP) {
  2327. wpa_printf(MSG_INFO, "DPP: TESTING - no R-Proto Key");
  2328. wpabuf_free(pr);
  2329. pr = NULL;
  2330. } else if (dpp_test == DPP_TEST_INVALID_R_PROTO_KEY_AUTH_RESP) {
  2331. wpa_printf(MSG_INFO, "DPP: TESTING - invalid R-Proto Key");
  2332. wpabuf_free(pr);
  2333. pr = wpabuf_alloc(2 * auth->curve->prime_len);
  2334. if (!pr || dpp_test_gen_invalid_key(pr, auth->curve) < 0)
  2335. goto fail;
  2336. } else if (dpp_test == DPP_TEST_NO_R_AUTH_AUTH_RESP) {
  2337. wpa_printf(MSG_INFO, "DPP: TESTING - no R-Auth");
  2338. w_r_auth = NULL;
  2339. wrapped_r_auth_len = 0;
  2340. } else if (dpp_test == DPP_TEST_NO_STATUS_AUTH_RESP) {
  2341. wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
  2342. status = 255;
  2343. } else if (dpp_test == DPP_TEST_INVALID_STATUS_AUTH_RESP) {
  2344. wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
  2345. status = 254;
  2346. } else if (dpp_test == DPP_TEST_NO_R_NONCE_AUTH_RESP) {
  2347. wpa_printf(MSG_INFO, "DPP: TESTING - no R-nonce");
  2348. r_nonce = NULL;
  2349. } else if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_RESP) {
  2350. wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce");
  2351. i_nonce = NULL;
  2352. }
  2353. #endif /* CONFIG_TESTING_OPTIONS */
  2354. msg = dpp_auth_build_resp(auth, status, pr, nonce_len,
  2355. r_pubkey_hash, i_pubkey_hash,
  2356. r_nonce, i_nonce,
  2357. w_r_auth, wrapped_r_auth_len,
  2358. auth->k2);
  2359. if (!msg)
  2360. goto fail;
  2361. wpabuf_free(auth->resp_msg);
  2362. auth->resp_msg = msg;
  2363. ret = 0;
  2364. fail:
  2365. wpabuf_free(pr);
  2366. return ret;
  2367. }
  2368. static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
  2369. enum dpp_status_error status)
  2370. {
  2371. struct wpabuf *msg;
  2372. const u8 *r_pubkey_hash, *i_pubkey_hash, *i_nonce;
  2373. #ifdef CONFIG_TESTING_OPTIONS
  2374. u8 test_hash[SHA256_MAC_LEN];
  2375. #endif /* CONFIG_TESTING_OPTIONS */
  2376. if (!auth->own_bi)
  2377. return -1;
  2378. wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
  2379. r_pubkey_hash = auth->own_bi->pubkey_hash;
  2380. if (auth->peer_bi)
  2381. i_pubkey_hash = auth->peer_bi->pubkey_hash;
  2382. else
  2383. i_pubkey_hash = NULL;
  2384. i_nonce = auth->i_nonce;
  2385. #ifdef CONFIG_TESTING_OPTIONS
  2386. if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
  2387. wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
  2388. r_pubkey_hash = NULL;
  2389. } else if (dpp_test ==
  2390. DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
  2391. wpa_printf(MSG_INFO,
  2392. "DPP: TESTING - invalid R-Bootstrap Key Hash");
  2393. os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
  2394. test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
  2395. r_pubkey_hash = test_hash;
  2396. } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
  2397. wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
  2398. i_pubkey_hash = NULL;
  2399. } else if (dpp_test ==
  2400. DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
  2401. wpa_printf(MSG_INFO,
  2402. "DPP: TESTING - invalid I-Bootstrap Key Hash");
  2403. if (i_pubkey_hash)
  2404. os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
  2405. else
  2406. os_memset(test_hash, 0, SHA256_MAC_LEN);
  2407. test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
  2408. i_pubkey_hash = test_hash;
  2409. } else if (dpp_test == DPP_TEST_NO_STATUS_AUTH_RESP) {
  2410. wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
  2411. status = -1;
  2412. } else if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_RESP) {
  2413. wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce");
  2414. i_nonce = NULL;
  2415. }
  2416. #endif /* CONFIG_TESTING_OPTIONS */
  2417. msg = dpp_auth_build_resp(auth, status, NULL, auth->curve->nonce_len,
  2418. r_pubkey_hash, i_pubkey_hash,
  2419. NULL, i_nonce, NULL, 0, auth->k1);
  2420. if (!msg)
  2421. return -1;
  2422. wpabuf_free(auth->resp_msg);
  2423. auth->resp_msg = msg;
  2424. return 0;
  2425. }
  2426. struct dpp_authentication *
  2427. dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
  2428. struct dpp_bootstrap_info *peer_bi,
  2429. struct dpp_bootstrap_info *own_bi,
  2430. unsigned int freq, const u8 *hdr, const u8 *attr_start,
  2431. size_t attr_len)
  2432. {
  2433. EVP_PKEY *pi = NULL;
  2434. EVP_PKEY_CTX *ctx = NULL;
  2435. size_t secret_len;
  2436. const u8 *addr[2];
  2437. size_t len[2];
  2438. u8 *unwrapped = NULL;
  2439. size_t unwrapped_len = 0;
  2440. const u8 *wrapped_data, *i_proto, *i_nonce, *i_capab, *i_bootstrap,
  2441. *channel;
  2442. u16 wrapped_data_len, i_proto_len, i_nonce_len, i_capab_len,
  2443. i_bootstrap_len, channel_len;
  2444. struct dpp_authentication *auth = NULL;
  2445. wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
  2446. &wrapped_data_len);
  2447. if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
  2448. wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
  2449. "Missing or invalid required Wrapped Data attribute");
  2450. return NULL;
  2451. }
  2452. wpa_hexdump(MSG_MSGDUMP, "DPP: Wrapped Data",
  2453. wrapped_data, wrapped_data_len);
  2454. attr_len = wrapped_data - 4 - attr_start;
  2455. auth = os_zalloc(sizeof(*auth));
  2456. if (!auth)
  2457. goto fail;
  2458. auth->msg_ctx = msg_ctx;
  2459. auth->peer_bi = peer_bi;
  2460. auth->own_bi = own_bi;
  2461. auth->curve = own_bi->curve;
  2462. auth->curr_freq = freq;
  2463. channel = dpp_get_attr(attr_start, attr_len, DPP_ATTR_CHANNEL,
  2464. &channel_len);
  2465. if (channel) {
  2466. int neg_freq;
  2467. if (channel_len < 2) {
  2468. dpp_auth_fail(auth, "Too short Channel attribute");
  2469. goto fail;
  2470. }
  2471. neg_freq = ieee80211_chan_to_freq(NULL, channel[0], channel[1]);
  2472. wpa_printf(MSG_DEBUG,
  2473. "DPP: Initiator requested different channel for negotiation: op_class=%u channel=%u --> freq=%d",
  2474. channel[0], channel[1], neg_freq);
  2475. if (neg_freq < 0) {
  2476. dpp_auth_fail(auth,
  2477. "Unsupported Channel attribute value");
  2478. goto fail;
  2479. }
  2480. if (auth->curr_freq != (unsigned int) neg_freq) {
  2481. wpa_printf(MSG_DEBUG,
  2482. "DPP: Changing negotiation channel from %u MHz to %u MHz",
  2483. freq, neg_freq);
  2484. auth->curr_freq = neg_freq;
  2485. }
  2486. }
  2487. i_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_I_PROTOCOL_KEY,
  2488. &i_proto_len);
  2489. if (!i_proto) {
  2490. dpp_auth_fail(auth,
  2491. "Missing required Initiator Protocol Key attribute");
  2492. goto fail;
  2493. }
  2494. wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Protocol Key",
  2495. i_proto, i_proto_len);
  2496. /* M = bR * PI */
  2497. pi = dpp_set_pubkey_point(own_bi->pubkey, i_proto, i_proto_len);
  2498. if (!pi) {
  2499. dpp_auth_fail(auth, "Invalid Initiator Protocol Key");
  2500. goto fail;
  2501. }
  2502. dpp_debug_print_key("Peer (Initiator) Protocol Key", pi);
  2503. ctx = EVP_PKEY_CTX_new(own_bi->pubkey, NULL);
  2504. if (!ctx ||
  2505. EVP_PKEY_derive_init(ctx) != 1 ||
  2506. EVP_PKEY_derive_set_peer(ctx, pi) != 1 ||
  2507. EVP_PKEY_derive(ctx, NULL, &secret_len) != 1 ||
  2508. secret_len > DPP_MAX_SHARED_SECRET_LEN ||
  2509. EVP_PKEY_derive(ctx, auth->Mx, &secret_len) != 1) {
  2510. wpa_printf(MSG_ERROR,
  2511. "DPP: Failed to derive ECDH shared secret: %s",
  2512. ERR_error_string(ERR_get_error(), NULL));
  2513. dpp_auth_fail(auth, "Failed to derive ECDH shared secret");
  2514. goto fail;
  2515. }
  2516. auth->secret_len = secret_len;
  2517. EVP_PKEY_CTX_free(ctx);
  2518. ctx = NULL;
  2519. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)",
  2520. auth->Mx, auth->secret_len);
  2521. if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1,
  2522. auth->curve->hash_len) < 0)
  2523. goto fail;
  2524. addr[0] = hdr;
  2525. len[0] = DPP_HDR_LEN;
  2526. addr[1] = attr_start;
  2527. len[1] = attr_len;
  2528. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  2529. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  2530. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  2531. wrapped_data, wrapped_data_len);
  2532. unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
  2533. unwrapped = os_malloc(unwrapped_len);
  2534. if (!unwrapped)
  2535. goto fail;
  2536. if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
  2537. wrapped_data, wrapped_data_len,
  2538. 2, addr, len, unwrapped) < 0) {
  2539. dpp_auth_fail(auth, "AES-SIV decryption failed");
  2540. goto fail;
  2541. }
  2542. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
  2543. unwrapped, unwrapped_len);
  2544. if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
  2545. dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
  2546. goto fail;
  2547. }
  2548. i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
  2549. &i_nonce_len);
  2550. if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
  2551. dpp_auth_fail(auth, "Missing or invalid I-nonce");
  2552. goto fail;
  2553. }
  2554. wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
  2555. os_memcpy(auth->i_nonce, i_nonce, i_nonce_len);
  2556. i_capab = dpp_get_attr(unwrapped, unwrapped_len,
  2557. DPP_ATTR_I_CAPABILITIES,
  2558. &i_capab_len);
  2559. if (!i_capab || i_capab_len < 1) {
  2560. dpp_auth_fail(auth, "Missing or invalid I-capabilities");
  2561. goto fail;
  2562. }
  2563. auth->i_capab = i_capab[0];
  2564. wpa_printf(MSG_DEBUG, "DPP: I-capabilities: 0x%02x", auth->i_capab);
  2565. bin_clear_free(unwrapped, unwrapped_len);
  2566. unwrapped = NULL;
  2567. switch (auth->i_capab & DPP_CAPAB_ROLE_MASK) {
  2568. case DPP_CAPAB_ENROLLEE:
  2569. if (!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR)) {
  2570. wpa_printf(MSG_DEBUG,
  2571. "DPP: Local policy does not allow Configurator role");
  2572. goto not_compatible;
  2573. }
  2574. wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator");
  2575. auth->configurator = 1;
  2576. break;
  2577. case DPP_CAPAB_CONFIGURATOR:
  2578. if (!(dpp_allowed_roles & DPP_CAPAB_ENROLLEE)) {
  2579. wpa_printf(MSG_DEBUG,
  2580. "DPP: Local policy does not allow Enrollee role");
  2581. goto not_compatible;
  2582. }
  2583. wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee");
  2584. auth->configurator = 0;
  2585. break;
  2586. case DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE:
  2587. if (dpp_allowed_roles & DPP_CAPAB_ENROLLEE) {
  2588. wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee");
  2589. auth->configurator = 0;
  2590. } else if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR) {
  2591. wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator");
  2592. auth->configurator = 1;
  2593. } else {
  2594. wpa_printf(MSG_DEBUG,
  2595. "DPP: Local policy does not allow Configurator/Enrollee role");
  2596. goto not_compatible;
  2597. }
  2598. break;
  2599. default:
  2600. wpa_printf(MSG_DEBUG, "DPP: Unexpected role in I-capabilities");
  2601. wpa_msg(auth->msg_ctx, MSG_INFO,
  2602. DPP_EVENT_FAIL "Invalid role in I-capabilities 0x%02x",
  2603. auth->i_capab & DPP_CAPAB_ROLE_MASK);
  2604. goto fail;
  2605. }
  2606. auth->peer_protocol_key = pi;
  2607. pi = NULL;
  2608. if (qr_mutual && !peer_bi && own_bi->type == DPP_BOOTSTRAP_QR_CODE) {
  2609. char hex[SHA256_MAC_LEN * 2 + 1];
  2610. wpa_printf(MSG_DEBUG,
  2611. "DPP: Mutual authentication required with QR Codes, but peer info is not yet available - request more time");
  2612. if (dpp_auth_build_resp_status(auth,
  2613. DPP_STATUS_RESPONSE_PENDING) < 0)
  2614. goto fail;
  2615. i_bootstrap = dpp_get_attr(attr_start, attr_len,
  2616. DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
  2617. &i_bootstrap_len);
  2618. if (i_bootstrap && i_bootstrap_len == SHA256_MAC_LEN) {
  2619. auth->response_pending = 1;
  2620. os_memcpy(auth->waiting_pubkey_hash,
  2621. i_bootstrap, i_bootstrap_len);
  2622. wpa_snprintf_hex(hex, sizeof(hex), i_bootstrap,
  2623. i_bootstrap_len);
  2624. } else {
  2625. hex[0] = '\0';
  2626. }
  2627. wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_SCAN_PEER_QR_CODE
  2628. "%s", hex);
  2629. return auth;
  2630. }
  2631. if (dpp_auth_build_resp_ok(auth) < 0)
  2632. goto fail;
  2633. return auth;
  2634. not_compatible:
  2635. wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE
  2636. "i-capab=0x%02x", auth->i_capab);
  2637. if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR)
  2638. auth->configurator = 1;
  2639. else
  2640. auth->configurator = 0;
  2641. auth->peer_protocol_key = pi;
  2642. pi = NULL;
  2643. if (dpp_auth_build_resp_status(auth, DPP_STATUS_NOT_COMPATIBLE) < 0)
  2644. goto fail;
  2645. auth->remove_on_tx_status = 1;
  2646. return auth;
  2647. fail:
  2648. bin_clear_free(unwrapped, unwrapped_len);
  2649. EVP_PKEY_free(pi);
  2650. EVP_PKEY_CTX_free(ctx);
  2651. dpp_auth_deinit(auth);
  2652. return NULL;
  2653. }
  2654. int dpp_notify_new_qr_code(struct dpp_authentication *auth,
  2655. struct dpp_bootstrap_info *peer_bi)
  2656. {
  2657. if (!auth || !auth->response_pending ||
  2658. os_memcmp(auth->waiting_pubkey_hash, peer_bi->pubkey_hash,
  2659. SHA256_MAC_LEN) != 0)
  2660. return 0;
  2661. wpa_printf(MSG_DEBUG,
  2662. "DPP: New scanned QR Code has matching public key that was needed to continue DPP Authentication exchange with "
  2663. MACSTR, MAC2STR(auth->peer_mac_addr));
  2664. auth->peer_bi = peer_bi;
  2665. if (dpp_auth_build_resp_ok(auth) < 0)
  2666. return -1;
  2667. return 1;
  2668. }
  2669. static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth,
  2670. enum dpp_status_error status)
  2671. {
  2672. struct wpabuf *msg;
  2673. u8 i_auth[4 + DPP_MAX_HASH_LEN];
  2674. size_t i_auth_len;
  2675. u8 r_nonce[4 + DPP_MAX_NONCE_LEN];
  2676. size_t r_nonce_len;
  2677. const u8 *addr[2];
  2678. size_t len[2], attr_len;
  2679. u8 *wrapped_i_auth;
  2680. u8 *wrapped_r_nonce;
  2681. u8 *attr_start, *attr_end;
  2682. const u8 *r_pubkey_hash, *i_pubkey_hash;
  2683. #ifdef CONFIG_TESTING_OPTIONS
  2684. u8 test_hash[SHA256_MAC_LEN];
  2685. #endif /* CONFIG_TESTING_OPTIONS */
  2686. wpa_printf(MSG_DEBUG, "DPP: Build Authentication Confirmation");
  2687. i_auth_len = 4 + auth->curve->hash_len;
  2688. r_nonce_len = 4 + auth->curve->nonce_len;
  2689. /* Build DPP Authentication Confirmation frame attributes */
  2690. attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
  2691. 4 + i_auth_len + r_nonce_len + AES_BLOCK_SIZE;
  2692. #ifdef CONFIG_TESTING_OPTIONS
  2693. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF)
  2694. attr_len += 5;
  2695. #endif /* CONFIG_TESTING_OPTIONS */
  2696. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, attr_len);
  2697. if (!msg)
  2698. goto fail;
  2699. attr_start = wpabuf_put(msg, 0);
  2700. r_pubkey_hash = auth->peer_bi->pubkey_hash;
  2701. if (auth->own_bi)
  2702. i_pubkey_hash = auth->own_bi->pubkey_hash;
  2703. else
  2704. i_pubkey_hash = NULL;
  2705. #ifdef CONFIG_TESTING_OPTIONS
  2706. if (dpp_test == DPP_TEST_NO_STATUS_AUTH_CONF) {
  2707. wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
  2708. goto skip_status;
  2709. } else if (dpp_test == DPP_TEST_INVALID_STATUS_AUTH_CONF) {
  2710. wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
  2711. status = 254;
  2712. }
  2713. #endif /* CONFIG_TESTING_OPTIONS */
  2714. /* DPP Status */
  2715. dpp_build_attr_status(msg, status);
  2716. #ifdef CONFIG_TESTING_OPTIONS
  2717. skip_status:
  2718. if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
  2719. wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
  2720. r_pubkey_hash = NULL;
  2721. } else if (dpp_test ==
  2722. DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
  2723. wpa_printf(MSG_INFO,
  2724. "DPP: TESTING - invalid R-Bootstrap Key Hash");
  2725. os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
  2726. test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
  2727. r_pubkey_hash = test_hash;
  2728. } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
  2729. wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
  2730. i_pubkey_hash = NULL;
  2731. } else if (dpp_test ==
  2732. DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
  2733. wpa_printf(MSG_INFO,
  2734. "DPP: TESTING - invalid I-Bootstrap Key Hash");
  2735. if (i_pubkey_hash)
  2736. os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
  2737. else
  2738. os_memset(test_hash, 0, SHA256_MAC_LEN);
  2739. test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
  2740. i_pubkey_hash = test_hash;
  2741. }
  2742. #endif /* CONFIG_TESTING_OPTIONS */
  2743. /* Responder Bootstrapping Key Hash */
  2744. dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash);
  2745. /* Initiator Bootstrapping Key Hash (mutual authentication) */
  2746. dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash);
  2747. #ifdef CONFIG_TESTING_OPTIONS
  2748. if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_CONF)
  2749. goto skip_wrapped_data;
  2750. if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF)
  2751. i_auth_len = 0;
  2752. #endif /* CONFIG_TESTING_OPTIONS */
  2753. attr_end = wpabuf_put(msg, 0);
  2754. /* OUI, OUI type, Crypto Suite, DPP frame type */
  2755. addr[0] = wpabuf_head_u8(msg) + 2;
  2756. len[0] = 3 + 1 + 1 + 1;
  2757. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  2758. /* Attributes before Wrapped Data */
  2759. addr[1] = attr_start;
  2760. len[1] = attr_end - attr_start;
  2761. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  2762. if (status == DPP_STATUS_OK) {
  2763. /* I-auth wrapped with ke */
  2764. wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
  2765. wpabuf_put_le16(msg, i_auth_len + AES_BLOCK_SIZE);
  2766. wrapped_i_auth = wpabuf_put(msg, i_auth_len + AES_BLOCK_SIZE);
  2767. #ifdef CONFIG_TESTING_OPTIONS
  2768. if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF)
  2769. goto skip_i_auth;
  2770. #endif /* CONFIG_TESTING_OPTIONS */
  2771. /* I-auth = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |]
  2772. * 1) */
  2773. WPA_PUT_LE16(i_auth, DPP_ATTR_I_AUTH_TAG);
  2774. WPA_PUT_LE16(&i_auth[2], auth->curve->hash_len);
  2775. if (dpp_gen_i_auth(auth, i_auth + 4) < 0)
  2776. goto fail;
  2777. #ifdef CONFIG_TESTING_OPTIONS
  2778. if (dpp_test == DPP_TEST_I_AUTH_MISMATCH_AUTH_CONF) {
  2779. wpa_printf(MSG_INFO, "DPP: TESTING - I-auth mismatch");
  2780. i_auth[4 + auth->curve->hash_len / 2] ^= 0x01;
  2781. }
  2782. skip_i_auth:
  2783. #endif /* CONFIG_TESTING_OPTIONS */
  2784. if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
  2785. i_auth, i_auth_len,
  2786. 2, addr, len, wrapped_i_auth) < 0)
  2787. goto fail;
  2788. wpa_hexdump(MSG_DEBUG, "DPP: {I-auth}ke",
  2789. wrapped_i_auth, i_auth_len + AES_BLOCK_SIZE);
  2790. } else {
  2791. /* R-nonce wrapped with k2 */
  2792. wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
  2793. wpabuf_put_le16(msg, r_nonce_len + AES_BLOCK_SIZE);
  2794. wrapped_r_nonce = wpabuf_put(msg, r_nonce_len + AES_BLOCK_SIZE);
  2795. WPA_PUT_LE16(r_nonce, DPP_ATTR_R_NONCE);
  2796. WPA_PUT_LE16(&r_nonce[2], auth->curve->nonce_len);
  2797. os_memcpy(r_nonce + 4, auth->r_nonce, auth->curve->nonce_len);
  2798. if (aes_siv_encrypt(auth->k2, auth->curve->hash_len,
  2799. r_nonce, r_nonce_len,
  2800. 2, addr, len, wrapped_r_nonce) < 0)
  2801. goto fail;
  2802. wpa_hexdump(MSG_DEBUG, "DPP: {R-nonce}k2",
  2803. wrapped_r_nonce, r_nonce_len + AES_BLOCK_SIZE);
  2804. }
  2805. #ifdef CONFIG_TESTING_OPTIONS
  2806. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF) {
  2807. wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
  2808. dpp_build_attr_status(msg, DPP_STATUS_OK);
  2809. }
  2810. skip_wrapped_data:
  2811. #endif /* CONFIG_TESTING_OPTIONS */
  2812. wpa_hexdump_buf(MSG_DEBUG,
  2813. "DPP: Authentication Confirmation frame attributes",
  2814. msg);
  2815. if (status == DPP_STATUS_OK)
  2816. dpp_auth_success(auth);
  2817. return msg;
  2818. fail:
  2819. wpabuf_free(msg);
  2820. return NULL;
  2821. }
  2822. static void
  2823. dpp_auth_resp_rx_status(struct dpp_authentication *auth, const u8 *hdr,
  2824. const u8 *attr_start, size_t attr_len,
  2825. const u8 *wrapped_data, u16 wrapped_data_len,
  2826. enum dpp_status_error status)
  2827. {
  2828. const u8 *addr[2];
  2829. size_t len[2];
  2830. u8 *unwrapped = NULL;
  2831. size_t unwrapped_len = 0;
  2832. const u8 *i_nonce, *r_capab;
  2833. u16 i_nonce_len, r_capab_len;
  2834. if (status == DPP_STATUS_NOT_COMPATIBLE) {
  2835. wpa_printf(MSG_DEBUG,
  2836. "DPP: Responder reported incompatible roles");
  2837. } else if (status == DPP_STATUS_RESPONSE_PENDING) {
  2838. wpa_printf(MSG_DEBUG,
  2839. "DPP: Responder reported more time needed");
  2840. } else {
  2841. wpa_printf(MSG_DEBUG,
  2842. "DPP: Responder reported failure (status %d)",
  2843. status);
  2844. dpp_auth_fail(auth, "Responder reported failure");
  2845. return;
  2846. }
  2847. addr[0] = hdr;
  2848. len[0] = DPP_HDR_LEN;
  2849. addr[1] = attr_start;
  2850. len[1] = attr_len;
  2851. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  2852. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  2853. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  2854. wrapped_data, wrapped_data_len);
  2855. unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
  2856. unwrapped = os_malloc(unwrapped_len);
  2857. if (!unwrapped)
  2858. goto fail;
  2859. if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
  2860. wrapped_data, wrapped_data_len,
  2861. 2, addr, len, unwrapped) < 0) {
  2862. dpp_auth_fail(auth, "AES-SIV decryption failed");
  2863. goto fail;
  2864. }
  2865. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
  2866. unwrapped, unwrapped_len);
  2867. if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
  2868. dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
  2869. goto fail;
  2870. }
  2871. i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
  2872. &i_nonce_len);
  2873. if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
  2874. dpp_auth_fail(auth, "Missing or invalid I-nonce");
  2875. goto fail;
  2876. }
  2877. wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
  2878. if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) {
  2879. dpp_auth_fail(auth, "I-nonce mismatch");
  2880. goto fail;
  2881. }
  2882. r_capab = dpp_get_attr(unwrapped, unwrapped_len,
  2883. DPP_ATTR_R_CAPABILITIES,
  2884. &r_capab_len);
  2885. if (!r_capab || r_capab_len < 1) {
  2886. dpp_auth_fail(auth, "Missing or invalid R-capabilities");
  2887. goto fail;
  2888. }
  2889. auth->r_capab = r_capab[0];
  2890. wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab);
  2891. if (status == DPP_STATUS_NOT_COMPATIBLE) {
  2892. wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE
  2893. "r-capab=0x%02x", auth->r_capab);
  2894. } else if (status == DPP_STATUS_RESPONSE_PENDING) {
  2895. u8 role = auth->r_capab & DPP_CAPAB_ROLE_MASK;
  2896. if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) ||
  2897. (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) {
  2898. wpa_msg(auth->msg_ctx, MSG_INFO,
  2899. DPP_EVENT_FAIL "Unexpected role in R-capabilities 0x%02x",
  2900. role);
  2901. } else {
  2902. wpa_printf(MSG_DEBUG,
  2903. "DPP: Continue waiting for full DPP Authentication Response");
  2904. wpa_msg(auth->msg_ctx, MSG_INFO,
  2905. DPP_EVENT_RESPONSE_PENDING "%s",
  2906. auth->tmp_own_bi ? auth->tmp_own_bi->uri : "");
  2907. }
  2908. }
  2909. fail:
  2910. bin_clear_free(unwrapped, unwrapped_len);
  2911. }
  2912. struct wpabuf *
  2913. dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
  2914. const u8 *attr_start, size_t attr_len)
  2915. {
  2916. EVP_PKEY *pr;
  2917. EVP_PKEY_CTX *ctx = NULL;
  2918. size_t secret_len;
  2919. const u8 *addr[2];
  2920. size_t len[2];
  2921. u8 *unwrapped = NULL, *unwrapped2 = NULL;
  2922. size_t unwrapped_len = 0, unwrapped2_len = 0;
  2923. const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *r_proto,
  2924. *r_nonce, *i_nonce, *r_capab, *wrapped2, *r_auth;
  2925. u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
  2926. r_proto_len, r_nonce_len, i_nonce_len, r_capab_len,
  2927. wrapped2_len, r_auth_len;
  2928. u8 r_auth2[DPP_MAX_HASH_LEN];
  2929. u8 role;
  2930. if (!auth->initiator) {
  2931. dpp_auth_fail(auth, "Unexpected Authentication Response");
  2932. return NULL;
  2933. }
  2934. auth->waiting_auth_resp = 0;
  2935. wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
  2936. &wrapped_data_len);
  2937. if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
  2938. dpp_auth_fail(auth,
  2939. "Missing or invalid required Wrapped Data attribute");
  2940. return NULL;
  2941. }
  2942. wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data",
  2943. wrapped_data, wrapped_data_len);
  2944. attr_len = wrapped_data - 4 - attr_start;
  2945. r_bootstrap = dpp_get_attr(attr_start, attr_len,
  2946. DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
  2947. &r_bootstrap_len);
  2948. if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
  2949. dpp_auth_fail(auth,
  2950. "Missing or invalid required Responder Bootstrapping Key Hash attribute");
  2951. return NULL;
  2952. }
  2953. wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash",
  2954. r_bootstrap, r_bootstrap_len);
  2955. if (os_memcmp(r_bootstrap, auth->peer_bi->pubkey_hash,
  2956. SHA256_MAC_LEN) != 0) {
  2957. dpp_auth_fail(auth,
  2958. "Unexpected Responder Bootstrapping Key Hash value");
  2959. wpa_hexdump(MSG_DEBUG,
  2960. "DPP: Expected Responder Bootstrapping Key Hash",
  2961. auth->peer_bi->pubkey_hash, SHA256_MAC_LEN);
  2962. return NULL;
  2963. }
  2964. i_bootstrap = dpp_get_attr(attr_start, attr_len,
  2965. DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
  2966. &i_bootstrap_len);
  2967. if (i_bootstrap) {
  2968. if (i_bootstrap_len != SHA256_MAC_LEN) {
  2969. dpp_auth_fail(auth,
  2970. "Invalid Initiator Bootstrapping Key Hash attribute");
  2971. return NULL;
  2972. }
  2973. wpa_hexdump(MSG_MSGDUMP,
  2974. "DPP: Initiator Bootstrapping Key Hash",
  2975. i_bootstrap, i_bootstrap_len);
  2976. if (!auth->own_bi ||
  2977. os_memcmp(i_bootstrap, auth->own_bi->pubkey_hash,
  2978. SHA256_MAC_LEN) != 0) {
  2979. dpp_auth_fail(auth,
  2980. "Initiator Bootstrapping Key Hash attribute did not match");
  2981. return NULL;
  2982. }
  2983. } else if (auth->own_bi && auth->own_bi->type == DPP_BOOTSTRAP_PKEX) {
  2984. /* PKEX bootstrapping mandates use of mutual authentication */
  2985. dpp_auth_fail(auth,
  2986. "Missing Initiator Bootstrapping Key Hash attribute");
  2987. return NULL;
  2988. }
  2989. status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS,
  2990. &status_len);
  2991. if (!status || status_len < 1) {
  2992. dpp_auth_fail(auth,
  2993. "Missing or invalid required DPP Status attribute");
  2994. return NULL;
  2995. }
  2996. wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
  2997. auth->auth_resp_status = status[0];
  2998. if (status[0] != DPP_STATUS_OK) {
  2999. dpp_auth_resp_rx_status(auth, hdr, attr_start,
  3000. attr_len, wrapped_data,
  3001. wrapped_data_len, status[0]);
  3002. return NULL;
  3003. }
  3004. if (!i_bootstrap && auth->own_bi) {
  3005. wpa_printf(MSG_DEBUG,
  3006. "DPP: Responder decided not to use mutual authentication");
  3007. auth->own_bi = NULL;
  3008. }
  3009. r_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_R_PROTOCOL_KEY,
  3010. &r_proto_len);
  3011. if (!r_proto) {
  3012. dpp_auth_fail(auth,
  3013. "Missing required Responder Protocol Key attribute");
  3014. return NULL;
  3015. }
  3016. wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Protocol Key",
  3017. r_proto, r_proto_len);
  3018. /* N = pI * PR */
  3019. pr = dpp_set_pubkey_point(auth->own_protocol_key, r_proto, r_proto_len);
  3020. if (!pr) {
  3021. dpp_auth_fail(auth, "Invalid Responder Protocol Key");
  3022. return NULL;
  3023. }
  3024. dpp_debug_print_key("Peer (Responder) Protocol Key", pr);
  3025. ctx = EVP_PKEY_CTX_new(auth->own_protocol_key, NULL);
  3026. if (!ctx ||
  3027. EVP_PKEY_derive_init(ctx) != 1 ||
  3028. EVP_PKEY_derive_set_peer(ctx, pr) != 1 ||
  3029. EVP_PKEY_derive(ctx, NULL, &secret_len) != 1 ||
  3030. secret_len > DPP_MAX_SHARED_SECRET_LEN ||
  3031. EVP_PKEY_derive(ctx, auth->Nx, &secret_len) != 1) {
  3032. wpa_printf(MSG_ERROR,
  3033. "DPP: Failed to derive ECDH shared secret: %s",
  3034. ERR_error_string(ERR_get_error(), NULL));
  3035. dpp_auth_fail(auth, "Failed to derive ECDH shared secret");
  3036. goto fail;
  3037. }
  3038. EVP_PKEY_CTX_free(ctx);
  3039. ctx = NULL;
  3040. auth->peer_protocol_key = pr;
  3041. pr = NULL;
  3042. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)",
  3043. auth->Nx, auth->secret_len);
  3044. if (dpp_derive_k2(auth->Nx, auth->secret_len, auth->k2,
  3045. auth->curve->hash_len) < 0)
  3046. goto fail;
  3047. addr[0] = hdr;
  3048. len[0] = DPP_HDR_LEN;
  3049. addr[1] = attr_start;
  3050. len[1] = attr_len;
  3051. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  3052. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  3053. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  3054. wrapped_data, wrapped_data_len);
  3055. unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
  3056. unwrapped = os_malloc(unwrapped_len);
  3057. if (!unwrapped)
  3058. goto fail;
  3059. if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
  3060. wrapped_data, wrapped_data_len,
  3061. 2, addr, len, unwrapped) < 0) {
  3062. dpp_auth_fail(auth, "AES-SIV decryption failed");
  3063. goto fail;
  3064. }
  3065. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
  3066. unwrapped, unwrapped_len);
  3067. if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
  3068. dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
  3069. goto fail;
  3070. }
  3071. r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE,
  3072. &r_nonce_len);
  3073. if (!r_nonce || r_nonce_len != auth->curve->nonce_len) {
  3074. dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce");
  3075. goto fail;
  3076. }
  3077. wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", r_nonce, r_nonce_len);
  3078. os_memcpy(auth->r_nonce, r_nonce, r_nonce_len);
  3079. i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
  3080. &i_nonce_len);
  3081. if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
  3082. dpp_auth_fail(auth, "Missing or invalid I-nonce");
  3083. goto fail;
  3084. }
  3085. wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
  3086. if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) {
  3087. dpp_auth_fail(auth, "I-nonce mismatch");
  3088. goto fail;
  3089. }
  3090. if (auth->own_bi && auth->peer_bi) {
  3091. /* Mutual authentication */
  3092. if (dpp_auth_derive_l_initiator(auth) < 0)
  3093. goto fail;
  3094. }
  3095. r_capab = dpp_get_attr(unwrapped, unwrapped_len,
  3096. DPP_ATTR_R_CAPABILITIES,
  3097. &r_capab_len);
  3098. if (!r_capab || r_capab_len < 1) {
  3099. dpp_auth_fail(auth, "Missing or invalid R-capabilities");
  3100. goto fail;
  3101. }
  3102. auth->r_capab = r_capab[0];
  3103. wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab);
  3104. role = auth->r_capab & DPP_CAPAB_ROLE_MASK;
  3105. if ((auth->allowed_roles ==
  3106. (DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE)) &&
  3107. (role == DPP_CAPAB_CONFIGURATOR || role == DPP_CAPAB_ENROLLEE)) {
  3108. /* Peer selected its role, so move from "either role" to the
  3109. * role that is compatible with peer's selection. */
  3110. auth->configurator = role == DPP_CAPAB_ENROLLEE;
  3111. wpa_printf(MSG_DEBUG, "DPP: Acting as %s",
  3112. auth->configurator ? "Configurator" : "Enrollee");
  3113. } else if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) ||
  3114. (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) {
  3115. wpa_printf(MSG_DEBUG, "DPP: Incompatible role selection");
  3116. wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
  3117. "Unexpected role in R-capabilities 0x%02x",
  3118. role);
  3119. if (role != DPP_CAPAB_ENROLLEE &&
  3120. role != DPP_CAPAB_CONFIGURATOR)
  3121. goto fail;
  3122. bin_clear_free(unwrapped, unwrapped_len);
  3123. auth->remove_on_tx_status = 1;
  3124. return dpp_auth_build_conf(auth, DPP_STATUS_NOT_COMPATIBLE);
  3125. }
  3126. wrapped2 = dpp_get_attr(unwrapped, unwrapped_len,
  3127. DPP_ATTR_WRAPPED_DATA, &wrapped2_len);
  3128. if (!wrapped2 || wrapped2_len < AES_BLOCK_SIZE) {
  3129. dpp_auth_fail(auth,
  3130. "Missing or invalid Secondary Wrapped Data");
  3131. goto fail;
  3132. }
  3133. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  3134. wrapped2, wrapped2_len);
  3135. if (dpp_derive_ke(auth, auth->ke, auth->curve->hash_len) < 0)
  3136. goto fail;
  3137. unwrapped2_len = wrapped2_len - AES_BLOCK_SIZE;
  3138. unwrapped2 = os_malloc(unwrapped2_len);
  3139. if (!unwrapped2)
  3140. goto fail;
  3141. if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
  3142. wrapped2, wrapped2_len,
  3143. 0, NULL, NULL, unwrapped2) < 0) {
  3144. dpp_auth_fail(auth, "AES-SIV decryption failed");
  3145. goto fail;
  3146. }
  3147. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
  3148. unwrapped2, unwrapped2_len);
  3149. if (dpp_check_attrs(unwrapped2, unwrapped2_len) < 0) {
  3150. dpp_auth_fail(auth,
  3151. "Invalid attribute in secondary unwrapped data");
  3152. goto fail;
  3153. }
  3154. r_auth = dpp_get_attr(unwrapped2, unwrapped2_len, DPP_ATTR_R_AUTH_TAG,
  3155. &r_auth_len);
  3156. if (!r_auth || r_auth_len != auth->curve->hash_len) {
  3157. dpp_auth_fail(auth,
  3158. "Missing or invalid Responder Authenticating Tag");
  3159. goto fail;
  3160. }
  3161. wpa_hexdump(MSG_DEBUG, "DPP: Received Responder Authenticating Tag",
  3162. r_auth, r_auth_len);
  3163. /* R-auth' = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */
  3164. if (dpp_gen_r_auth(auth, r_auth2) < 0)
  3165. goto fail;
  3166. wpa_hexdump(MSG_DEBUG, "DPP: Calculated Responder Authenticating Tag",
  3167. r_auth2, r_auth_len);
  3168. if (os_memcmp(r_auth, r_auth2, r_auth_len) != 0) {
  3169. dpp_auth_fail(auth, "Mismatching Responder Authenticating Tag");
  3170. bin_clear_free(unwrapped, unwrapped_len);
  3171. bin_clear_free(unwrapped2, unwrapped2_len);
  3172. auth->remove_on_tx_status = 1;
  3173. return dpp_auth_build_conf(auth, DPP_STATUS_AUTH_FAILURE);
  3174. }
  3175. bin_clear_free(unwrapped, unwrapped_len);
  3176. bin_clear_free(unwrapped2, unwrapped2_len);
  3177. #ifdef CONFIG_TESTING_OPTIONS
  3178. if (dpp_test == DPP_TEST_AUTH_RESP_IN_PLACE_OF_CONF) {
  3179. wpa_printf(MSG_INFO,
  3180. "DPP: TESTING - Authentication Response in place of Confirm");
  3181. if (dpp_auth_build_resp_ok(auth) < 0)
  3182. return NULL;
  3183. return wpabuf_dup(auth->resp_msg);
  3184. }
  3185. #endif /* CONFIG_TESTING_OPTIONS */
  3186. return dpp_auth_build_conf(auth, DPP_STATUS_OK);
  3187. fail:
  3188. bin_clear_free(unwrapped, unwrapped_len);
  3189. bin_clear_free(unwrapped2, unwrapped2_len);
  3190. EVP_PKEY_free(pr);
  3191. EVP_PKEY_CTX_free(ctx);
  3192. return NULL;
  3193. }
  3194. static int dpp_auth_conf_rx_failure(struct dpp_authentication *auth,
  3195. const u8 *hdr,
  3196. const u8 *attr_start, size_t attr_len,
  3197. const u8 *wrapped_data,
  3198. u16 wrapped_data_len,
  3199. enum dpp_status_error status)
  3200. {
  3201. const u8 *addr[2];
  3202. size_t len[2];
  3203. u8 *unwrapped = NULL;
  3204. size_t unwrapped_len = 0;
  3205. const u8 *r_nonce;
  3206. u16 r_nonce_len;
  3207. /* Authentication Confirm failure cases are expected to include
  3208. * {R-nonce}k2 in the Wrapped Data attribute. */
  3209. addr[0] = hdr;
  3210. len[0] = DPP_HDR_LEN;
  3211. addr[1] = attr_start;
  3212. len[1] = attr_len;
  3213. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  3214. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  3215. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  3216. wrapped_data, wrapped_data_len);
  3217. unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
  3218. unwrapped = os_malloc(unwrapped_len);
  3219. if (!unwrapped) {
  3220. dpp_auth_fail(auth, "Authentication failed");
  3221. goto fail;
  3222. }
  3223. if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
  3224. wrapped_data, wrapped_data_len,
  3225. 2, addr, len, unwrapped) < 0) {
  3226. dpp_auth_fail(auth, "AES-SIV decryption failed");
  3227. goto fail;
  3228. }
  3229. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
  3230. unwrapped, unwrapped_len);
  3231. if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
  3232. dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
  3233. goto fail;
  3234. }
  3235. r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE,
  3236. &r_nonce_len);
  3237. if (!r_nonce || r_nonce_len != auth->curve->nonce_len) {
  3238. dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce");
  3239. goto fail;
  3240. }
  3241. if (os_memcmp(r_nonce, auth->r_nonce, r_nonce_len) != 0) {
  3242. wpa_hexdump(MSG_DEBUG, "DPP: Received R-nonce",
  3243. r_nonce, r_nonce_len);
  3244. wpa_hexdump(MSG_DEBUG, "DPP: Expected R-nonce",
  3245. auth->r_nonce, r_nonce_len);
  3246. dpp_auth_fail(auth, "R-nonce mismatch");
  3247. goto fail;
  3248. }
  3249. if (status == DPP_STATUS_NOT_COMPATIBLE)
  3250. dpp_auth_fail(auth, "Peer reported incompatible R-capab role");
  3251. else if (status == DPP_STATUS_AUTH_FAILURE)
  3252. dpp_auth_fail(auth, "Peer reported authentication failure)");
  3253. fail:
  3254. bin_clear_free(unwrapped, unwrapped_len);
  3255. return -1;
  3256. }
  3257. int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
  3258. const u8 *attr_start, size_t attr_len)
  3259. {
  3260. const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *i_auth;
  3261. u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
  3262. i_auth_len;
  3263. const u8 *addr[2];
  3264. size_t len[2];
  3265. u8 *unwrapped = NULL;
  3266. size_t unwrapped_len = 0;
  3267. u8 i_auth2[DPP_MAX_HASH_LEN];
  3268. if (auth->initiator) {
  3269. dpp_auth_fail(auth, "Unexpected Authentication Confirm");
  3270. return -1;
  3271. }
  3272. auth->waiting_auth_conf = 0;
  3273. wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
  3274. &wrapped_data_len);
  3275. if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
  3276. dpp_auth_fail(auth,
  3277. "Missing or invalid required Wrapped Data attribute");
  3278. return -1;
  3279. }
  3280. wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data",
  3281. wrapped_data, wrapped_data_len);
  3282. attr_len = wrapped_data - 4 - attr_start;
  3283. r_bootstrap = dpp_get_attr(attr_start, attr_len,
  3284. DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
  3285. &r_bootstrap_len);
  3286. if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
  3287. dpp_auth_fail(auth,
  3288. "Missing or invalid required Responder Bootstrapping Key Hash attribute");
  3289. return -1;
  3290. }
  3291. wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash",
  3292. r_bootstrap, r_bootstrap_len);
  3293. if (os_memcmp(r_bootstrap, auth->own_bi->pubkey_hash,
  3294. SHA256_MAC_LEN) != 0) {
  3295. wpa_hexdump(MSG_DEBUG,
  3296. "DPP: Expected Responder Bootstrapping Key Hash",
  3297. auth->peer_bi->pubkey_hash, SHA256_MAC_LEN);
  3298. dpp_auth_fail(auth,
  3299. "Responder Bootstrapping Key Hash mismatch");
  3300. return -1;
  3301. }
  3302. i_bootstrap = dpp_get_attr(attr_start, attr_len,
  3303. DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
  3304. &i_bootstrap_len);
  3305. if (i_bootstrap) {
  3306. if (i_bootstrap_len != SHA256_MAC_LEN) {
  3307. dpp_auth_fail(auth,
  3308. "Invalid Initiator Bootstrapping Key Hash attribute");
  3309. return -1;
  3310. }
  3311. wpa_hexdump(MSG_MSGDUMP,
  3312. "DPP: Initiator Bootstrapping Key Hash",
  3313. i_bootstrap, i_bootstrap_len);
  3314. if (!auth->peer_bi ||
  3315. os_memcmp(i_bootstrap, auth->peer_bi->pubkey_hash,
  3316. SHA256_MAC_LEN) != 0) {
  3317. dpp_auth_fail(auth,
  3318. "Initiator Bootstrapping Key Hash mismatch");
  3319. return -1;
  3320. }
  3321. } else if (auth->own_bi && auth->peer_bi) {
  3322. /* Mutual authentication and peer did not include its
  3323. * Bootstrapping Key Hash attribute. */
  3324. dpp_auth_fail(auth,
  3325. "Missing Initiator Bootstrapping Key Hash attribute");
  3326. return -1;
  3327. }
  3328. status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS,
  3329. &status_len);
  3330. if (!status || status_len < 1) {
  3331. dpp_auth_fail(auth,
  3332. "Missing or invalid required DPP Status attribute");
  3333. return -1;
  3334. }
  3335. wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
  3336. if (status[0] == DPP_STATUS_NOT_COMPATIBLE ||
  3337. status[0] == DPP_STATUS_AUTH_FAILURE)
  3338. return dpp_auth_conf_rx_failure(auth, hdr, attr_start,
  3339. attr_len, wrapped_data,
  3340. wrapped_data_len, status[0]);
  3341. if (status[0] != DPP_STATUS_OK) {
  3342. dpp_auth_fail(auth, "Authentication failed");
  3343. return -1;
  3344. }
  3345. addr[0] = hdr;
  3346. len[0] = DPP_HDR_LEN;
  3347. addr[1] = attr_start;
  3348. len[1] = attr_len;
  3349. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  3350. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  3351. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  3352. wrapped_data, wrapped_data_len);
  3353. unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
  3354. unwrapped = os_malloc(unwrapped_len);
  3355. if (!unwrapped)
  3356. return -1;
  3357. if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
  3358. wrapped_data, wrapped_data_len,
  3359. 2, addr, len, unwrapped) < 0) {
  3360. dpp_auth_fail(auth, "AES-SIV decryption failed");
  3361. goto fail;
  3362. }
  3363. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
  3364. unwrapped, unwrapped_len);
  3365. if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
  3366. dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
  3367. goto fail;
  3368. }
  3369. i_auth = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_AUTH_TAG,
  3370. &i_auth_len);
  3371. if (!i_auth || i_auth_len != auth->curve->hash_len) {
  3372. dpp_auth_fail(auth,
  3373. "Missing or invalid Initiator Authenticating Tag");
  3374. goto fail;
  3375. }
  3376. wpa_hexdump(MSG_DEBUG, "DPP: Received Initiator Authenticating Tag",
  3377. i_auth, i_auth_len);
  3378. /* I-auth' = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |] 1) */
  3379. if (dpp_gen_i_auth(auth, i_auth2) < 0)
  3380. goto fail;
  3381. wpa_hexdump(MSG_DEBUG, "DPP: Calculated Initiator Authenticating Tag",
  3382. i_auth2, i_auth_len);
  3383. if (os_memcmp(i_auth, i_auth2, i_auth_len) != 0) {
  3384. dpp_auth_fail(auth, "Mismatching Initiator Authenticating Tag");
  3385. goto fail;
  3386. }
  3387. bin_clear_free(unwrapped, unwrapped_len);
  3388. dpp_auth_success(auth);
  3389. return 0;
  3390. fail:
  3391. bin_clear_free(unwrapped, unwrapped_len);
  3392. return -1;
  3393. }
  3394. void dpp_configuration_free(struct dpp_configuration *conf)
  3395. {
  3396. if (!conf)
  3397. return;
  3398. str_clear_free(conf->passphrase);
  3399. bin_clear_free(conf, sizeof(*conf));
  3400. }
  3401. void dpp_auth_deinit(struct dpp_authentication *auth)
  3402. {
  3403. if (!auth)
  3404. return;
  3405. dpp_configuration_free(auth->conf_ap);
  3406. dpp_configuration_free(auth->conf_sta);
  3407. EVP_PKEY_free(auth->own_protocol_key);
  3408. EVP_PKEY_free(auth->peer_protocol_key);
  3409. wpabuf_free(auth->req_msg);
  3410. wpabuf_free(auth->resp_msg);
  3411. wpabuf_free(auth->conf_req);
  3412. os_free(auth->connector);
  3413. wpabuf_free(auth->net_access_key);
  3414. wpabuf_free(auth->c_sign_key);
  3415. dpp_bootstrap_info_free(auth->tmp_own_bi);
  3416. #ifdef CONFIG_TESTING_OPTIONS
  3417. os_free(auth->config_obj_override);
  3418. os_free(auth->discovery_override);
  3419. os_free(auth->groups_override);
  3420. #endif /* CONFIG_TESTING_OPTIONS */
  3421. bin_clear_free(auth, sizeof(*auth));
  3422. }
  3423. static struct wpabuf *
  3424. dpp_build_conf_start(struct dpp_authentication *auth,
  3425. struct dpp_configuration *conf, size_t tailroom)
  3426. {
  3427. struct wpabuf *buf;
  3428. char ssid[6 * sizeof(conf->ssid) + 1];
  3429. #ifdef CONFIG_TESTING_OPTIONS
  3430. if (auth->discovery_override)
  3431. tailroom += os_strlen(auth->discovery_override);
  3432. #endif /* CONFIG_TESTING_OPTIONS */
  3433. buf = wpabuf_alloc(200 + tailroom);
  3434. if (!buf)
  3435. return NULL;
  3436. wpabuf_put_str(buf, "{\"wi-fi_tech\":\"infra\",\"discovery\":");
  3437. #ifdef CONFIG_TESTING_OPTIONS
  3438. if (auth->discovery_override) {
  3439. wpa_printf(MSG_DEBUG, "DPP: TESTING - discovery override: '%s'",
  3440. auth->discovery_override);
  3441. wpabuf_put_str(buf, auth->discovery_override);
  3442. wpabuf_put_u8(buf, ',');
  3443. return buf;
  3444. }
  3445. #endif /* CONFIG_TESTING_OPTIONS */
  3446. wpabuf_put_str(buf, "{\"ssid\":\"");
  3447. json_escape_string(ssid, sizeof(ssid),
  3448. (const char *) conf->ssid, conf->ssid_len);
  3449. wpabuf_put_str(buf, ssid);
  3450. wpabuf_put_str(buf, "\"},");
  3451. return buf;
  3452. }
  3453. static int dpp_build_jwk(struct wpabuf *buf, const char *name, EVP_PKEY *key,
  3454. const char *kid, const struct dpp_curve_params *curve)
  3455. {
  3456. struct wpabuf *pub;
  3457. const u8 *pos;
  3458. char *x = NULL, *y = NULL;
  3459. int ret = -1;
  3460. pub = dpp_get_pubkey_point(key, 0);
  3461. if (!pub)
  3462. goto fail;
  3463. pos = wpabuf_head(pub);
  3464. x = (char *) base64_url_encode(pos, curve->prime_len, NULL, 0);
  3465. pos += curve->prime_len;
  3466. y = (char *) base64_url_encode(pos, curve->prime_len, NULL, 0);
  3467. if (!x || !y)
  3468. goto fail;
  3469. wpabuf_put_str(buf, "\"");
  3470. wpabuf_put_str(buf, name);
  3471. wpabuf_put_str(buf, "\":{\"kty\":\"EC\",\"crv\":\"");
  3472. wpabuf_put_str(buf, curve->jwk_crv);
  3473. wpabuf_put_str(buf, "\",\"x\":\"");
  3474. wpabuf_put_str(buf, x);
  3475. wpabuf_put_str(buf, "\",\"y\":\"");
  3476. wpabuf_put_str(buf, y);
  3477. if (kid) {
  3478. wpabuf_put_str(buf, "\",\"kid\":\"");
  3479. wpabuf_put_str(buf, kid);
  3480. }
  3481. wpabuf_put_str(buf, "\"}");
  3482. ret = 0;
  3483. fail:
  3484. wpabuf_free(pub);
  3485. os_free(x);
  3486. os_free(y);
  3487. return ret;
  3488. }
  3489. static struct wpabuf *
  3490. dpp_build_conf_obj_dpp(struct dpp_authentication *auth, int ap,
  3491. struct dpp_configuration *conf)
  3492. {
  3493. struct wpabuf *buf = NULL;
  3494. char *signed1 = NULL, *signed2 = NULL, *signed3 = NULL;
  3495. size_t tailroom;
  3496. const struct dpp_curve_params *curve;
  3497. char jws_prot_hdr[100];
  3498. size_t signed1_len, signed2_len, signed3_len;
  3499. struct wpabuf *dppcon = NULL;
  3500. unsigned char *signature = NULL;
  3501. const unsigned char *p;
  3502. size_t signature_len;
  3503. EVP_MD_CTX *md_ctx = NULL;
  3504. ECDSA_SIG *sig = NULL;
  3505. char *dot = ".";
  3506. const EVP_MD *sign_md;
  3507. const BIGNUM *r, *s;
  3508. size_t extra_len = 1000;
  3509. if (!auth->conf) {
  3510. wpa_printf(MSG_INFO,
  3511. "DPP: No configurator specified - cannot generate DPP config object");
  3512. goto fail;
  3513. }
  3514. curve = auth->conf->curve;
  3515. if (curve->hash_len == SHA256_MAC_LEN) {
  3516. sign_md = EVP_sha256();
  3517. } else if (curve->hash_len == SHA384_MAC_LEN) {
  3518. sign_md = EVP_sha384();
  3519. } else if (curve->hash_len == SHA512_MAC_LEN) {
  3520. sign_md = EVP_sha512();
  3521. } else {
  3522. wpa_printf(MSG_DEBUG, "DPP: Unknown signature algorithm");
  3523. goto fail;
  3524. }
  3525. #ifdef CONFIG_TESTING_OPTIONS
  3526. if (auth->groups_override)
  3527. extra_len += os_strlen(auth->groups_override);
  3528. #endif /* CONFIG_TESTING_OPTIONS */
  3529. /* Connector (JSON dppCon object) */
  3530. dppcon = wpabuf_alloc(extra_len + 2 * auth->curve->prime_len * 4 / 3);
  3531. if (!dppcon)
  3532. goto fail;
  3533. #ifdef CONFIG_TESTING_OPTIONS
  3534. if (auth->groups_override) {
  3535. wpabuf_put_u8(dppcon, '{');
  3536. if (auth->groups_override) {
  3537. wpa_printf(MSG_DEBUG,
  3538. "DPP: TESTING - groups override: '%s'",
  3539. auth->groups_override);
  3540. wpabuf_put_str(dppcon, "\"groups\":");
  3541. wpabuf_put_str(dppcon, auth->groups_override);
  3542. wpabuf_put_u8(dppcon, ',');
  3543. }
  3544. goto skip_groups;
  3545. }
  3546. #endif /* CONFIG_TESTING_OPTIONS */
  3547. wpabuf_put_str(dppcon, "{\"groups\":[{\"groupId\":\"*\",");
  3548. wpabuf_printf(dppcon, "\"netRole\":\"%s\"}],", ap ? "ap" : "sta");
  3549. #ifdef CONFIG_TESTING_OPTIONS
  3550. skip_groups:
  3551. #endif /* CONFIG_TESTING_OPTIONS */
  3552. if (dpp_build_jwk(dppcon, "netAccessKey", auth->peer_protocol_key, NULL,
  3553. auth->curve) < 0) {
  3554. wpa_printf(MSG_DEBUG, "DPP: Failed to build netAccessKey JWK");
  3555. goto fail;
  3556. }
  3557. if (conf->netaccesskey_expiry) {
  3558. struct os_tm tm;
  3559. if (os_gmtime(conf->netaccesskey_expiry, &tm) < 0) {
  3560. wpa_printf(MSG_DEBUG,
  3561. "DPP: Failed to generate expiry string");
  3562. goto fail;
  3563. }
  3564. wpabuf_printf(dppcon,
  3565. ",\"expiry\":\"%04u-%02u-%02uT%02u:%02u:%02uZ\"",
  3566. tm.year, tm.month, tm.day,
  3567. tm.hour, tm.min, tm.sec);
  3568. }
  3569. wpabuf_put_u8(dppcon, '}');
  3570. wpa_printf(MSG_DEBUG, "DPP: dppCon: %s",
  3571. (const char *) wpabuf_head(dppcon));
  3572. os_snprintf(jws_prot_hdr, sizeof(jws_prot_hdr),
  3573. "{\"typ\":\"dppCon\",\"kid\":\"%s\",\"alg\":\"%s\"}",
  3574. auth->conf->kid, curve->jws_alg);
  3575. signed1 = (char *) base64_url_encode((unsigned char *) jws_prot_hdr,
  3576. os_strlen(jws_prot_hdr),
  3577. &signed1_len, 0);
  3578. signed2 = (char *) base64_url_encode(wpabuf_head(dppcon),
  3579. wpabuf_len(dppcon),
  3580. &signed2_len, 0);
  3581. if (!signed1 || !signed2)
  3582. goto fail;
  3583. md_ctx = EVP_MD_CTX_create();
  3584. if (!md_ctx)
  3585. goto fail;
  3586. ERR_clear_error();
  3587. if (EVP_DigestSignInit(md_ctx, NULL, sign_md, NULL,
  3588. auth->conf->csign) != 1) {
  3589. wpa_printf(MSG_DEBUG, "DPP: EVP_DigestSignInit failed: %s",
  3590. ERR_error_string(ERR_get_error(), NULL));
  3591. goto fail;
  3592. }
  3593. if (EVP_DigestSignUpdate(md_ctx, signed1, signed1_len) != 1 ||
  3594. EVP_DigestSignUpdate(md_ctx, dot, 1) != 1 ||
  3595. EVP_DigestSignUpdate(md_ctx, signed2, signed2_len) != 1) {
  3596. wpa_printf(MSG_DEBUG, "DPP: EVP_DigestSignUpdate failed: %s",
  3597. ERR_error_string(ERR_get_error(), NULL));
  3598. goto fail;
  3599. }
  3600. if (EVP_DigestSignFinal(md_ctx, NULL, &signature_len) != 1) {
  3601. wpa_printf(MSG_DEBUG, "DPP: EVP_DigestSignFinal failed: %s",
  3602. ERR_error_string(ERR_get_error(), NULL));
  3603. goto fail;
  3604. }
  3605. signature = os_malloc(signature_len);
  3606. if (!signature)
  3607. goto fail;
  3608. if (EVP_DigestSignFinal(md_ctx, signature, &signature_len) != 1) {
  3609. wpa_printf(MSG_DEBUG, "DPP: EVP_DigestSignFinal failed: %s",
  3610. ERR_error_string(ERR_get_error(), NULL));
  3611. goto fail;
  3612. }
  3613. wpa_hexdump(MSG_DEBUG, "DPP: signedConnector ECDSA signature (DER)",
  3614. signature, signature_len);
  3615. /* Convert to raw coordinates r,s */
  3616. p = signature;
  3617. sig = d2i_ECDSA_SIG(NULL, &p, signature_len);
  3618. if (!sig)
  3619. goto fail;
  3620. ECDSA_SIG_get0(sig, &r, &s);
  3621. if (dpp_bn2bin_pad(r, signature, curve->prime_len) < 0 ||
  3622. dpp_bn2bin_pad(s, signature + curve->prime_len,
  3623. curve->prime_len) < 0)
  3624. goto fail;
  3625. signature_len = 2 * curve->prime_len;
  3626. wpa_hexdump(MSG_DEBUG, "DPP: signedConnector ECDSA signature (raw r,s)",
  3627. signature, signature_len);
  3628. signed3 = (char *) base64_url_encode(signature, signature_len,
  3629. &signed3_len, 0);
  3630. if (!signed3)
  3631. goto fail;
  3632. tailroom = 1000;
  3633. tailroom += 2 * curve->prime_len * 4 / 3 + os_strlen(auth->conf->kid);
  3634. tailroom += signed1_len + signed2_len + signed3_len;
  3635. buf = dpp_build_conf_start(auth, conf, tailroom);
  3636. if (!buf)
  3637. goto fail;
  3638. wpabuf_put_str(buf, "\"cred\":{\"akm\":\"dpp\",\"signedConnector\":\"");
  3639. wpabuf_put_str(buf, signed1);
  3640. wpabuf_put_u8(buf, '.');
  3641. wpabuf_put_str(buf, signed2);
  3642. wpabuf_put_u8(buf, '.');
  3643. wpabuf_put_str(buf, signed3);
  3644. wpabuf_put_str(buf, "\",");
  3645. if (dpp_build_jwk(buf, "csign", auth->conf->csign, auth->conf->kid,
  3646. curve) < 0) {
  3647. wpa_printf(MSG_DEBUG, "DPP: Failed to build csign JWK");
  3648. goto fail;
  3649. }
  3650. wpabuf_put_str(buf, "}}");
  3651. wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Configuration Object",
  3652. wpabuf_head(buf), wpabuf_len(buf));
  3653. out:
  3654. EVP_MD_CTX_destroy(md_ctx);
  3655. ECDSA_SIG_free(sig);
  3656. os_free(signed1);
  3657. os_free(signed2);
  3658. os_free(signed3);
  3659. os_free(signature);
  3660. wpabuf_free(dppcon);
  3661. return buf;
  3662. fail:
  3663. wpa_printf(MSG_DEBUG, "DPP: Failed to build configuration object");
  3664. wpabuf_free(buf);
  3665. buf = NULL;
  3666. goto out;
  3667. }
  3668. static struct wpabuf *
  3669. dpp_build_conf_obj_legacy(struct dpp_authentication *auth, int ap,
  3670. struct dpp_configuration *conf)
  3671. {
  3672. struct wpabuf *buf;
  3673. buf = dpp_build_conf_start(auth, conf, 1000);
  3674. if (!buf)
  3675. return NULL;
  3676. wpabuf_printf(buf, "\"cred\":{\"akm\":\"%s\",", dpp_akm_str(conf->akm));
  3677. if (conf->passphrase) {
  3678. char pass[63 * 6 + 1];
  3679. if (os_strlen(conf->passphrase) > 63) {
  3680. wpabuf_free(buf);
  3681. return NULL;
  3682. }
  3683. json_escape_string(pass, sizeof(pass), conf->passphrase,
  3684. os_strlen(conf->passphrase));
  3685. wpabuf_put_str(buf, "\"pass\":\"");
  3686. wpabuf_put_str(buf, pass);
  3687. wpabuf_put_str(buf, "\"");
  3688. } else {
  3689. char psk[2 * sizeof(conf->psk) + 1];
  3690. wpa_snprintf_hex(psk, sizeof(psk),
  3691. conf->psk, sizeof(conf->psk));
  3692. wpabuf_put_str(buf, "\"psk_hex\":\"");
  3693. wpabuf_put_str(buf, psk);
  3694. wpabuf_put_str(buf, "\"");
  3695. }
  3696. wpabuf_put_str(buf, "}}");
  3697. wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Configuration Object (legacy)",
  3698. wpabuf_head(buf), wpabuf_len(buf));
  3699. return buf;
  3700. }
  3701. static struct wpabuf *
  3702. dpp_build_conf_obj(struct dpp_authentication *auth, int ap)
  3703. {
  3704. struct dpp_configuration *conf;
  3705. #ifdef CONFIG_TESTING_OPTIONS
  3706. if (auth->config_obj_override) {
  3707. wpa_printf(MSG_DEBUG, "DPP: Testing - Config Object override");
  3708. return wpabuf_alloc_copy(auth->config_obj_override,
  3709. os_strlen(auth->config_obj_override));
  3710. }
  3711. #endif /* CONFIG_TESTING_OPTIONS */
  3712. conf = ap ? auth->conf_ap : auth->conf_sta;
  3713. if (!conf) {
  3714. wpa_printf(MSG_DEBUG,
  3715. "DPP: No configuration available for Enrollee(%s) - reject configuration request",
  3716. ap ? "ap" : "sta");
  3717. return NULL;
  3718. }
  3719. if (conf->akm == DPP_AKM_DPP)
  3720. return dpp_build_conf_obj_dpp(auth, ap, conf);
  3721. return dpp_build_conf_obj_legacy(auth, ap, conf);
  3722. }
  3723. static struct wpabuf *
  3724. dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
  3725. u16 e_nonce_len, int ap)
  3726. {
  3727. struct wpabuf *conf;
  3728. size_t clear_len, attr_len;
  3729. struct wpabuf *clear = NULL, *msg = NULL;
  3730. u8 *wrapped;
  3731. const u8 *addr[1];
  3732. size_t len[1];
  3733. enum dpp_status_error status;
  3734. conf = dpp_build_conf_obj(auth, ap);
  3735. if (conf) {
  3736. wpa_hexdump_ascii(MSG_DEBUG, "DPP: configurationObject JSON",
  3737. wpabuf_head(conf), wpabuf_len(conf));
  3738. }
  3739. status = conf ? DPP_STATUS_OK : DPP_STATUS_CONFIGURE_FAILURE;
  3740. /* { E-nonce, configurationObject}ke */
  3741. clear_len = 4 + e_nonce_len;
  3742. if (conf)
  3743. clear_len += 4 + wpabuf_len(conf);
  3744. clear = wpabuf_alloc(clear_len);
  3745. attr_len = 4 + 1 + 4 + clear_len + AES_BLOCK_SIZE;
  3746. #ifdef CONFIG_TESTING_OPTIONS
  3747. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_CONF_RESP)
  3748. attr_len += 5;
  3749. #endif /* CONFIG_TESTING_OPTIONS */
  3750. msg = wpabuf_alloc(attr_len);
  3751. if (!clear || !msg)
  3752. goto fail;
  3753. #ifdef CONFIG_TESTING_OPTIONS
  3754. if (dpp_test == DPP_TEST_NO_E_NONCE_CONF_RESP) {
  3755. wpa_printf(MSG_INFO, "DPP: TESTING - no E-nonce");
  3756. goto skip_e_nonce;
  3757. }
  3758. if (dpp_test == DPP_TEST_E_NONCE_MISMATCH_CONF_RESP) {
  3759. wpa_printf(MSG_INFO, "DPP: TESTING - E-nonce mismatch");
  3760. wpabuf_put_le16(clear, DPP_ATTR_ENROLLEE_NONCE);
  3761. wpabuf_put_le16(clear, e_nonce_len);
  3762. wpabuf_put_data(clear, e_nonce, e_nonce_len - 1);
  3763. wpabuf_put_u8(clear, e_nonce[e_nonce_len - 1] ^ 0x01);
  3764. goto skip_e_nonce;
  3765. }
  3766. if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_CONF_RESP) {
  3767. wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data");
  3768. goto skip_wrapped_data;
  3769. }
  3770. #endif /* CONFIG_TESTING_OPTIONS */
  3771. /* E-nonce */
  3772. wpabuf_put_le16(clear, DPP_ATTR_ENROLLEE_NONCE);
  3773. wpabuf_put_le16(clear, e_nonce_len);
  3774. wpabuf_put_data(clear, e_nonce, e_nonce_len);
  3775. #ifdef CONFIG_TESTING_OPTIONS
  3776. skip_e_nonce:
  3777. if (dpp_test == DPP_TEST_NO_CONFIG_OBJ_CONF_RESP) {
  3778. wpa_printf(MSG_INFO, "DPP: TESTING - Config Object");
  3779. goto skip_config_obj;
  3780. }
  3781. #endif /* CONFIG_TESTING_OPTIONS */
  3782. if (conf) {
  3783. wpabuf_put_le16(clear, DPP_ATTR_CONFIG_OBJ);
  3784. wpabuf_put_le16(clear, wpabuf_len(conf));
  3785. wpabuf_put_buf(clear, conf);
  3786. }
  3787. #ifdef CONFIG_TESTING_OPTIONS
  3788. skip_config_obj:
  3789. if (dpp_test == DPP_TEST_NO_STATUS_CONF_RESP) {
  3790. wpa_printf(MSG_INFO, "DPP: TESTING - Status");
  3791. goto skip_status;
  3792. }
  3793. if (dpp_test == DPP_TEST_INVALID_STATUS_CONF_RESP) {
  3794. wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
  3795. status = 255;
  3796. }
  3797. #endif /* CONFIG_TESTING_OPTIONS */
  3798. /* DPP Status */
  3799. dpp_build_attr_status(msg, status);
  3800. #ifdef CONFIG_TESTING_OPTIONS
  3801. skip_status:
  3802. #endif /* CONFIG_TESTING_OPTIONS */
  3803. addr[0] = wpabuf_head(msg);
  3804. len[0] = wpabuf_len(msg);
  3805. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD", addr[0], len[0]);
  3806. wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
  3807. wpabuf_put_le16(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
  3808. wrapped = wpabuf_put(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
  3809. wpa_hexdump_buf(MSG_DEBUG, "DPP: AES-SIV cleartext", clear);
  3810. if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
  3811. wpabuf_head(clear), wpabuf_len(clear),
  3812. 1, addr, len, wrapped) < 0)
  3813. goto fail;
  3814. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  3815. wrapped, wpabuf_len(clear) + AES_BLOCK_SIZE);
  3816. #ifdef CONFIG_TESTING_OPTIONS
  3817. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_CONF_RESP) {
  3818. wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
  3819. dpp_build_attr_status(msg, DPP_STATUS_OK);
  3820. }
  3821. skip_wrapped_data:
  3822. #endif /* CONFIG_TESTING_OPTIONS */
  3823. wpa_hexdump_buf(MSG_DEBUG,
  3824. "DPP: Configuration Response attributes", msg);
  3825. out:
  3826. wpabuf_free(conf);
  3827. wpabuf_free(clear);
  3828. return msg;
  3829. fail:
  3830. wpabuf_free(msg);
  3831. msg = NULL;
  3832. goto out;
  3833. }
  3834. struct wpabuf *
  3835. dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
  3836. size_t attr_len)
  3837. {
  3838. const u8 *wrapped_data, *e_nonce, *config_attr;
  3839. u16 wrapped_data_len, e_nonce_len, config_attr_len;
  3840. u8 *unwrapped = NULL;
  3841. size_t unwrapped_len = 0;
  3842. struct wpabuf *resp = NULL;
  3843. struct json_token *root = NULL, *token;
  3844. int ap;
  3845. if (dpp_check_attrs(attr_start, attr_len) < 0) {
  3846. dpp_auth_fail(auth, "Invalid attribute in config request");
  3847. return NULL;
  3848. }
  3849. wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
  3850. &wrapped_data_len);
  3851. if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
  3852. dpp_auth_fail(auth,
  3853. "Missing or invalid required Wrapped Data attribute");
  3854. return NULL;
  3855. }
  3856. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  3857. wrapped_data, wrapped_data_len);
  3858. unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
  3859. unwrapped = os_malloc(unwrapped_len);
  3860. if (!unwrapped)
  3861. return NULL;
  3862. if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
  3863. wrapped_data, wrapped_data_len,
  3864. 0, NULL, NULL, unwrapped) < 0) {
  3865. dpp_auth_fail(auth, "AES-SIV decryption failed");
  3866. goto fail;
  3867. }
  3868. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
  3869. unwrapped, unwrapped_len);
  3870. if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
  3871. dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
  3872. goto fail;
  3873. }
  3874. e_nonce = dpp_get_attr(unwrapped, unwrapped_len,
  3875. DPP_ATTR_ENROLLEE_NONCE,
  3876. &e_nonce_len);
  3877. if (!e_nonce || e_nonce_len != auth->curve->nonce_len) {
  3878. dpp_auth_fail(auth,
  3879. "Missing or invalid Enrollee Nonce attribute");
  3880. goto fail;
  3881. }
  3882. wpa_hexdump(MSG_DEBUG, "DPP: Enrollee Nonce", e_nonce, e_nonce_len);
  3883. config_attr = dpp_get_attr(unwrapped, unwrapped_len,
  3884. DPP_ATTR_CONFIG_ATTR_OBJ,
  3885. &config_attr_len);
  3886. if (!config_attr) {
  3887. dpp_auth_fail(auth,
  3888. "Missing or invalid Config Attributes attribute");
  3889. goto fail;
  3890. }
  3891. wpa_hexdump_ascii(MSG_DEBUG, "DPP: Config Attributes",
  3892. config_attr, config_attr_len);
  3893. root = json_parse((const char *) config_attr, config_attr_len);
  3894. if (!root) {
  3895. dpp_auth_fail(auth, "Could not parse Config Attributes");
  3896. goto fail;
  3897. }
  3898. token = json_get_member(root, "name");
  3899. if (!token || token->type != JSON_STRING) {
  3900. dpp_auth_fail(auth, "No Config Attributes - name");
  3901. goto fail;
  3902. }
  3903. wpa_printf(MSG_DEBUG, "DPP: Enrollee name = '%s'", token->string);
  3904. token = json_get_member(root, "wi-fi_tech");
  3905. if (!token || token->type != JSON_STRING) {
  3906. dpp_auth_fail(auth, "No Config Attributes - wi-fi_tech");
  3907. goto fail;
  3908. }
  3909. wpa_printf(MSG_DEBUG, "DPP: wi-fi_tech = '%s'", token->string);
  3910. if (os_strcmp(token->string, "infra") != 0) {
  3911. wpa_printf(MSG_DEBUG, "DPP: Unsupported wi-fi_tech '%s'",
  3912. token->string);
  3913. dpp_auth_fail(auth, "Unsupported wi-fi_tech");
  3914. goto fail;
  3915. }
  3916. token = json_get_member(root, "netRole");
  3917. if (!token || token->type != JSON_STRING) {
  3918. dpp_auth_fail(auth, "No Config Attributes - netRole");
  3919. goto fail;
  3920. }
  3921. wpa_printf(MSG_DEBUG, "DPP: netRole = '%s'", token->string);
  3922. if (os_strcmp(token->string, "sta") == 0) {
  3923. ap = 0;
  3924. } else if (os_strcmp(token->string, "ap") == 0) {
  3925. ap = 1;
  3926. } else {
  3927. wpa_printf(MSG_DEBUG, "DPP: Unsupported netRole '%s'",
  3928. token->string);
  3929. dpp_auth_fail(auth, "Unsupported netRole");
  3930. goto fail;
  3931. }
  3932. resp = dpp_build_conf_resp(auth, e_nonce, e_nonce_len, ap);
  3933. fail:
  3934. json_free(root);
  3935. os_free(unwrapped);
  3936. return resp;
  3937. }
  3938. static struct wpabuf *
  3939. dpp_parse_jws_prot_hdr(const struct dpp_curve_params *curve,
  3940. const u8 *prot_hdr, u16 prot_hdr_len,
  3941. const EVP_MD **ret_md)
  3942. {
  3943. struct json_token *root, *token;
  3944. struct wpabuf *kid = NULL;
  3945. root = json_parse((const char *) prot_hdr, prot_hdr_len);
  3946. if (!root) {
  3947. wpa_printf(MSG_DEBUG,
  3948. "DPP: JSON parsing failed for JWS Protected Header");
  3949. goto fail;
  3950. }
  3951. if (root->type != JSON_OBJECT) {
  3952. wpa_printf(MSG_DEBUG,
  3953. "DPP: JWS Protected Header root is not an object");
  3954. goto fail;
  3955. }
  3956. token = json_get_member(root, "typ");
  3957. if (!token || token->type != JSON_STRING) {
  3958. wpa_printf(MSG_DEBUG, "DPP: No typ string value found");
  3959. goto fail;
  3960. }
  3961. wpa_printf(MSG_DEBUG, "DPP: JWS Protected Header typ=%s",
  3962. token->string);
  3963. if (os_strcmp(token->string, "dppCon") != 0) {
  3964. wpa_printf(MSG_DEBUG,
  3965. "DPP: Unsupported JWS Protected Header typ=%s",
  3966. token->string);
  3967. goto fail;
  3968. }
  3969. token = json_get_member(root, "alg");
  3970. if (!token || token->type != JSON_STRING) {
  3971. wpa_printf(MSG_DEBUG, "DPP: No alg string value found");
  3972. goto fail;
  3973. }
  3974. wpa_printf(MSG_DEBUG, "DPP: JWS Protected Header alg=%s",
  3975. token->string);
  3976. if (os_strcmp(token->string, curve->jws_alg) != 0) {
  3977. wpa_printf(MSG_DEBUG,
  3978. "DPP: Unexpected JWS Protected Header alg=%s (expected %s based on C-sign-key)",
  3979. token->string, curve->jws_alg);
  3980. goto fail;
  3981. }
  3982. if (os_strcmp(token->string, "ES256") == 0 ||
  3983. os_strcmp(token->string, "BS256") == 0)
  3984. *ret_md = EVP_sha256();
  3985. else if (os_strcmp(token->string, "ES384") == 0 ||
  3986. os_strcmp(token->string, "BS384") == 0)
  3987. *ret_md = EVP_sha384();
  3988. else if (os_strcmp(token->string, "ES512") == 0 ||
  3989. os_strcmp(token->string, "BS512") == 0)
  3990. *ret_md = EVP_sha512();
  3991. else
  3992. *ret_md = NULL;
  3993. if (!*ret_md) {
  3994. wpa_printf(MSG_DEBUG,
  3995. "DPP: Unsupported JWS Protected Header alg=%s",
  3996. token->string);
  3997. goto fail;
  3998. }
  3999. kid = json_get_member_base64url(root, "kid");
  4000. if (!kid) {
  4001. wpa_printf(MSG_DEBUG, "DPP: No kid string value found");
  4002. goto fail;
  4003. }
  4004. wpa_hexdump_buf(MSG_DEBUG, "DPP: JWS Protected Header kid (decoded)",
  4005. kid);
  4006. fail:
  4007. json_free(root);
  4008. return kid;
  4009. }
  4010. static int dpp_parse_cred_legacy(struct dpp_authentication *auth,
  4011. struct json_token *cred)
  4012. {
  4013. struct json_token *pass, *psk_hex;
  4014. wpa_printf(MSG_DEBUG, "DPP: Legacy akm=psk credential");
  4015. pass = json_get_member(cred, "pass");
  4016. psk_hex = json_get_member(cred, "psk_hex");
  4017. if (pass && pass->type == JSON_STRING) {
  4018. size_t len = os_strlen(pass->string);
  4019. wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Legacy passphrase",
  4020. pass->string, len);
  4021. if (len < 8 || len > 63)
  4022. return -1;
  4023. os_strlcpy(auth->passphrase, pass->string,
  4024. sizeof(auth->passphrase));
  4025. } else if (psk_hex && psk_hex->type == JSON_STRING) {
  4026. if (auth->akm == DPP_AKM_SAE) {
  4027. wpa_printf(MSG_DEBUG,
  4028. "DPP: Unexpected psk_hex with akm=sae");
  4029. return -1;
  4030. }
  4031. if (os_strlen(psk_hex->string) != PMK_LEN * 2 ||
  4032. hexstr2bin(psk_hex->string, auth->psk, PMK_LEN) < 0) {
  4033. wpa_printf(MSG_DEBUG, "DPP: Invalid psk_hex encoding");
  4034. return -1;
  4035. }
  4036. wpa_hexdump_key(MSG_DEBUG, "DPP: Legacy PSK",
  4037. auth->psk, PMK_LEN);
  4038. auth->psk_set = 1;
  4039. } else {
  4040. wpa_printf(MSG_DEBUG, "DPP: No pass or psk_hex strings found");
  4041. return -1;
  4042. }
  4043. if ((auth->akm == DPP_AKM_SAE || auth->akm == DPP_AKM_PSK_SAE) &&
  4044. !auth->passphrase[0]) {
  4045. wpa_printf(MSG_DEBUG, "DPP: No pass for sae found");
  4046. return -1;
  4047. }
  4048. return 0;
  4049. }
  4050. static EVP_PKEY * dpp_parse_jwk(struct json_token *jwk,
  4051. const struct dpp_curve_params **key_curve)
  4052. {
  4053. struct json_token *token;
  4054. const struct dpp_curve_params *curve;
  4055. struct wpabuf *x = NULL, *y = NULL;
  4056. EC_GROUP *group;
  4057. EVP_PKEY *pkey = NULL;
  4058. token = json_get_member(jwk, "kty");
  4059. if (!token || token->type != JSON_STRING) {
  4060. wpa_printf(MSG_DEBUG, "DPP: No kty in JWK");
  4061. goto fail;
  4062. }
  4063. if (os_strcmp(token->string, "EC") != 0) {
  4064. wpa_printf(MSG_DEBUG, "DPP: Unexpected JWK kty '%s",
  4065. token->string);
  4066. goto fail;
  4067. }
  4068. token = json_get_member(jwk, "crv");
  4069. if (!token || token->type != JSON_STRING) {
  4070. wpa_printf(MSG_DEBUG, "DPP: No crv in JWK");
  4071. goto fail;
  4072. }
  4073. curve = dpp_get_curve_jwk_crv(token->string);
  4074. if (!curve) {
  4075. wpa_printf(MSG_DEBUG, "DPP: Unsupported JWK crv '%s'",
  4076. token->string);
  4077. goto fail;
  4078. }
  4079. x = json_get_member_base64url(jwk, "x");
  4080. if (!x) {
  4081. wpa_printf(MSG_DEBUG, "DPP: No x in JWK");
  4082. goto fail;
  4083. }
  4084. wpa_hexdump_buf(MSG_DEBUG, "DPP: JWK x", x);
  4085. if (wpabuf_len(x) != curve->prime_len) {
  4086. wpa_printf(MSG_DEBUG,
  4087. "DPP: Unexpected JWK x length %u (expected %u for curve %s)",
  4088. (unsigned int) wpabuf_len(x),
  4089. (unsigned int) curve->prime_len, curve->name);
  4090. goto fail;
  4091. }
  4092. y = json_get_member_base64url(jwk, "y");
  4093. if (!y) {
  4094. wpa_printf(MSG_DEBUG, "DPP: No y in JWK");
  4095. goto fail;
  4096. }
  4097. wpa_hexdump_buf(MSG_DEBUG, "DPP: JWK y", y);
  4098. if (wpabuf_len(y) != curve->prime_len) {
  4099. wpa_printf(MSG_DEBUG,
  4100. "DPP: Unexpected JWK y length %u (expected %u for curve %s)",
  4101. (unsigned int) wpabuf_len(y),
  4102. (unsigned int) curve->prime_len, curve->name);
  4103. goto fail;
  4104. }
  4105. group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
  4106. if (!group) {
  4107. wpa_printf(MSG_DEBUG, "DPP: Could not prepare group for JWK");
  4108. goto fail;
  4109. }
  4110. pkey = dpp_set_pubkey_point_group(group, wpabuf_head(x), wpabuf_head(y),
  4111. wpabuf_len(x));
  4112. *key_curve = curve;
  4113. fail:
  4114. wpabuf_free(x);
  4115. wpabuf_free(y);
  4116. return pkey;
  4117. }
  4118. int dpp_key_expired(const char *timestamp, os_time_t *expiry)
  4119. {
  4120. struct os_time now;
  4121. unsigned int year, month, day, hour, min, sec;
  4122. os_time_t utime;
  4123. const char *pos;
  4124. /* ISO 8601 date and time:
  4125. * <date>T<time>
  4126. * YYYY-MM-DDTHH:MM:SSZ
  4127. * YYYY-MM-DDTHH:MM:SS+03:00
  4128. */
  4129. if (os_strlen(timestamp) < 19) {
  4130. wpa_printf(MSG_DEBUG,
  4131. "DPP: Too short timestamp - assume expired key");
  4132. return 1;
  4133. }
  4134. if (sscanf(timestamp, "%04u-%02u-%02uT%02u:%02u:%02u",
  4135. &year, &month, &day, &hour, &min, &sec) != 6) {
  4136. wpa_printf(MSG_DEBUG,
  4137. "DPP: Failed to parse expiration day - assume expired key");
  4138. return 1;
  4139. }
  4140. if (os_mktime(year, month, day, hour, min, sec, &utime) < 0) {
  4141. wpa_printf(MSG_DEBUG,
  4142. "DPP: Invalid date/time information - assume expired key");
  4143. return 1;
  4144. }
  4145. pos = timestamp + 19;
  4146. if (*pos == 'Z' || *pos == '\0') {
  4147. /* In UTC - no need to adjust */
  4148. } else if (*pos == '-' || *pos == '+') {
  4149. int items;
  4150. /* Adjust local time to UTC */
  4151. items = sscanf(pos + 1, "%02u:%02u", &hour, &min);
  4152. if (items < 1) {
  4153. wpa_printf(MSG_DEBUG,
  4154. "DPP: Invalid time zone designator (%s) - assume expired key",
  4155. pos);
  4156. return 1;
  4157. }
  4158. if (*pos == '-')
  4159. utime += 3600 * hour;
  4160. if (*pos == '+')
  4161. utime -= 3600 * hour;
  4162. if (items > 1) {
  4163. if (*pos == '-')
  4164. utime += 60 * min;
  4165. if (*pos == '+')
  4166. utime -= 60 * min;
  4167. }
  4168. } else {
  4169. wpa_printf(MSG_DEBUG,
  4170. "DPP: Invalid time zone designator (%s) - assume expired key",
  4171. pos);
  4172. return 1;
  4173. }
  4174. if (expiry)
  4175. *expiry = utime;
  4176. if (os_get_time(&now) < 0) {
  4177. wpa_printf(MSG_DEBUG,
  4178. "DPP: Cannot get current time - assume expired key");
  4179. return 1;
  4180. }
  4181. if (now.sec > utime) {
  4182. wpa_printf(MSG_DEBUG, "DPP: Key has expired (%lu < %lu)",
  4183. utime, now.sec);
  4184. return 1;
  4185. }
  4186. return 0;
  4187. }
  4188. static int dpp_parse_connector(struct dpp_authentication *auth,
  4189. const unsigned char *payload,
  4190. u16 payload_len)
  4191. {
  4192. struct json_token *root, *groups, *netkey, *token;
  4193. int ret = -1;
  4194. EVP_PKEY *key = NULL;
  4195. const struct dpp_curve_params *curve;
  4196. unsigned int rules = 0;
  4197. root = json_parse((const char *) payload, payload_len);
  4198. if (!root) {
  4199. wpa_printf(MSG_DEBUG, "DPP: JSON parsing of connector failed");
  4200. goto fail;
  4201. }
  4202. groups = json_get_member(root, "groups");
  4203. if (!groups || groups->type != JSON_ARRAY) {
  4204. wpa_printf(MSG_DEBUG, "DPP: No groups array found");
  4205. goto skip_groups;
  4206. }
  4207. for (token = groups->child; token; token = token->sibling) {
  4208. struct json_token *id, *role;
  4209. id = json_get_member(token, "groupId");
  4210. if (!id || id->type != JSON_STRING) {
  4211. wpa_printf(MSG_DEBUG, "DPP: Missing groupId string");
  4212. goto fail;
  4213. }
  4214. role = json_get_member(token, "netRole");
  4215. if (!role || role->type != JSON_STRING) {
  4216. wpa_printf(MSG_DEBUG, "DPP: Missing netRole string");
  4217. goto fail;
  4218. }
  4219. wpa_printf(MSG_DEBUG,
  4220. "DPP: connector group: groupId='%s' netRole='%s'",
  4221. id->string, role->string);
  4222. rules++;
  4223. }
  4224. skip_groups:
  4225. if (!rules) {
  4226. wpa_printf(MSG_DEBUG,
  4227. "DPP: Connector includes no groups");
  4228. goto fail;
  4229. }
  4230. token = json_get_member(root, "expiry");
  4231. if (!token || token->type != JSON_STRING) {
  4232. wpa_printf(MSG_DEBUG,
  4233. "DPP: No expiry string found - connector does not expire");
  4234. } else {
  4235. wpa_printf(MSG_DEBUG, "DPP: expiry = %s", token->string);
  4236. if (dpp_key_expired(token->string,
  4237. &auth->net_access_key_expiry)) {
  4238. wpa_printf(MSG_DEBUG,
  4239. "DPP: Connector (netAccessKey) has expired");
  4240. goto fail;
  4241. }
  4242. }
  4243. netkey = json_get_member(root, "netAccessKey");
  4244. if (!netkey || netkey->type != JSON_OBJECT) {
  4245. wpa_printf(MSG_DEBUG, "DPP: No netAccessKey object found");
  4246. goto fail;
  4247. }
  4248. key = dpp_parse_jwk(netkey, &curve);
  4249. if (!key)
  4250. goto fail;
  4251. dpp_debug_print_key("DPP: Received netAccessKey", key);
  4252. if (EVP_PKEY_cmp(key, auth->own_protocol_key) != 1) {
  4253. wpa_printf(MSG_DEBUG,
  4254. "DPP: netAccessKey in connector does not match own protocol key");
  4255. #ifdef CONFIG_TESTING_OPTIONS
  4256. if (auth->ignore_netaccesskey_mismatch) {
  4257. wpa_printf(MSG_DEBUG,
  4258. "DPP: TESTING - skip netAccessKey mismatch");
  4259. } else {
  4260. goto fail;
  4261. }
  4262. #else /* CONFIG_TESTING_OPTIONS */
  4263. goto fail;
  4264. #endif /* CONFIG_TESTING_OPTIONS */
  4265. }
  4266. ret = 0;
  4267. fail:
  4268. EVP_PKEY_free(key);
  4269. json_free(root);
  4270. return ret;
  4271. }
  4272. static int dpp_check_pubkey_match(EVP_PKEY *pub, struct wpabuf *r_hash)
  4273. {
  4274. struct wpabuf *uncomp;
  4275. int res;
  4276. u8 hash[SHA256_MAC_LEN];
  4277. const u8 *addr[1];
  4278. size_t len[1];
  4279. if (wpabuf_len(r_hash) != SHA256_MAC_LEN)
  4280. return -1;
  4281. uncomp = dpp_get_pubkey_point(pub, 1);
  4282. if (!uncomp)
  4283. return -1;
  4284. addr[0] = wpabuf_head(uncomp);
  4285. len[0] = wpabuf_len(uncomp);
  4286. wpa_hexdump(MSG_DEBUG, "DPP: Uncompressed public key",
  4287. addr[0], len[0]);
  4288. res = sha256_vector(1, addr, len, hash);
  4289. wpabuf_free(uncomp);
  4290. if (res < 0)
  4291. return -1;
  4292. if (os_memcmp(hash, wpabuf_head(r_hash), SHA256_MAC_LEN) != 0) {
  4293. wpa_printf(MSG_DEBUG,
  4294. "DPP: Received hash value does not match calculated public key hash value");
  4295. wpa_hexdump(MSG_DEBUG, "DPP: Calculated hash",
  4296. hash, SHA256_MAC_LEN);
  4297. return -1;
  4298. }
  4299. return 0;
  4300. }
  4301. static void dpp_copy_csign(struct dpp_authentication *auth, EVP_PKEY *csign)
  4302. {
  4303. unsigned char *der = NULL;
  4304. int der_len;
  4305. der_len = i2d_PUBKEY(csign, &der);
  4306. if (der_len <= 0)
  4307. return;
  4308. wpabuf_free(auth->c_sign_key);
  4309. auth->c_sign_key = wpabuf_alloc_copy(der, der_len);
  4310. OPENSSL_free(der);
  4311. }
  4312. static void dpp_copy_netaccesskey(struct dpp_authentication *auth)
  4313. {
  4314. unsigned char *der = NULL;
  4315. int der_len;
  4316. EC_KEY *eckey;
  4317. eckey = EVP_PKEY_get1_EC_KEY(auth->own_protocol_key);
  4318. if (!eckey)
  4319. return;
  4320. der_len = i2d_ECPrivateKey(eckey, &der);
  4321. if (der_len <= 0) {
  4322. EC_KEY_free(eckey);
  4323. return;
  4324. }
  4325. wpabuf_free(auth->net_access_key);
  4326. auth->net_access_key = wpabuf_alloc_copy(der, der_len);
  4327. OPENSSL_free(der);
  4328. EC_KEY_free(eckey);
  4329. }
  4330. struct dpp_signed_connector_info {
  4331. unsigned char *payload;
  4332. size_t payload_len;
  4333. };
  4334. static enum dpp_status_error
  4335. dpp_process_signed_connector(struct dpp_signed_connector_info *info,
  4336. EVP_PKEY *csign_pub, const char *connector)
  4337. {
  4338. enum dpp_status_error ret = 255;
  4339. const char *pos, *end, *signed_start, *signed_end;
  4340. struct wpabuf *kid = NULL;
  4341. unsigned char *prot_hdr = NULL, *signature = NULL;
  4342. size_t prot_hdr_len = 0, signature_len = 0;
  4343. const EVP_MD *sign_md = NULL;
  4344. unsigned char *der = NULL;
  4345. int der_len;
  4346. int res;
  4347. EVP_MD_CTX *md_ctx = NULL;
  4348. ECDSA_SIG *sig = NULL;
  4349. BIGNUM *r = NULL, *s = NULL;
  4350. const struct dpp_curve_params *curve;
  4351. EC_KEY *eckey;
  4352. const EC_GROUP *group;
  4353. int nid;
  4354. eckey = EVP_PKEY_get1_EC_KEY(csign_pub);
  4355. if (!eckey)
  4356. goto fail;
  4357. group = EC_KEY_get0_group(eckey);
  4358. if (!group)
  4359. goto fail;
  4360. nid = EC_GROUP_get_curve_name(group);
  4361. curve = dpp_get_curve_nid(nid);
  4362. if (!curve)
  4363. goto fail;
  4364. wpa_printf(MSG_DEBUG, "DPP: C-sign-key group: %s", curve->jwk_crv);
  4365. os_memset(info, 0, sizeof(*info));
  4366. signed_start = pos = connector;
  4367. end = os_strchr(pos, '.');
  4368. if (!end) {
  4369. wpa_printf(MSG_DEBUG, "DPP: Missing dot(1) in signedConnector");
  4370. ret = DPP_STATUS_INVALID_CONNECTOR;
  4371. goto fail;
  4372. }
  4373. prot_hdr = base64_url_decode((const unsigned char *) pos,
  4374. end - pos, &prot_hdr_len);
  4375. if (!prot_hdr) {
  4376. wpa_printf(MSG_DEBUG,
  4377. "DPP: Failed to base64url decode signedConnector JWS Protected Header");
  4378. ret = DPP_STATUS_INVALID_CONNECTOR;
  4379. goto fail;
  4380. }
  4381. wpa_hexdump_ascii(MSG_DEBUG,
  4382. "DPP: signedConnector - JWS Protected Header",
  4383. prot_hdr, prot_hdr_len);
  4384. kid = dpp_parse_jws_prot_hdr(curve, prot_hdr, prot_hdr_len, &sign_md);
  4385. if (!kid) {
  4386. ret = DPP_STATUS_INVALID_CONNECTOR;
  4387. goto fail;
  4388. }
  4389. if (wpabuf_len(kid) != SHA256_MAC_LEN) {
  4390. wpa_printf(MSG_DEBUG,
  4391. "DPP: Unexpected signedConnector JWS Protected Header kid length: %u (expected %u)",
  4392. (unsigned int) wpabuf_len(kid), SHA256_MAC_LEN);
  4393. ret = DPP_STATUS_INVALID_CONNECTOR;
  4394. goto fail;
  4395. }
  4396. pos = end + 1;
  4397. end = os_strchr(pos, '.');
  4398. if (!end) {
  4399. wpa_printf(MSG_DEBUG,
  4400. "DPP: Missing dot(2) in signedConnector");
  4401. ret = DPP_STATUS_INVALID_CONNECTOR;
  4402. goto fail;
  4403. }
  4404. signed_end = end - 1;
  4405. info->payload = base64_url_decode((const unsigned char *) pos,
  4406. end - pos, &info->payload_len);
  4407. if (!info->payload) {
  4408. wpa_printf(MSG_DEBUG,
  4409. "DPP: Failed to base64url decode signedConnector JWS Payload");
  4410. ret = DPP_STATUS_INVALID_CONNECTOR;
  4411. goto fail;
  4412. }
  4413. wpa_hexdump_ascii(MSG_DEBUG,
  4414. "DPP: signedConnector - JWS Payload",
  4415. info->payload, info->payload_len);
  4416. pos = end + 1;
  4417. signature = base64_url_decode((const unsigned char *) pos,
  4418. os_strlen(pos), &signature_len);
  4419. if (!signature) {
  4420. wpa_printf(MSG_DEBUG,
  4421. "DPP: Failed to base64url decode signedConnector signature");
  4422. ret = DPP_STATUS_INVALID_CONNECTOR;
  4423. goto fail;
  4424. }
  4425. wpa_hexdump(MSG_DEBUG, "DPP: signedConnector - signature",
  4426. signature, signature_len);
  4427. if (dpp_check_pubkey_match(csign_pub, kid) < 0) {
  4428. ret = DPP_STATUS_NO_MATCH;
  4429. goto fail;
  4430. }
  4431. if (signature_len & 0x01) {
  4432. wpa_printf(MSG_DEBUG,
  4433. "DPP: Unexpected signedConnector signature length (%d)",
  4434. (int) signature_len);
  4435. ret = DPP_STATUS_INVALID_CONNECTOR;
  4436. goto fail;
  4437. }
  4438. /* JWS Signature encodes the signature (r,s) as two octet strings. Need
  4439. * to convert that to DER encoded ECDSA_SIG for OpenSSL EVP routines. */
  4440. r = BN_bin2bn(signature, signature_len / 2, NULL);
  4441. s = BN_bin2bn(signature + signature_len / 2, signature_len / 2, NULL);
  4442. sig = ECDSA_SIG_new();
  4443. if (!r || !s || !sig || ECDSA_SIG_set0(sig, r, s) != 1)
  4444. goto fail;
  4445. r = NULL;
  4446. s = NULL;
  4447. der_len = i2d_ECDSA_SIG(sig, &der);
  4448. if (der_len <= 0) {
  4449. wpa_printf(MSG_DEBUG, "DPP: Could not DER encode signature");
  4450. goto fail;
  4451. }
  4452. wpa_hexdump(MSG_DEBUG, "DPP: DER encoded signature", der, der_len);
  4453. md_ctx = EVP_MD_CTX_create();
  4454. if (!md_ctx)
  4455. goto fail;
  4456. ERR_clear_error();
  4457. if (EVP_DigestVerifyInit(md_ctx, NULL, sign_md, NULL, csign_pub) != 1) {
  4458. wpa_printf(MSG_DEBUG, "DPP: EVP_DigestVerifyInit failed: %s",
  4459. ERR_error_string(ERR_get_error(), NULL));
  4460. goto fail;
  4461. }
  4462. if (EVP_DigestVerifyUpdate(md_ctx, signed_start,
  4463. signed_end - signed_start + 1) != 1) {
  4464. wpa_printf(MSG_DEBUG, "DPP: EVP_DigestVerifyUpdate failed: %s",
  4465. ERR_error_string(ERR_get_error(), NULL));
  4466. goto fail;
  4467. }
  4468. res = EVP_DigestVerifyFinal(md_ctx, der, der_len);
  4469. if (res != 1) {
  4470. wpa_printf(MSG_DEBUG,
  4471. "DPP: EVP_DigestVerifyFinal failed (res=%d): %s",
  4472. res, ERR_error_string(ERR_get_error(), NULL));
  4473. ret = DPP_STATUS_INVALID_CONNECTOR;
  4474. goto fail;
  4475. }
  4476. ret = DPP_STATUS_OK;
  4477. fail:
  4478. EC_KEY_free(eckey);
  4479. EVP_MD_CTX_destroy(md_ctx);
  4480. os_free(prot_hdr);
  4481. wpabuf_free(kid);
  4482. os_free(signature);
  4483. ECDSA_SIG_free(sig);
  4484. BN_free(r);
  4485. BN_free(s);
  4486. OPENSSL_free(der);
  4487. return ret;
  4488. }
  4489. static int dpp_parse_cred_dpp(struct dpp_authentication *auth,
  4490. struct json_token *cred)
  4491. {
  4492. struct dpp_signed_connector_info info;
  4493. struct json_token *token, *csign;
  4494. int ret = -1;
  4495. EVP_PKEY *csign_pub = NULL;
  4496. const struct dpp_curve_params *key_curve = NULL;
  4497. const char *signed_connector;
  4498. os_memset(&info, 0, sizeof(info));
  4499. wpa_printf(MSG_DEBUG, "DPP: Connector credential");
  4500. csign = json_get_member(cred, "csign");
  4501. if (!csign || csign->type != JSON_OBJECT) {
  4502. wpa_printf(MSG_DEBUG, "DPP: No csign JWK in JSON");
  4503. goto fail;
  4504. }
  4505. csign_pub = dpp_parse_jwk(csign, &key_curve);
  4506. if (!csign_pub) {
  4507. wpa_printf(MSG_DEBUG, "DPP: Failed to parse csign JWK");
  4508. goto fail;
  4509. }
  4510. dpp_debug_print_key("DPP: Received C-sign-key", csign_pub);
  4511. token = json_get_member(cred, "signedConnector");
  4512. if (!token || token->type != JSON_STRING) {
  4513. wpa_printf(MSG_DEBUG, "DPP: No signedConnector string found");
  4514. goto fail;
  4515. }
  4516. wpa_hexdump_ascii(MSG_DEBUG, "DPP: signedConnector",
  4517. token->string, os_strlen(token->string));
  4518. signed_connector = token->string;
  4519. if (os_strchr(signed_connector, '"') ||
  4520. os_strchr(signed_connector, '\n')) {
  4521. wpa_printf(MSG_DEBUG,
  4522. "DPP: Unexpected character in signedConnector");
  4523. goto fail;
  4524. }
  4525. if (dpp_process_signed_connector(&info, csign_pub,
  4526. signed_connector) != DPP_STATUS_OK)
  4527. goto fail;
  4528. if (dpp_parse_connector(auth, info.payload, info.payload_len) < 0) {
  4529. wpa_printf(MSG_DEBUG, "DPP: Failed to parse connector");
  4530. goto fail;
  4531. }
  4532. os_free(auth->connector);
  4533. auth->connector = os_strdup(signed_connector);
  4534. dpp_copy_csign(auth, csign_pub);
  4535. dpp_copy_netaccesskey(auth);
  4536. ret = 0;
  4537. fail:
  4538. EVP_PKEY_free(csign_pub);
  4539. os_free(info.payload);
  4540. return ret;
  4541. }
  4542. const char * dpp_akm_str(enum dpp_akm akm)
  4543. {
  4544. switch (akm) {
  4545. case DPP_AKM_DPP:
  4546. return "dpp";
  4547. case DPP_AKM_PSK:
  4548. return "psk";
  4549. case DPP_AKM_SAE:
  4550. return "sae";
  4551. case DPP_AKM_PSK_SAE:
  4552. return "psk+sae";
  4553. default:
  4554. return "??";
  4555. }
  4556. }
  4557. static enum dpp_akm dpp_akm_from_str(const char *akm)
  4558. {
  4559. if (os_strcmp(akm, "psk") == 0)
  4560. return DPP_AKM_PSK;
  4561. if (os_strcmp(akm, "sae") == 0)
  4562. return DPP_AKM_SAE;
  4563. if (os_strcmp(akm, "psk+sae") == 0)
  4564. return DPP_AKM_PSK_SAE;
  4565. if (os_strcmp(akm, "dpp") == 0)
  4566. return DPP_AKM_DPP;
  4567. return DPP_AKM_UNKNOWN;
  4568. }
  4569. static int dpp_parse_conf_obj(struct dpp_authentication *auth,
  4570. const u8 *conf_obj, u16 conf_obj_len)
  4571. {
  4572. int ret = -1;
  4573. struct json_token *root, *token, *discovery, *cred;
  4574. root = json_parse((const char *) conf_obj, conf_obj_len);
  4575. if (!root)
  4576. return -1;
  4577. if (root->type != JSON_OBJECT) {
  4578. dpp_auth_fail(auth, "JSON root is not an object");
  4579. goto fail;
  4580. }
  4581. token = json_get_member(root, "wi-fi_tech");
  4582. if (!token || token->type != JSON_STRING) {
  4583. dpp_auth_fail(auth, "No wi-fi_tech string value found");
  4584. goto fail;
  4585. }
  4586. if (os_strcmp(token->string, "infra") != 0) {
  4587. wpa_printf(MSG_DEBUG, "DPP: Unsupported wi-fi_tech value: '%s'",
  4588. token->string);
  4589. dpp_auth_fail(auth, "Unsupported wi-fi_tech value");
  4590. goto fail;
  4591. }
  4592. discovery = json_get_member(root, "discovery");
  4593. if (!discovery || discovery->type != JSON_OBJECT) {
  4594. dpp_auth_fail(auth, "No discovery object in JSON");
  4595. goto fail;
  4596. }
  4597. token = json_get_member(discovery, "ssid");
  4598. if (!token || token->type != JSON_STRING) {
  4599. dpp_auth_fail(auth, "No discovery::ssid string value found");
  4600. goto fail;
  4601. }
  4602. wpa_hexdump_ascii(MSG_DEBUG, "DPP: discovery::ssid",
  4603. token->string, os_strlen(token->string));
  4604. if (os_strlen(token->string) > SSID_MAX_LEN) {
  4605. dpp_auth_fail(auth, "Too long discovery::ssid string value");
  4606. goto fail;
  4607. }
  4608. auth->ssid_len = os_strlen(token->string);
  4609. os_memcpy(auth->ssid, token->string, auth->ssid_len);
  4610. cred = json_get_member(root, "cred");
  4611. if (!cred || cred->type != JSON_OBJECT) {
  4612. dpp_auth_fail(auth, "No cred object in JSON");
  4613. goto fail;
  4614. }
  4615. token = json_get_member(cred, "akm");
  4616. if (!token || token->type != JSON_STRING) {
  4617. dpp_auth_fail(auth, "No cred::akm string value found");
  4618. goto fail;
  4619. }
  4620. auth->akm = dpp_akm_from_str(token->string);
  4621. if (auth->akm == DPP_AKM_PSK || auth->akm == DPP_AKM_SAE ||
  4622. auth->akm == DPP_AKM_PSK_SAE) {
  4623. if (dpp_parse_cred_legacy(auth, cred) < 0)
  4624. goto fail;
  4625. } else if (auth->akm == DPP_AKM_DPP) {
  4626. if (dpp_parse_cred_dpp(auth, cred) < 0)
  4627. goto fail;
  4628. } else {
  4629. wpa_printf(MSG_DEBUG, "DPP: Unsupported akm: %s",
  4630. token->string);
  4631. dpp_auth_fail(auth, "Unsupported akm");
  4632. goto fail;
  4633. }
  4634. wpa_printf(MSG_DEBUG, "DPP: JSON parsing completed successfully");
  4635. ret = 0;
  4636. fail:
  4637. json_free(root);
  4638. return ret;
  4639. }
  4640. int dpp_conf_resp_rx(struct dpp_authentication *auth,
  4641. const struct wpabuf *resp)
  4642. {
  4643. const u8 *wrapped_data, *e_nonce, *status, *conf_obj;
  4644. u16 wrapped_data_len, e_nonce_len, status_len, conf_obj_len;
  4645. const u8 *addr[1];
  4646. size_t len[1];
  4647. u8 *unwrapped = NULL;
  4648. size_t unwrapped_len = 0;
  4649. int ret = -1;
  4650. if (dpp_check_attrs(wpabuf_head(resp), wpabuf_len(resp)) < 0) {
  4651. dpp_auth_fail(auth, "Invalid attribute in config response");
  4652. return -1;
  4653. }
  4654. wrapped_data = dpp_get_attr(wpabuf_head(resp), wpabuf_len(resp),
  4655. DPP_ATTR_WRAPPED_DATA,
  4656. &wrapped_data_len);
  4657. if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
  4658. dpp_auth_fail(auth,
  4659. "Missing or invalid required Wrapped Data attribute");
  4660. return -1;
  4661. }
  4662. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  4663. wrapped_data, wrapped_data_len);
  4664. unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
  4665. unwrapped = os_malloc(unwrapped_len);
  4666. if (!unwrapped)
  4667. return -1;
  4668. addr[0] = wpabuf_head(resp);
  4669. len[0] = wrapped_data - 4 - (const u8 *) wpabuf_head(resp);
  4670. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD", addr[0], len[0]);
  4671. if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
  4672. wrapped_data, wrapped_data_len,
  4673. 1, addr, len, unwrapped) < 0) {
  4674. dpp_auth_fail(auth, "AES-SIV decryption failed");
  4675. goto fail;
  4676. }
  4677. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
  4678. unwrapped, unwrapped_len);
  4679. if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
  4680. dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
  4681. goto fail;
  4682. }
  4683. e_nonce = dpp_get_attr(unwrapped, unwrapped_len,
  4684. DPP_ATTR_ENROLLEE_NONCE,
  4685. &e_nonce_len);
  4686. if (!e_nonce || e_nonce_len != auth->curve->nonce_len) {
  4687. dpp_auth_fail(auth,
  4688. "Missing or invalid Enrollee Nonce attribute");
  4689. goto fail;
  4690. }
  4691. wpa_hexdump(MSG_DEBUG, "DPP: Enrollee Nonce", e_nonce, e_nonce_len);
  4692. if (os_memcmp(e_nonce, auth->e_nonce, e_nonce_len) != 0) {
  4693. dpp_auth_fail(auth, "Enrollee Nonce mismatch");
  4694. goto fail;
  4695. }
  4696. status = dpp_get_attr(wpabuf_head(resp), wpabuf_len(resp),
  4697. DPP_ATTR_STATUS, &status_len);
  4698. if (!status || status_len < 1) {
  4699. dpp_auth_fail(auth,
  4700. "Missing or invalid required DPP Status attribute");
  4701. goto fail;
  4702. }
  4703. wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
  4704. if (status[0] != DPP_STATUS_OK) {
  4705. dpp_auth_fail(auth, "Configurator rejected configuration");
  4706. goto fail;
  4707. }
  4708. conf_obj = dpp_get_attr(unwrapped, unwrapped_len,
  4709. DPP_ATTR_CONFIG_OBJ, &conf_obj_len);
  4710. if (!conf_obj) {
  4711. dpp_auth_fail(auth,
  4712. "Missing required Configuration Object attribute");
  4713. goto fail;
  4714. }
  4715. wpa_hexdump_ascii(MSG_DEBUG, "DPP: configurationObject JSON",
  4716. conf_obj, conf_obj_len);
  4717. if (dpp_parse_conf_obj(auth, conf_obj, conf_obj_len) < 0)
  4718. goto fail;
  4719. ret = 0;
  4720. fail:
  4721. os_free(unwrapped);
  4722. return ret;
  4723. }
  4724. void dpp_configurator_free(struct dpp_configurator *conf)
  4725. {
  4726. if (!conf)
  4727. return;
  4728. EVP_PKEY_free(conf->csign);
  4729. os_free(conf->kid);
  4730. os_free(conf);
  4731. }
  4732. struct dpp_configurator *
  4733. dpp_keygen_configurator(const char *curve, const u8 *privkey,
  4734. size_t privkey_len)
  4735. {
  4736. struct dpp_configurator *conf;
  4737. struct wpabuf *csign_pub = NULL;
  4738. u8 kid_hash[SHA256_MAC_LEN];
  4739. const u8 *addr[1];
  4740. size_t len[1];
  4741. conf = os_zalloc(sizeof(*conf));
  4742. if (!conf)
  4743. return NULL;
  4744. if (!curve) {
  4745. conf->curve = &dpp_curves[0];
  4746. } else {
  4747. conf->curve = dpp_get_curve_name(curve);
  4748. if (!conf->curve) {
  4749. wpa_printf(MSG_INFO, "DPP: Unsupported curve: %s",
  4750. curve);
  4751. return NULL;
  4752. }
  4753. }
  4754. if (privkey)
  4755. conf->csign = dpp_set_keypair(&conf->curve, privkey,
  4756. privkey_len);
  4757. else
  4758. conf->csign = dpp_gen_keypair(conf->curve);
  4759. if (!conf->csign)
  4760. goto fail;
  4761. conf->own = 1;
  4762. csign_pub = dpp_get_pubkey_point(conf->csign, 1);
  4763. if (!csign_pub) {
  4764. wpa_printf(MSG_INFO, "DPP: Failed to extract C-sign-key");
  4765. goto fail;
  4766. }
  4767. /* kid = SHA256(ANSI X9.63 uncompressed C-sign-key) */
  4768. addr[0] = wpabuf_head(csign_pub);
  4769. len[0] = wpabuf_len(csign_pub);
  4770. if (sha256_vector(1, addr, len, kid_hash) < 0) {
  4771. wpa_printf(MSG_DEBUG,
  4772. "DPP: Failed to derive kid for C-sign-key");
  4773. goto fail;
  4774. }
  4775. conf->kid = (char *) base64_url_encode(kid_hash, sizeof(kid_hash),
  4776. NULL, 0);
  4777. if (!conf->kid)
  4778. goto fail;
  4779. out:
  4780. wpabuf_free(csign_pub);
  4781. return conf;
  4782. fail:
  4783. dpp_configurator_free(conf);
  4784. conf = NULL;
  4785. goto out;
  4786. }
  4787. int dpp_configurator_own_config(struct dpp_authentication *auth,
  4788. const char *curve, int ap)
  4789. {
  4790. struct wpabuf *conf_obj;
  4791. int ret = -1;
  4792. if (!auth->conf) {
  4793. wpa_printf(MSG_DEBUG, "DPP: No configurator specified");
  4794. return -1;
  4795. }
  4796. if (!curve) {
  4797. auth->curve = &dpp_curves[0];
  4798. } else {
  4799. auth->curve = dpp_get_curve_name(curve);
  4800. if (!auth->curve) {
  4801. wpa_printf(MSG_INFO, "DPP: Unsupported curve: %s",
  4802. curve);
  4803. return -1;
  4804. }
  4805. }
  4806. wpa_printf(MSG_DEBUG,
  4807. "DPP: Building own configuration/connector with curve %s",
  4808. auth->curve->name);
  4809. auth->own_protocol_key = dpp_gen_keypair(auth->curve);
  4810. if (!auth->own_protocol_key)
  4811. return -1;
  4812. dpp_copy_netaccesskey(auth);
  4813. auth->peer_protocol_key = auth->own_protocol_key;
  4814. dpp_copy_csign(auth, auth->conf->csign);
  4815. conf_obj = dpp_build_conf_obj(auth, ap);
  4816. if (!conf_obj)
  4817. goto fail;
  4818. ret = dpp_parse_conf_obj(auth, wpabuf_head(conf_obj),
  4819. wpabuf_len(conf_obj));
  4820. fail:
  4821. wpabuf_free(conf_obj);
  4822. auth->peer_protocol_key = NULL;
  4823. return ret;
  4824. }
  4825. static int dpp_compatible_netrole(const char *role1, const char *role2)
  4826. {
  4827. return (os_strcmp(role1, "sta") == 0 && os_strcmp(role2, "ap") == 0) ||
  4828. (os_strcmp(role1, "ap") == 0 && os_strcmp(role2, "sta") == 0);
  4829. }
  4830. static int dpp_connector_compatible_group(struct json_token *root,
  4831. const char *group_id,
  4832. const char *net_role)
  4833. {
  4834. struct json_token *groups, *token;
  4835. groups = json_get_member(root, "groups");
  4836. if (!groups || groups->type != JSON_ARRAY)
  4837. return 0;
  4838. for (token = groups->child; token; token = token->sibling) {
  4839. struct json_token *id, *role;
  4840. id = json_get_member(token, "groupId");
  4841. if (!id || id->type != JSON_STRING)
  4842. continue;
  4843. role = json_get_member(token, "netRole");
  4844. if (!role || role->type != JSON_STRING)
  4845. continue;
  4846. if (os_strcmp(id->string, "*") != 0 &&
  4847. os_strcmp(group_id, "*") != 0 &&
  4848. os_strcmp(id->string, group_id) != 0)
  4849. continue;
  4850. if (dpp_compatible_netrole(role->string, net_role))
  4851. return 1;
  4852. }
  4853. return 0;
  4854. }
  4855. static int dpp_connector_match_groups(struct json_token *own_root,
  4856. struct json_token *peer_root)
  4857. {
  4858. struct json_token *groups, *token;
  4859. groups = json_get_member(peer_root, "groups");
  4860. if (!groups || groups->type != JSON_ARRAY) {
  4861. wpa_printf(MSG_DEBUG, "DPP: No peer groups array found");
  4862. return 0;
  4863. }
  4864. for (token = groups->child; token; token = token->sibling) {
  4865. struct json_token *id, *role;
  4866. id = json_get_member(token, "groupId");
  4867. if (!id || id->type != JSON_STRING) {
  4868. wpa_printf(MSG_DEBUG,
  4869. "DPP: Missing peer groupId string");
  4870. continue;
  4871. }
  4872. role = json_get_member(token, "netRole");
  4873. if (!role || role->type != JSON_STRING) {
  4874. wpa_printf(MSG_DEBUG,
  4875. "DPP: Missing peer groups::netRole string");
  4876. continue;
  4877. }
  4878. wpa_printf(MSG_DEBUG,
  4879. "DPP: peer connector group: groupId='%s' netRole='%s'",
  4880. id->string, role->string);
  4881. if (dpp_connector_compatible_group(own_root, id->string,
  4882. role->string)) {
  4883. wpa_printf(MSG_DEBUG,
  4884. "DPP: Compatible group/netRole in own connector");
  4885. return 1;
  4886. }
  4887. }
  4888. return 0;
  4889. }
  4890. static int dpp_derive_pmk(const u8 *Nx, size_t Nx_len, u8 *pmk,
  4891. unsigned int hash_len)
  4892. {
  4893. u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN];
  4894. const char *info = "DPP PMK";
  4895. int res;
  4896. /* PMK = HKDF(<>, "DPP PMK", N.x) */
  4897. /* HKDF-Extract(<>, N.x) */
  4898. os_memset(salt, 0, hash_len);
  4899. if (dpp_hmac(hash_len, salt, hash_len, Nx, Nx_len, prk) < 0)
  4900. return -1;
  4901. wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM=N.x)",
  4902. prk, hash_len);
  4903. /* HKDF-Expand(PRK, info, L) */
  4904. res = dpp_hkdf_expand(hash_len, prk, hash_len, info, pmk, hash_len);
  4905. os_memset(prk, 0, hash_len);
  4906. if (res < 0)
  4907. return -1;
  4908. wpa_hexdump_key(MSG_DEBUG, "DPP: PMK = HKDF-Expand(PRK, info, L)",
  4909. pmk, hash_len);
  4910. return 0;
  4911. }
  4912. static int dpp_derive_pmkid(const struct dpp_curve_params *curve,
  4913. EVP_PKEY *own_key, EVP_PKEY *peer_key, u8 *pmkid)
  4914. {
  4915. struct wpabuf *nkx, *pkx;
  4916. int ret = -1, res;
  4917. const u8 *addr[2];
  4918. size_t len[2];
  4919. u8 hash[SHA256_MAC_LEN];
  4920. /* PMKID = Truncate-128(H(min(NK.x, PK.x) | max(NK.x, PK.x))) */
  4921. nkx = dpp_get_pubkey_point(own_key, 0);
  4922. pkx = dpp_get_pubkey_point(peer_key, 0);
  4923. if (!nkx || !pkx)
  4924. goto fail;
  4925. addr[0] = wpabuf_head(nkx);
  4926. len[0] = wpabuf_len(nkx) / 2;
  4927. addr[1] = wpabuf_head(pkx);
  4928. len[1] = wpabuf_len(pkx) / 2;
  4929. if (len[0] != len[1])
  4930. goto fail;
  4931. if (os_memcmp(addr[0], addr[1], len[0]) > 0) {
  4932. addr[0] = wpabuf_head(pkx);
  4933. addr[1] = wpabuf_head(nkx);
  4934. }
  4935. wpa_hexdump(MSG_DEBUG, "DPP: PMKID hash payload 1", addr[0], len[0]);
  4936. wpa_hexdump(MSG_DEBUG, "DPP: PMKID hash payload 2", addr[1], len[1]);
  4937. res = sha256_vector(2, addr, len, hash);
  4938. if (res < 0)
  4939. goto fail;
  4940. wpa_hexdump(MSG_DEBUG, "DPP: PMKID hash output", hash, SHA256_MAC_LEN);
  4941. os_memcpy(pmkid, hash, PMKID_LEN);
  4942. wpa_hexdump(MSG_DEBUG, "DPP: PMKID", pmkid, PMKID_LEN);
  4943. ret = 0;
  4944. fail:
  4945. wpabuf_free(nkx);
  4946. wpabuf_free(pkx);
  4947. return ret;
  4948. }
  4949. enum dpp_status_error
  4950. dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
  4951. const u8 *net_access_key, size_t net_access_key_len,
  4952. const u8 *csign_key, size_t csign_key_len,
  4953. const u8 *peer_connector, size_t peer_connector_len,
  4954. os_time_t *expiry)
  4955. {
  4956. struct json_token *root = NULL, *netkey, *token;
  4957. struct json_token *own_root = NULL;
  4958. enum dpp_status_error ret = 255, res;
  4959. EVP_PKEY *own_key = NULL, *peer_key = NULL;
  4960. struct wpabuf *own_key_pub = NULL;
  4961. const struct dpp_curve_params *curve, *own_curve;
  4962. struct dpp_signed_connector_info info;
  4963. const unsigned char *p;
  4964. EVP_PKEY *csign = NULL;
  4965. char *signed_connector = NULL;
  4966. const char *pos, *end;
  4967. unsigned char *own_conn = NULL;
  4968. size_t own_conn_len;
  4969. EVP_PKEY_CTX *ctx = NULL;
  4970. size_t Nx_len;
  4971. u8 Nx[DPP_MAX_SHARED_SECRET_LEN];
  4972. os_memset(intro, 0, sizeof(*intro));
  4973. os_memset(&info, 0, sizeof(info));
  4974. if (expiry)
  4975. *expiry = 0;
  4976. p = csign_key;
  4977. csign = d2i_PUBKEY(NULL, &p, csign_key_len);
  4978. if (!csign) {
  4979. wpa_printf(MSG_ERROR,
  4980. "DPP: Failed to parse local C-sign-key information");
  4981. goto fail;
  4982. }
  4983. own_key = dpp_set_keypair(&own_curve, net_access_key,
  4984. net_access_key_len);
  4985. if (!own_key) {
  4986. wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey");
  4987. goto fail;
  4988. }
  4989. pos = os_strchr(own_connector, '.');
  4990. if (!pos) {
  4991. wpa_printf(MSG_DEBUG, "DPP: Own connector is missing the first dot (.)");
  4992. goto fail;
  4993. }
  4994. pos++;
  4995. end = os_strchr(pos, '.');
  4996. if (!end) {
  4997. wpa_printf(MSG_DEBUG, "DPP: Own connector is missing the second dot (.)");
  4998. goto fail;
  4999. }
  5000. own_conn = base64_url_decode((const unsigned char *) pos,
  5001. end - pos, &own_conn_len);
  5002. if (!own_conn) {
  5003. wpa_printf(MSG_DEBUG,
  5004. "DPP: Failed to base64url decode own signedConnector JWS Payload");
  5005. goto fail;
  5006. }
  5007. own_root = json_parse((const char *) own_conn, own_conn_len);
  5008. if (!own_root) {
  5009. wpa_printf(MSG_DEBUG, "DPP: Failed to parse local connector");
  5010. goto fail;
  5011. }
  5012. wpa_hexdump_ascii(MSG_DEBUG, "DPP: Peer signedConnector",
  5013. peer_connector, peer_connector_len);
  5014. signed_connector = os_malloc(peer_connector_len + 1);
  5015. if (!signed_connector)
  5016. goto fail;
  5017. os_memcpy(signed_connector, peer_connector, peer_connector_len);
  5018. signed_connector[peer_connector_len] = '\0';
  5019. res = dpp_process_signed_connector(&info, csign, signed_connector);
  5020. if (res != DPP_STATUS_OK) {
  5021. ret = res;
  5022. goto fail;
  5023. }
  5024. root = json_parse((const char *) info.payload, info.payload_len);
  5025. if (!root) {
  5026. wpa_printf(MSG_DEBUG, "DPP: JSON parsing of connector failed");
  5027. ret = DPP_STATUS_INVALID_CONNECTOR;
  5028. goto fail;
  5029. }
  5030. if (!dpp_connector_match_groups(own_root, root)) {
  5031. wpa_printf(MSG_DEBUG,
  5032. "DPP: Peer connector does not include compatible group netrole with own connector");
  5033. ret = DPP_STATUS_NO_MATCH;
  5034. goto fail;
  5035. }
  5036. token = json_get_member(root, "expiry");
  5037. if (!token || token->type != JSON_STRING) {
  5038. wpa_printf(MSG_DEBUG,
  5039. "DPP: No expiry string found - connector does not expire");
  5040. } else {
  5041. wpa_printf(MSG_DEBUG, "DPP: expiry = %s", token->string);
  5042. if (dpp_key_expired(token->string, expiry)) {
  5043. wpa_printf(MSG_DEBUG,
  5044. "DPP: Connector (netAccessKey) has expired");
  5045. ret = DPP_STATUS_INVALID_CONNECTOR;
  5046. goto fail;
  5047. }
  5048. }
  5049. netkey = json_get_member(root, "netAccessKey");
  5050. if (!netkey || netkey->type != JSON_OBJECT) {
  5051. wpa_printf(MSG_DEBUG, "DPP: No netAccessKey object found");
  5052. ret = DPP_STATUS_INVALID_CONNECTOR;
  5053. goto fail;
  5054. }
  5055. peer_key = dpp_parse_jwk(netkey, &curve);
  5056. if (!peer_key) {
  5057. ret = DPP_STATUS_INVALID_CONNECTOR;
  5058. goto fail;
  5059. }
  5060. dpp_debug_print_key("DPP: Received netAccessKey", peer_key);
  5061. if (own_curve != curve) {
  5062. wpa_printf(MSG_DEBUG,
  5063. "DPP: Mismatching netAccessKey curves (%s != %s)",
  5064. own_curve->name, curve->name);
  5065. ret = DPP_STATUS_INVALID_CONNECTOR;
  5066. goto fail;
  5067. }
  5068. /* ECDH: N = nk * PK */
  5069. ctx = EVP_PKEY_CTX_new(own_key, NULL);
  5070. if (!ctx ||
  5071. EVP_PKEY_derive_init(ctx) != 1 ||
  5072. EVP_PKEY_derive_set_peer(ctx, peer_key) != 1 ||
  5073. EVP_PKEY_derive(ctx, NULL, &Nx_len) != 1 ||
  5074. Nx_len > DPP_MAX_SHARED_SECRET_LEN ||
  5075. EVP_PKEY_derive(ctx, Nx, &Nx_len) != 1) {
  5076. wpa_printf(MSG_ERROR,
  5077. "DPP: Failed to derive ECDH shared secret: %s",
  5078. ERR_error_string(ERR_get_error(), NULL));
  5079. goto fail;
  5080. }
  5081. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)",
  5082. Nx, Nx_len);
  5083. /* PMK = HKDF(<>, "DPP PMK", N.x) */
  5084. if (dpp_derive_pmk(Nx, Nx_len, intro->pmk, curve->hash_len) < 0) {
  5085. wpa_printf(MSG_ERROR, "DPP: Failed to derive PMK");
  5086. goto fail;
  5087. }
  5088. intro->pmk_len = curve->hash_len;
  5089. /* PMKID = Truncate-128(H(min(NK.x, PK.x) | max(NK.x, PK.x))) */
  5090. if (dpp_derive_pmkid(curve, own_key, peer_key, intro->pmkid) < 0) {
  5091. wpa_printf(MSG_ERROR, "DPP: Failed to derive PMKID");
  5092. goto fail;
  5093. }
  5094. ret = DPP_STATUS_OK;
  5095. fail:
  5096. if (ret != DPP_STATUS_OK)
  5097. os_memset(intro, 0, sizeof(*intro));
  5098. os_memset(Nx, 0, sizeof(Nx));
  5099. EVP_PKEY_CTX_free(ctx);
  5100. os_free(own_conn);
  5101. os_free(signed_connector);
  5102. os_free(info.payload);
  5103. EVP_PKEY_free(own_key);
  5104. wpabuf_free(own_key_pub);
  5105. EVP_PKEY_free(peer_key);
  5106. EVP_PKEY_free(csign);
  5107. json_free(root);
  5108. json_free(own_root);
  5109. return ret;
  5110. }
  5111. static EVP_PKEY * dpp_pkex_get_role_elem(const struct dpp_curve_params *curve,
  5112. int init)
  5113. {
  5114. EC_GROUP *group;
  5115. size_t len = curve->prime_len;
  5116. const u8 *x, *y;
  5117. switch (curve->ike_group) {
  5118. case 19:
  5119. x = init ? pkex_init_x_p256 : pkex_resp_x_p256;
  5120. y = init ? pkex_init_y_p256 : pkex_resp_y_p256;
  5121. break;
  5122. case 20:
  5123. x = init ? pkex_init_x_p384 : pkex_resp_x_p384;
  5124. y = init ? pkex_init_y_p384 : pkex_resp_y_p384;
  5125. break;
  5126. case 21:
  5127. x = init ? pkex_init_x_p521 : pkex_resp_x_p521;
  5128. y = init ? pkex_init_y_p521 : pkex_resp_y_p521;
  5129. break;
  5130. case 28:
  5131. x = init ? pkex_init_x_bp_p256r1 : pkex_resp_x_bp_p256r1;
  5132. y = init ? pkex_init_y_bp_p256r1 : pkex_resp_y_bp_p256r1;
  5133. break;
  5134. case 29:
  5135. x = init ? pkex_init_x_bp_p384r1 : pkex_resp_x_bp_p384r1;
  5136. y = init ? pkex_init_y_bp_p384r1 : pkex_resp_y_bp_p384r1;
  5137. break;
  5138. case 30:
  5139. x = init ? pkex_init_x_bp_p512r1 : pkex_resp_x_bp_p512r1;
  5140. y = init ? pkex_init_y_bp_p512r1 : pkex_resp_y_bp_p512r1;
  5141. break;
  5142. default:
  5143. return NULL;
  5144. }
  5145. group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
  5146. if (!group)
  5147. return NULL;
  5148. return dpp_set_pubkey_point_group(group, x, y, len);
  5149. }
  5150. static EC_POINT * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
  5151. const u8 *mac_init, const char *code,
  5152. const char *identifier, BN_CTX *bnctx,
  5153. const EC_GROUP **ret_group)
  5154. {
  5155. u8 hash[DPP_MAX_HASH_LEN];
  5156. const u8 *addr[3];
  5157. size_t len[3];
  5158. unsigned int num_elem = 0;
  5159. EC_POINT *Qi = NULL;
  5160. EVP_PKEY *Pi = NULL;
  5161. EC_KEY *Pi_ec = NULL;
  5162. const EC_POINT *Pi_point;
  5163. BIGNUM *hash_bn = NULL;
  5164. const EC_GROUP *group = NULL;
  5165. EC_GROUP *group2 = NULL;
  5166. /* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
  5167. wpa_printf(MSG_DEBUG, "DPP: MAC-Initiator: " MACSTR, MAC2STR(mac_init));
  5168. addr[num_elem] = mac_init;
  5169. len[num_elem] = ETH_ALEN;
  5170. num_elem++;
  5171. if (identifier) {
  5172. wpa_printf(MSG_DEBUG, "DPP: code identifier: %s",
  5173. identifier);
  5174. addr[num_elem] = (const u8 *) identifier;
  5175. len[num_elem] = os_strlen(identifier);
  5176. num_elem++;
  5177. }
  5178. wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: code", code, os_strlen(code));
  5179. addr[num_elem] = (const u8 *) code;
  5180. len[num_elem] = os_strlen(code);
  5181. num_elem++;
  5182. if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0)
  5183. goto fail;
  5184. wpa_hexdump_key(MSG_DEBUG,
  5185. "DPP: H(MAC-Initiator | [identifier |] code)",
  5186. hash, curve->hash_len);
  5187. Pi = dpp_pkex_get_role_elem(curve, 1);
  5188. if (!Pi)
  5189. goto fail;
  5190. dpp_debug_print_key("DPP: Pi", Pi);
  5191. Pi_ec = EVP_PKEY_get1_EC_KEY(Pi);
  5192. if (!Pi_ec)
  5193. goto fail;
  5194. Pi_point = EC_KEY_get0_public_key(Pi_ec);
  5195. group = EC_KEY_get0_group(Pi_ec);
  5196. if (!group)
  5197. goto fail;
  5198. group2 = EC_GROUP_dup(group);
  5199. if (!group2)
  5200. goto fail;
  5201. Qi = EC_POINT_new(group2);
  5202. if (!Qi) {
  5203. EC_GROUP_free(group2);
  5204. goto fail;
  5205. }
  5206. hash_bn = BN_bin2bn(hash, curve->hash_len, NULL);
  5207. if (!hash_bn ||
  5208. EC_POINT_mul(group2, Qi, NULL, Pi_point, hash_bn, bnctx) != 1)
  5209. goto fail;
  5210. if (EC_POINT_is_at_infinity(group, Qi)) {
  5211. wpa_printf(MSG_INFO, "DPP: Qi is the point-at-infinity");
  5212. goto fail;
  5213. }
  5214. dpp_debug_print_point("DPP: Qi", group, Qi);
  5215. out:
  5216. EC_KEY_free(Pi_ec);
  5217. EVP_PKEY_free(Pi);
  5218. BN_clear_free(hash_bn);
  5219. if (ret_group)
  5220. *ret_group = group2;
  5221. return Qi;
  5222. fail:
  5223. EC_POINT_free(Qi);
  5224. Qi = NULL;
  5225. goto out;
  5226. }
  5227. static EC_POINT * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
  5228. const u8 *mac_resp, const char *code,
  5229. const char *identifier, BN_CTX *bnctx,
  5230. const EC_GROUP **ret_group)
  5231. {
  5232. u8 hash[DPP_MAX_HASH_LEN];
  5233. const u8 *addr[3];
  5234. size_t len[3];
  5235. unsigned int num_elem = 0;
  5236. EC_POINT *Qr = NULL;
  5237. EVP_PKEY *Pr = NULL;
  5238. EC_KEY *Pr_ec = NULL;
  5239. const EC_POINT *Pr_point;
  5240. BIGNUM *hash_bn = NULL;
  5241. const EC_GROUP *group = NULL;
  5242. EC_GROUP *group2 = NULL;
  5243. /* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
  5244. wpa_printf(MSG_DEBUG, "DPP: MAC-Responder: " MACSTR, MAC2STR(mac_resp));
  5245. addr[num_elem] = mac_resp;
  5246. len[num_elem] = ETH_ALEN;
  5247. num_elem++;
  5248. if (identifier) {
  5249. wpa_printf(MSG_DEBUG, "DPP: code identifier: %s",
  5250. identifier);
  5251. addr[num_elem] = (const u8 *) identifier;
  5252. len[num_elem] = os_strlen(identifier);
  5253. num_elem++;
  5254. }
  5255. wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: code", code, os_strlen(code));
  5256. addr[num_elem] = (const u8 *) code;
  5257. len[num_elem] = os_strlen(code);
  5258. num_elem++;
  5259. if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0)
  5260. goto fail;
  5261. wpa_hexdump_key(MSG_DEBUG,
  5262. "DPP: H(MAC-Responder | [identifier |] code)",
  5263. hash, curve->hash_len);
  5264. Pr = dpp_pkex_get_role_elem(curve, 0);
  5265. if (!Pr)
  5266. goto fail;
  5267. dpp_debug_print_key("DPP: Pr", Pr);
  5268. Pr_ec = EVP_PKEY_get1_EC_KEY(Pr);
  5269. if (!Pr_ec)
  5270. goto fail;
  5271. Pr_point = EC_KEY_get0_public_key(Pr_ec);
  5272. group = EC_KEY_get0_group(Pr_ec);
  5273. if (!group)
  5274. goto fail;
  5275. group2 = EC_GROUP_dup(group);
  5276. if (!group2)
  5277. goto fail;
  5278. Qr = EC_POINT_new(group2);
  5279. if (!Qr) {
  5280. EC_GROUP_free(group2);
  5281. goto fail;
  5282. }
  5283. hash_bn = BN_bin2bn(hash, curve->hash_len, NULL);
  5284. if (!hash_bn ||
  5285. EC_POINT_mul(group2, Qr, NULL, Pr_point, hash_bn, bnctx) != 1)
  5286. goto fail;
  5287. if (EC_POINT_is_at_infinity(group, Qr)) {
  5288. wpa_printf(MSG_INFO, "DPP: Qr is the point-at-infinity");
  5289. goto fail;
  5290. }
  5291. dpp_debug_print_point("DPP: Qr", group, Qr);
  5292. out:
  5293. EC_KEY_free(Pr_ec);
  5294. EVP_PKEY_free(Pr);
  5295. BN_clear_free(hash_bn);
  5296. if (ret_group)
  5297. *ret_group = group2;
  5298. return Qr;
  5299. fail:
  5300. EC_POINT_free(Qr);
  5301. Qr = NULL;
  5302. goto out;
  5303. }
  5304. #ifdef CONFIG_TESTING_OPTIONS
  5305. static int dpp_test_gen_invalid_key(struct wpabuf *msg,
  5306. const struct dpp_curve_params *curve)
  5307. {
  5308. BN_CTX *ctx;
  5309. BIGNUM *x, *y;
  5310. int ret = -1;
  5311. EC_GROUP *group;
  5312. EC_POINT *point;
  5313. group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
  5314. if (!group)
  5315. return -1;
  5316. ctx = BN_CTX_new();
  5317. point = EC_POINT_new(group);
  5318. x = BN_new();
  5319. y = BN_new();
  5320. if (!ctx || !point || !x || !y)
  5321. goto fail;
  5322. if (BN_rand(x, curve->prime_len * 8, 0, 0) != 1)
  5323. goto fail;
  5324. /* Generate a random y coordinate that results in a point that is not
  5325. * on the curve. */
  5326. for (;;) {
  5327. if (BN_rand(y, curve->prime_len * 8, 0, 0) != 1)
  5328. goto fail;
  5329. if (EC_POINT_set_affine_coordinates_GFp(group, point, x, y,
  5330. ctx) != 1) {
  5331. #ifdef OPENSSL_IS_BORINGSSL
  5332. /* Unlike OpenSSL, BoringSSL returns an error from
  5333. * EC_POINT_set_affine_coordinates_GFp() is not on the curve. */
  5334. break;
  5335. #else /* OPENSSL_IS_BORINGSSL */
  5336. goto fail;
  5337. #endif /* OPENSSL_IS_BORINGSSL */
  5338. }
  5339. if (!EC_POINT_is_on_curve(group, point, ctx))
  5340. break;
  5341. }
  5342. if (dpp_bn2bin_pad(x, wpabuf_put(msg, curve->prime_len),
  5343. curve->prime_len) < 0 ||
  5344. dpp_bn2bin_pad(y, wpabuf_put(msg, curve->prime_len),
  5345. curve->prime_len) < 0)
  5346. goto fail;
  5347. ret = 0;
  5348. fail:
  5349. if (ret < 0)
  5350. wpa_printf(MSG_INFO, "DPP: Failed to generate invalid key");
  5351. BN_free(x);
  5352. BN_free(y);
  5353. EC_POINT_free(point);
  5354. BN_CTX_free(ctx);
  5355. return ret;
  5356. }
  5357. #endif /* CONFIG_TESTING_OPTIONS */
  5358. static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
  5359. {
  5360. EC_KEY *X_ec = NULL;
  5361. const EC_POINT *X_point;
  5362. BN_CTX *bnctx = NULL;
  5363. const EC_GROUP *group;
  5364. EC_POINT *Qi = NULL, *M = NULL;
  5365. struct wpabuf *M_buf = NULL;
  5366. BIGNUM *Mx = NULL, *My = NULL;
  5367. struct wpabuf *msg = NULL;
  5368. size_t attr_len;
  5369. const struct dpp_curve_params *curve = pkex->own_bi->curve;
  5370. wpa_printf(MSG_DEBUG, "DPP: Build PKEX Exchange Request");
  5371. /* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
  5372. bnctx = BN_CTX_new();
  5373. if (!bnctx)
  5374. goto fail;
  5375. Qi = dpp_pkex_derive_Qi(curve, pkex->own_mac, pkex->code,
  5376. pkex->identifier, bnctx, &group);
  5377. if (!Qi)
  5378. goto fail;
  5379. /* Generate a random ephemeral keypair x/X */
  5380. #ifdef CONFIG_TESTING_OPTIONS
  5381. if (dpp_pkex_ephemeral_key_override_len) {
  5382. const struct dpp_curve_params *tmp_curve;
  5383. wpa_printf(MSG_INFO,
  5384. "DPP: TESTING - override ephemeral key x/X");
  5385. pkex->x = dpp_set_keypair(&tmp_curve,
  5386. dpp_pkex_ephemeral_key_override,
  5387. dpp_pkex_ephemeral_key_override_len);
  5388. } else {
  5389. pkex->x = dpp_gen_keypair(curve);
  5390. }
  5391. #else /* CONFIG_TESTING_OPTIONS */
  5392. pkex->x = dpp_gen_keypair(curve);
  5393. #endif /* CONFIG_TESTING_OPTIONS */
  5394. if (!pkex->x)
  5395. goto fail;
  5396. /* M = X + Qi */
  5397. X_ec = EVP_PKEY_get1_EC_KEY(pkex->x);
  5398. if (!X_ec)
  5399. goto fail;
  5400. X_point = EC_KEY_get0_public_key(X_ec);
  5401. if (!X_point)
  5402. goto fail;
  5403. dpp_debug_print_point("DPP: X", group, X_point);
  5404. M = EC_POINT_new(group);
  5405. Mx = BN_new();
  5406. My = BN_new();
  5407. if (!M || !Mx || !My ||
  5408. EC_POINT_add(group, M, X_point, Qi, bnctx) != 1 ||
  5409. EC_POINT_get_affine_coordinates_GFp(group, M, Mx, My, bnctx) != 1)
  5410. goto fail;
  5411. dpp_debug_print_point("DPP: M", group, M);
  5412. /* Initiator -> Responder: group, [identifier,] M */
  5413. attr_len = 4 + 2;
  5414. if (pkex->identifier)
  5415. attr_len += 4 + os_strlen(pkex->identifier);
  5416. attr_len += 4 + 2 * curve->prime_len;
  5417. msg = dpp_alloc_msg(DPP_PA_PKEX_EXCHANGE_REQ, attr_len);
  5418. if (!msg)
  5419. goto fail;
  5420. #ifdef CONFIG_TESTING_OPTIONS
  5421. if (dpp_test == DPP_TEST_NO_FINITE_CYCLIC_GROUP_PKEX_EXCHANGE_REQ) {
  5422. wpa_printf(MSG_INFO, "DPP: TESTING - no Finite Cyclic Group");
  5423. goto skip_finite_cyclic_group;
  5424. }
  5425. #endif /* CONFIG_TESTING_OPTIONS */
  5426. /* Finite Cyclic Group attribute */
  5427. wpabuf_put_le16(msg, DPP_ATTR_FINITE_CYCLIC_GROUP);
  5428. wpabuf_put_le16(msg, 2);
  5429. wpabuf_put_le16(msg, curve->ike_group);
  5430. #ifdef CONFIG_TESTING_OPTIONS
  5431. skip_finite_cyclic_group:
  5432. #endif /* CONFIG_TESTING_OPTIONS */
  5433. /* Code Identifier attribute */
  5434. if (pkex->identifier) {
  5435. wpabuf_put_le16(msg, DPP_ATTR_CODE_IDENTIFIER);
  5436. wpabuf_put_le16(msg, os_strlen(pkex->identifier));
  5437. wpabuf_put_str(msg, pkex->identifier);
  5438. }
  5439. #ifdef CONFIG_TESTING_OPTIONS
  5440. if (dpp_test == DPP_TEST_NO_ENCRYPTED_KEY_PKEX_EXCHANGE_REQ) {
  5441. wpa_printf(MSG_INFO, "DPP: TESTING - no Encrypted Key");
  5442. goto out;
  5443. }
  5444. #endif /* CONFIG_TESTING_OPTIONS */
  5445. /* M in Encrypted Key attribute */
  5446. wpabuf_put_le16(msg, DPP_ATTR_ENCRYPTED_KEY);
  5447. wpabuf_put_le16(msg, 2 * curve->prime_len);
  5448. #ifdef CONFIG_TESTING_OPTIONS
  5449. if (dpp_test == DPP_TEST_INVALID_ENCRYPTED_KEY_PKEX_EXCHANGE_REQ) {
  5450. wpa_printf(MSG_INFO, "DPP: TESTING - invalid Encrypted Key");
  5451. if (dpp_test_gen_invalid_key(msg, curve) < 0)
  5452. goto fail;
  5453. goto out;
  5454. }
  5455. #endif /* CONFIG_TESTING_OPTIONS */
  5456. if (dpp_bn2bin_pad(Mx, wpabuf_put(msg, curve->prime_len),
  5457. curve->prime_len) < 0 ||
  5458. dpp_bn2bin_pad(Mx, pkex->Mx, curve->prime_len) < 0 ||
  5459. dpp_bn2bin_pad(My, wpabuf_put(msg, curve->prime_len),
  5460. curve->prime_len) < 0)
  5461. goto fail;
  5462. out:
  5463. wpabuf_free(M_buf);
  5464. EC_KEY_free(X_ec);
  5465. EC_POINT_free(M);
  5466. EC_POINT_free(Qi);
  5467. BN_clear_free(Mx);
  5468. BN_clear_free(My);
  5469. BN_CTX_free(bnctx);
  5470. return msg;
  5471. fail:
  5472. wpa_printf(MSG_INFO, "DPP: Failed to build PKEX Exchange Request");
  5473. wpabuf_free(msg);
  5474. msg = NULL;
  5475. goto out;
  5476. }
  5477. static void dpp_pkex_fail(struct dpp_pkex *pkex, const char *txt)
  5478. {
  5479. wpa_msg(pkex->msg_ctx, MSG_INFO, DPP_EVENT_FAIL "%s", txt);
  5480. }
  5481. struct dpp_pkex * dpp_pkex_init(void *msg_ctx, struct dpp_bootstrap_info *bi,
  5482. const u8 *own_mac,
  5483. const char *identifier,
  5484. const char *code)
  5485. {
  5486. struct dpp_pkex *pkex;
  5487. #ifdef CONFIG_TESTING_OPTIONS
  5488. if (!is_zero_ether_addr(dpp_pkex_own_mac_override)) {
  5489. wpa_printf(MSG_INFO, "DPP: TESTING - own_mac override " MACSTR,
  5490. MAC2STR(dpp_pkex_own_mac_override));
  5491. own_mac = dpp_pkex_own_mac_override;
  5492. }
  5493. #endif /* CONFIG_TESTING_OPTIONS */
  5494. pkex = os_zalloc(sizeof(*pkex));
  5495. if (!pkex)
  5496. return NULL;
  5497. pkex->msg_ctx = msg_ctx;
  5498. pkex->initiator = 1;
  5499. pkex->own_bi = bi;
  5500. os_memcpy(pkex->own_mac, own_mac, ETH_ALEN);
  5501. if (identifier) {
  5502. pkex->identifier = os_strdup(identifier);
  5503. if (!pkex->identifier)
  5504. goto fail;
  5505. }
  5506. pkex->code = os_strdup(code);
  5507. if (!pkex->code)
  5508. goto fail;
  5509. pkex->exchange_req = dpp_pkex_build_exchange_req(pkex);
  5510. if (!pkex->exchange_req)
  5511. goto fail;
  5512. return pkex;
  5513. fail:
  5514. dpp_pkex_free(pkex);
  5515. return NULL;
  5516. }
  5517. static struct wpabuf *
  5518. dpp_pkex_build_exchange_resp(struct dpp_pkex *pkex,
  5519. enum dpp_status_error status,
  5520. const BIGNUM *Nx, const BIGNUM *Ny)
  5521. {
  5522. struct wpabuf *msg = NULL;
  5523. size_t attr_len;
  5524. const struct dpp_curve_params *curve = pkex->own_bi->curve;
  5525. /* Initiator -> Responder: DPP Status, [identifier,] N */
  5526. attr_len = 4 + 1;
  5527. if (pkex->identifier)
  5528. attr_len += 4 + os_strlen(pkex->identifier);
  5529. attr_len += 4 + 2 * curve->prime_len;
  5530. msg = dpp_alloc_msg(DPP_PA_PKEX_EXCHANGE_RESP, attr_len);
  5531. if (!msg)
  5532. goto fail;
  5533. #ifdef CONFIG_TESTING_OPTIONS
  5534. if (dpp_test == DPP_TEST_NO_STATUS_PKEX_EXCHANGE_RESP) {
  5535. wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
  5536. goto skip_status;
  5537. }
  5538. if (dpp_test == DPP_TEST_INVALID_STATUS_PKEX_EXCHANGE_RESP) {
  5539. wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
  5540. status = 255;
  5541. }
  5542. #endif /* CONFIG_TESTING_OPTIONS */
  5543. /* DPP Status */
  5544. dpp_build_attr_status(msg, status);
  5545. #ifdef CONFIG_TESTING_OPTIONS
  5546. skip_status:
  5547. #endif /* CONFIG_TESTING_OPTIONS */
  5548. /* Code Identifier attribute */
  5549. if (pkex->identifier) {
  5550. wpabuf_put_le16(msg, DPP_ATTR_CODE_IDENTIFIER);
  5551. wpabuf_put_le16(msg, os_strlen(pkex->identifier));
  5552. wpabuf_put_str(msg, pkex->identifier);
  5553. }
  5554. if (status != DPP_STATUS_OK)
  5555. goto skip_encrypted_key;
  5556. #ifdef CONFIG_TESTING_OPTIONS
  5557. if (dpp_test == DPP_TEST_NO_ENCRYPTED_KEY_PKEX_EXCHANGE_RESP) {
  5558. wpa_printf(MSG_INFO, "DPP: TESTING - no Encrypted Key");
  5559. goto skip_encrypted_key;
  5560. }
  5561. #endif /* CONFIG_TESTING_OPTIONS */
  5562. /* N in Encrypted Key attribute */
  5563. wpabuf_put_le16(msg, DPP_ATTR_ENCRYPTED_KEY);
  5564. wpabuf_put_le16(msg, 2 * curve->prime_len);
  5565. #ifdef CONFIG_TESTING_OPTIONS
  5566. if (dpp_test == DPP_TEST_INVALID_ENCRYPTED_KEY_PKEX_EXCHANGE_RESP) {
  5567. wpa_printf(MSG_INFO, "DPP: TESTING - invalid Encrypted Key");
  5568. if (dpp_test_gen_invalid_key(msg, curve) < 0)
  5569. goto fail;
  5570. goto skip_encrypted_key;
  5571. }
  5572. #endif /* CONFIG_TESTING_OPTIONS */
  5573. if (dpp_bn2bin_pad(Nx, wpabuf_put(msg, curve->prime_len),
  5574. curve->prime_len) < 0 ||
  5575. dpp_bn2bin_pad(Nx, pkex->Nx, curve->prime_len) < 0 ||
  5576. dpp_bn2bin_pad(Ny, wpabuf_put(msg, curve->prime_len),
  5577. curve->prime_len) < 0)
  5578. goto fail;
  5579. skip_encrypted_key:
  5580. if (status == DPP_STATUS_BAD_GROUP) {
  5581. /* Finite Cyclic Group attribute */
  5582. wpabuf_put_le16(msg, DPP_ATTR_FINITE_CYCLIC_GROUP);
  5583. wpabuf_put_le16(msg, 2);
  5584. wpabuf_put_le16(msg, curve->ike_group);
  5585. }
  5586. return msg;
  5587. fail:
  5588. wpabuf_free(msg);
  5589. return NULL;
  5590. }
  5591. static int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
  5592. const u8 *Mx, size_t Mx_len,
  5593. const u8 *Nx, size_t Nx_len,
  5594. const char *code,
  5595. const u8 *Kx, size_t Kx_len,
  5596. u8 *z, unsigned int hash_len)
  5597. {
  5598. u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN];
  5599. int res;
  5600. u8 *info, *pos;
  5601. size_t info_len;
  5602. /* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x)
  5603. */
  5604. /* HKDF-Extract(<>, IKM=K.x) */
  5605. os_memset(salt, 0, hash_len);
  5606. if (dpp_hmac(hash_len, salt, hash_len, Kx, Kx_len, prk) < 0)
  5607. return -1;
  5608. wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM)",
  5609. prk, hash_len);
  5610. info_len = 2 * ETH_ALEN + Mx_len + Nx_len + os_strlen(code);
  5611. info = os_malloc(info_len);
  5612. if (!info)
  5613. return -1;
  5614. pos = info;
  5615. os_memcpy(pos, mac_init, ETH_ALEN);
  5616. pos += ETH_ALEN;
  5617. os_memcpy(pos, mac_resp, ETH_ALEN);
  5618. pos += ETH_ALEN;
  5619. os_memcpy(pos, Mx, Mx_len);
  5620. pos += Mx_len;
  5621. os_memcpy(pos, Nx, Nx_len);
  5622. pos += Nx_len;
  5623. os_memcpy(pos, code, os_strlen(code));
  5624. /* HKDF-Expand(PRK, info, L) */
  5625. if (hash_len == 32)
  5626. res = hmac_sha256_kdf(prk, hash_len, NULL, info, info_len,
  5627. z, hash_len);
  5628. else if (hash_len == 48)
  5629. res = hmac_sha384_kdf(prk, hash_len, NULL, info, info_len,
  5630. z, hash_len);
  5631. else if (hash_len == 64)
  5632. res = hmac_sha512_kdf(prk, hash_len, NULL, info, info_len,
  5633. z, hash_len);
  5634. else
  5635. res = -1;
  5636. os_free(info);
  5637. os_memset(prk, 0, hash_len);
  5638. if (res < 0)
  5639. return -1;
  5640. wpa_hexdump_key(MSG_DEBUG, "DPP: z = HKDF-Expand(PRK, info, L)",
  5641. z, hash_len);
  5642. return 0;
  5643. }
  5644. struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
  5645. struct dpp_bootstrap_info *bi,
  5646. const u8 *own_mac,
  5647. const u8 *peer_mac,
  5648. const char *identifier,
  5649. const char *code,
  5650. const u8 *buf, size_t len)
  5651. {
  5652. const u8 *attr_group, *attr_id, *attr_key;
  5653. u16 attr_group_len, attr_id_len, attr_key_len;
  5654. const struct dpp_curve_params *curve = bi->curve;
  5655. u16 ike_group;
  5656. struct dpp_pkex *pkex = NULL;
  5657. EC_POINT *Qi = NULL, *Qr = NULL, *M = NULL, *X = NULL, *N = NULL;
  5658. BN_CTX *bnctx = NULL;
  5659. const EC_GROUP *group;
  5660. BIGNUM *Mx = NULL, *My = NULL;
  5661. EC_KEY *Y_ec = NULL, *X_ec = NULL;;
  5662. const EC_POINT *Y_point;
  5663. BIGNUM *Nx = NULL, *Ny = NULL;
  5664. u8 Kx[DPP_MAX_SHARED_SECRET_LEN];
  5665. size_t Kx_len;
  5666. int res;
  5667. EVP_PKEY_CTX *ctx = NULL;
  5668. if (bi->pkex_t >= PKEX_COUNTER_T_LIMIT) {
  5669. wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
  5670. "PKEX counter t limit reached - ignore message");
  5671. return NULL;
  5672. }
  5673. #ifdef CONFIG_TESTING_OPTIONS
  5674. if (!is_zero_ether_addr(dpp_pkex_peer_mac_override)) {
  5675. wpa_printf(MSG_INFO, "DPP: TESTING - peer_mac override " MACSTR,
  5676. MAC2STR(dpp_pkex_peer_mac_override));
  5677. peer_mac = dpp_pkex_peer_mac_override;
  5678. }
  5679. if (!is_zero_ether_addr(dpp_pkex_own_mac_override)) {
  5680. wpa_printf(MSG_INFO, "DPP: TESTING - own_mac override " MACSTR,
  5681. MAC2STR(dpp_pkex_own_mac_override));
  5682. own_mac = dpp_pkex_own_mac_override;
  5683. }
  5684. #endif /* CONFIG_TESTING_OPTIONS */
  5685. attr_id = dpp_get_attr(buf, len, DPP_ATTR_CODE_IDENTIFIER,
  5686. &attr_id_len);
  5687. if (!attr_id && identifier) {
  5688. wpa_printf(MSG_DEBUG,
  5689. "DPP: No PKEX code identifier received, but expected one");
  5690. return NULL;
  5691. }
  5692. if (attr_id && identifier &&
  5693. (os_strlen(identifier) != attr_id_len ||
  5694. os_memcmp(identifier, attr_id, attr_id_len) != 0)) {
  5695. wpa_printf(MSG_DEBUG, "DPP: PKEX code identifier mismatch");
  5696. return NULL;
  5697. }
  5698. attr_group = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
  5699. &attr_group_len);
  5700. if (!attr_group || attr_group_len != 2) {
  5701. wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
  5702. "Missing or invalid Finite Cyclic Group attribute");
  5703. return NULL;
  5704. }
  5705. ike_group = WPA_GET_LE16(attr_group);
  5706. if (ike_group != curve->ike_group) {
  5707. wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
  5708. "Mismatching PKEX curve: peer=%u own=%u",
  5709. ike_group, curve->ike_group);
  5710. pkex = os_zalloc(sizeof(*pkex));
  5711. if (!pkex)
  5712. goto fail;
  5713. pkex->own_bi = bi;
  5714. pkex->failed = 1;
  5715. pkex->exchange_resp = dpp_pkex_build_exchange_resp(
  5716. pkex, DPP_STATUS_BAD_GROUP, NULL, NULL);
  5717. if (!pkex->exchange_resp)
  5718. goto fail;
  5719. return pkex;
  5720. }
  5721. /* M in Encrypted Key attribute */
  5722. attr_key = dpp_get_attr(buf, len, DPP_ATTR_ENCRYPTED_KEY,
  5723. &attr_key_len);
  5724. if (!attr_key || attr_key_len & 0x01 || attr_key_len < 2 ||
  5725. attr_key_len / 2 > DPP_MAX_SHARED_SECRET_LEN) {
  5726. wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
  5727. "Missing Encrypted Key attribute");
  5728. return NULL;
  5729. }
  5730. /* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
  5731. bnctx = BN_CTX_new();
  5732. if (!bnctx)
  5733. goto fail;
  5734. Qi = dpp_pkex_derive_Qi(curve, peer_mac, code, identifier, bnctx,
  5735. &group);
  5736. if (!Qi)
  5737. goto fail;
  5738. /* X' = M - Qi */
  5739. X = EC_POINT_new(group);
  5740. M = EC_POINT_new(group);
  5741. Mx = BN_bin2bn(attr_key, attr_key_len / 2, NULL);
  5742. My = BN_bin2bn(attr_key + attr_key_len / 2, attr_key_len / 2, NULL);
  5743. if (!X || !M || !Mx || !My ||
  5744. EC_POINT_set_affine_coordinates_GFp(group, M, Mx, My, bnctx) != 1 ||
  5745. EC_POINT_is_at_infinity(group, M) ||
  5746. !EC_POINT_is_on_curve(group, M, bnctx) ||
  5747. EC_POINT_invert(group, Qi, bnctx) != 1 ||
  5748. EC_POINT_add(group, X, M, Qi, bnctx) != 1 ||
  5749. EC_POINT_is_at_infinity(group, X) ||
  5750. !EC_POINT_is_on_curve(group, X, bnctx)) {
  5751. wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
  5752. "Invalid Encrypted Key value");
  5753. bi->pkex_t++;
  5754. goto fail;
  5755. }
  5756. dpp_debug_print_point("DPP: M", group, M);
  5757. dpp_debug_print_point("DPP: X'", group, X);
  5758. pkex = os_zalloc(sizeof(*pkex));
  5759. if (!pkex)
  5760. goto fail;
  5761. pkex->t = bi->pkex_t;
  5762. pkex->msg_ctx = msg_ctx;
  5763. pkex->own_bi = bi;
  5764. os_memcpy(pkex->own_mac, own_mac, ETH_ALEN);
  5765. os_memcpy(pkex->peer_mac, peer_mac, ETH_ALEN);
  5766. if (identifier) {
  5767. pkex->identifier = os_strdup(identifier);
  5768. if (!pkex->identifier)
  5769. goto fail;
  5770. }
  5771. pkex->code = os_strdup(code);
  5772. if (!pkex->code)
  5773. goto fail;
  5774. os_memcpy(pkex->Mx, attr_key, attr_key_len / 2);
  5775. X_ec = EC_KEY_new();
  5776. if (!X_ec ||
  5777. EC_KEY_set_group(X_ec, group) != 1 ||
  5778. EC_KEY_set_public_key(X_ec, X) != 1)
  5779. goto fail;
  5780. pkex->x = EVP_PKEY_new();
  5781. if (!pkex->x ||
  5782. EVP_PKEY_set1_EC_KEY(pkex->x, X_ec) != 1)
  5783. goto fail;
  5784. /* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
  5785. Qr = dpp_pkex_derive_Qr(curve, own_mac, code, identifier, bnctx, NULL);
  5786. if (!Qr)
  5787. goto fail;
  5788. /* Generate a random ephemeral keypair y/Y */
  5789. #ifdef CONFIG_TESTING_OPTIONS
  5790. if (dpp_pkex_ephemeral_key_override_len) {
  5791. const struct dpp_curve_params *tmp_curve;
  5792. wpa_printf(MSG_INFO,
  5793. "DPP: TESTING - override ephemeral key y/Y");
  5794. pkex->y = dpp_set_keypair(&tmp_curve,
  5795. dpp_pkex_ephemeral_key_override,
  5796. dpp_pkex_ephemeral_key_override_len);
  5797. } else {
  5798. pkex->y = dpp_gen_keypair(curve);
  5799. }
  5800. #else /* CONFIG_TESTING_OPTIONS */
  5801. pkex->y = dpp_gen_keypair(curve);
  5802. #endif /* CONFIG_TESTING_OPTIONS */
  5803. if (!pkex->y)
  5804. goto fail;
  5805. /* N = Y + Qr */
  5806. Y_ec = EVP_PKEY_get1_EC_KEY(pkex->y);
  5807. if (!Y_ec)
  5808. goto fail;
  5809. Y_point = EC_KEY_get0_public_key(Y_ec);
  5810. if (!Y_point)
  5811. goto fail;
  5812. dpp_debug_print_point("DPP: Y", group, Y_point);
  5813. N = EC_POINT_new(group);
  5814. Nx = BN_new();
  5815. Ny = BN_new();
  5816. if (!N || !Nx || !Ny ||
  5817. EC_POINT_add(group, N, Y_point, Qr, bnctx) != 1 ||
  5818. EC_POINT_get_affine_coordinates_GFp(group, N, Nx, Ny, bnctx) != 1)
  5819. goto fail;
  5820. dpp_debug_print_point("DPP: N", group, N);
  5821. pkex->exchange_resp = dpp_pkex_build_exchange_resp(pkex, DPP_STATUS_OK,
  5822. Nx, Ny);
  5823. if (!pkex->exchange_resp)
  5824. goto fail;
  5825. /* K = y * X' */
  5826. ctx = EVP_PKEY_CTX_new(pkex->y, NULL);
  5827. if (!ctx ||
  5828. EVP_PKEY_derive_init(ctx) != 1 ||
  5829. EVP_PKEY_derive_set_peer(ctx, pkex->x) != 1 ||
  5830. EVP_PKEY_derive(ctx, NULL, &Kx_len) != 1 ||
  5831. Kx_len > DPP_MAX_SHARED_SECRET_LEN ||
  5832. EVP_PKEY_derive(ctx, Kx, &Kx_len) != 1) {
  5833. wpa_printf(MSG_ERROR,
  5834. "DPP: Failed to derive ECDH shared secret: %s",
  5835. ERR_error_string(ERR_get_error(), NULL));
  5836. goto fail;
  5837. }
  5838. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (K.x)",
  5839. Kx, Kx_len);
  5840. /* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x)
  5841. */
  5842. res = dpp_pkex_derive_z(pkex->peer_mac, pkex->own_mac,
  5843. pkex->Mx, curve->prime_len,
  5844. pkex->Nx, curve->prime_len, pkex->code,
  5845. Kx, Kx_len, pkex->z, curve->hash_len);
  5846. os_memset(Kx, 0, Kx_len);
  5847. if (res < 0)
  5848. goto fail;
  5849. pkex->exchange_done = 1;
  5850. out:
  5851. EVP_PKEY_CTX_free(ctx);
  5852. BN_CTX_free(bnctx);
  5853. EC_POINT_free(Qi);
  5854. EC_POINT_free(Qr);
  5855. BN_free(Mx);
  5856. BN_free(My);
  5857. BN_free(Nx);
  5858. BN_free(Ny);
  5859. EC_POINT_free(M);
  5860. EC_POINT_free(N);
  5861. EC_POINT_free(X);
  5862. EC_KEY_free(X_ec);
  5863. EC_KEY_free(Y_ec);
  5864. return pkex;
  5865. fail:
  5866. wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request processing failed");
  5867. dpp_pkex_free(pkex);
  5868. pkex = NULL;
  5869. goto out;
  5870. }
  5871. static struct wpabuf *
  5872. dpp_pkex_build_commit_reveal_req(struct dpp_pkex *pkex,
  5873. const struct wpabuf *A_pub, const u8 *u)
  5874. {
  5875. const struct dpp_curve_params *curve = pkex->own_bi->curve;
  5876. struct wpabuf *msg = NULL;
  5877. size_t clear_len, attr_len;
  5878. struct wpabuf *clear = NULL;
  5879. u8 *wrapped;
  5880. u8 octet;
  5881. const u8 *addr[2];
  5882. size_t len[2];
  5883. /* {A, u, [bootstrapping info]}z */
  5884. clear_len = 4 + 2 * curve->prime_len + 4 + curve->hash_len;
  5885. clear = wpabuf_alloc(clear_len);
  5886. attr_len = 4 + clear_len + AES_BLOCK_SIZE;
  5887. #ifdef CONFIG_TESTING_OPTIONS
  5888. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_REQ)
  5889. attr_len += 5;
  5890. #endif /* CONFIG_TESTING_OPTIONS */
  5891. msg = dpp_alloc_msg(DPP_PA_PKEX_COMMIT_REVEAL_REQ, attr_len);
  5892. if (!clear || !msg)
  5893. goto fail;
  5894. #ifdef CONFIG_TESTING_OPTIONS
  5895. if (dpp_test == DPP_TEST_NO_BOOTSTRAP_KEY_PKEX_CR_REQ) {
  5896. wpa_printf(MSG_INFO, "DPP: TESTING - no Bootstrap Key");
  5897. goto skip_bootstrap_key;
  5898. }
  5899. if (dpp_test == DPP_TEST_INVALID_BOOTSTRAP_KEY_PKEX_CR_REQ) {
  5900. wpa_printf(MSG_INFO, "DPP: TESTING - invalid Bootstrap Key");
  5901. wpabuf_put_le16(clear, DPP_ATTR_BOOTSTRAP_KEY);
  5902. wpabuf_put_le16(clear, 2 * curve->prime_len);
  5903. if (dpp_test_gen_invalid_key(clear, curve) < 0)
  5904. goto fail;
  5905. goto skip_bootstrap_key;
  5906. }
  5907. #endif /* CONFIG_TESTING_OPTIONS */
  5908. /* A in Bootstrap Key attribute */
  5909. wpabuf_put_le16(clear, DPP_ATTR_BOOTSTRAP_KEY);
  5910. wpabuf_put_le16(clear, wpabuf_len(A_pub));
  5911. wpabuf_put_buf(clear, A_pub);
  5912. #ifdef CONFIG_TESTING_OPTIONS
  5913. skip_bootstrap_key:
  5914. if (dpp_test == DPP_TEST_NO_I_AUTH_TAG_PKEX_CR_REQ) {
  5915. wpa_printf(MSG_INFO, "DPP: TESTING - no I-Auth tag");
  5916. goto skip_i_auth_tag;
  5917. }
  5918. if (dpp_test == DPP_TEST_I_AUTH_TAG_MISMATCH_PKEX_CR_REQ) {
  5919. wpa_printf(MSG_INFO, "DPP: TESTING - I-Auth tag mismatch");
  5920. wpabuf_put_le16(clear, DPP_ATTR_I_AUTH_TAG);
  5921. wpabuf_put_le16(clear, curve->hash_len);
  5922. wpabuf_put_data(clear, u, curve->hash_len - 1);
  5923. wpabuf_put_u8(clear, u[curve->hash_len - 1] ^ 0x01);
  5924. goto skip_i_auth_tag;
  5925. }
  5926. #endif /* CONFIG_TESTING_OPTIONS */
  5927. /* u in I-Auth tag attribute */
  5928. wpabuf_put_le16(clear, DPP_ATTR_I_AUTH_TAG);
  5929. wpabuf_put_le16(clear, curve->hash_len);
  5930. wpabuf_put_data(clear, u, curve->hash_len);
  5931. #ifdef CONFIG_TESTING_OPTIONS
  5932. skip_i_auth_tag:
  5933. if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_PKEX_CR_REQ) {
  5934. wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data");
  5935. goto skip_wrapped_data;
  5936. }
  5937. #endif /* CONFIG_TESTING_OPTIONS */
  5938. addr[0] = wpabuf_head_u8(msg) + 2;
  5939. len[0] = DPP_HDR_LEN;
  5940. octet = 0;
  5941. addr[1] = &octet;
  5942. len[1] = sizeof(octet);
  5943. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  5944. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  5945. wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
  5946. wpabuf_put_le16(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
  5947. wrapped = wpabuf_put(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
  5948. wpa_hexdump_buf(MSG_DEBUG, "DPP: AES-SIV cleartext", clear);
  5949. if (aes_siv_encrypt(pkex->z, curve->hash_len,
  5950. wpabuf_head(clear), wpabuf_len(clear),
  5951. 2, addr, len, wrapped) < 0)
  5952. goto fail;
  5953. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  5954. wrapped, wpabuf_len(clear) + AES_BLOCK_SIZE);
  5955. #ifdef CONFIG_TESTING_OPTIONS
  5956. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_REQ) {
  5957. wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
  5958. dpp_build_attr_status(msg, DPP_STATUS_OK);
  5959. }
  5960. skip_wrapped_data:
  5961. #endif /* CONFIG_TESTING_OPTIONS */
  5962. out:
  5963. wpabuf_free(clear);
  5964. return msg;
  5965. fail:
  5966. wpabuf_free(msg);
  5967. msg = NULL;
  5968. goto out;
  5969. }
  5970. struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
  5971. const u8 *peer_mac,
  5972. const u8 *buf, size_t buflen)
  5973. {
  5974. const u8 *attr_status, *attr_id, *attr_key, *attr_group;
  5975. u16 attr_status_len, attr_id_len, attr_key_len, attr_group_len;
  5976. const EC_GROUP *group;
  5977. BN_CTX *bnctx = NULL;
  5978. struct wpabuf *msg = NULL, *A_pub = NULL, *X_pub = NULL, *Y_pub = NULL;
  5979. const struct dpp_curve_params *curve = pkex->own_bi->curve;
  5980. EC_POINT *Qr = NULL, *Y = NULL, *N = NULL;
  5981. BIGNUM *Nx = NULL, *Ny = NULL;
  5982. EVP_PKEY_CTX *ctx = NULL;
  5983. EC_KEY *Y_ec = NULL;
  5984. size_t Jx_len, Kx_len;
  5985. u8 Jx[DPP_MAX_SHARED_SECRET_LEN], Kx[DPP_MAX_SHARED_SECRET_LEN];
  5986. const u8 *addr[4];
  5987. size_t len[4];
  5988. u8 u[DPP_MAX_HASH_LEN];
  5989. int res;
  5990. if (pkex->failed || pkex->t >= PKEX_COUNTER_T_LIMIT || !pkex->initiator)
  5991. return NULL;
  5992. #ifdef CONFIG_TESTING_OPTIONS
  5993. if (!is_zero_ether_addr(dpp_pkex_peer_mac_override)) {
  5994. wpa_printf(MSG_INFO, "DPP: TESTING - peer_mac override " MACSTR,
  5995. MAC2STR(dpp_pkex_peer_mac_override));
  5996. peer_mac = dpp_pkex_peer_mac_override;
  5997. }
  5998. #endif /* CONFIG_TESTING_OPTIONS */
  5999. os_memcpy(pkex->peer_mac, peer_mac, ETH_ALEN);
  6000. attr_status = dpp_get_attr(buf, buflen, DPP_ATTR_STATUS,
  6001. &attr_status_len);
  6002. if (!attr_status || attr_status_len != 1) {
  6003. dpp_pkex_fail(pkex, "No DPP Status attribute");
  6004. return NULL;
  6005. }
  6006. wpa_printf(MSG_DEBUG, "DPP: Status %u", attr_status[0]);
  6007. if (attr_status[0] == DPP_STATUS_BAD_GROUP) {
  6008. attr_group = dpp_get_attr(buf, buflen,
  6009. DPP_ATTR_FINITE_CYCLIC_GROUP,
  6010. &attr_group_len);
  6011. if (attr_group && attr_group_len == 2) {
  6012. wpa_msg(pkex->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
  6013. "Peer indicated mismatching PKEX group - proposed %u",
  6014. WPA_GET_LE16(attr_group));
  6015. return NULL;
  6016. }
  6017. }
  6018. if (attr_status[0] != DPP_STATUS_OK) {
  6019. dpp_pkex_fail(pkex, "PKEX failed (peer indicated failure)");
  6020. return NULL;
  6021. }
  6022. attr_id = dpp_get_attr(buf, buflen, DPP_ATTR_CODE_IDENTIFIER,
  6023. &attr_id_len);
  6024. if (!attr_id && pkex->identifier) {
  6025. wpa_printf(MSG_DEBUG,
  6026. "DPP: No PKEX code identifier received, but expected one");
  6027. return NULL;
  6028. }
  6029. if (attr_id && pkex->identifier &&
  6030. (os_strlen(pkex->identifier) != attr_id_len ||
  6031. os_memcmp(pkex->identifier, attr_id, attr_id_len) != 0)) {
  6032. dpp_pkex_fail(pkex, "PKEX code identifier mismatch");
  6033. return NULL;
  6034. }
  6035. /* N in Encrypted Key attribute */
  6036. attr_key = dpp_get_attr(buf, buflen, DPP_ATTR_ENCRYPTED_KEY,
  6037. &attr_key_len);
  6038. if (!attr_key || attr_key_len & 0x01 || attr_key_len < 2) {
  6039. dpp_pkex_fail(pkex, "Missing Encrypted Key attribute");
  6040. return NULL;
  6041. }
  6042. /* Qr = H(MAC-Responder | [identifier |] code) * Pr */
  6043. bnctx = BN_CTX_new();
  6044. if (!bnctx)
  6045. goto fail;
  6046. Qr = dpp_pkex_derive_Qr(curve, pkex->peer_mac, pkex->code,
  6047. pkex->identifier, bnctx, &group);
  6048. if (!Qr)
  6049. goto fail;
  6050. /* Y' = N - Qr */
  6051. Y = EC_POINT_new(group);
  6052. N = EC_POINT_new(group);
  6053. Nx = BN_bin2bn(attr_key, attr_key_len / 2, NULL);
  6054. Ny = BN_bin2bn(attr_key + attr_key_len / 2, attr_key_len / 2, NULL);
  6055. if (!Y || !N || !Nx || !Ny ||
  6056. EC_POINT_set_affine_coordinates_GFp(group, N, Nx, Ny, bnctx) != 1 ||
  6057. EC_POINT_is_at_infinity(group, N) ||
  6058. !EC_POINT_is_on_curve(group, N, bnctx) ||
  6059. EC_POINT_invert(group, Qr, bnctx) != 1 ||
  6060. EC_POINT_add(group, Y, N, Qr, bnctx) != 1 ||
  6061. EC_POINT_is_at_infinity(group, Y) ||
  6062. !EC_POINT_is_on_curve(group, Y, bnctx)) {
  6063. dpp_pkex_fail(pkex, "Invalid Encrypted Key value");
  6064. pkex->t++;
  6065. goto fail;
  6066. }
  6067. dpp_debug_print_point("DPP: N", group, N);
  6068. dpp_debug_print_point("DPP: Y'", group, Y);
  6069. pkex->exchange_done = 1;
  6070. /* ECDH: J = a * Y’ */
  6071. Y_ec = EC_KEY_new();
  6072. if (!Y_ec ||
  6073. EC_KEY_set_group(Y_ec, group) != 1 ||
  6074. EC_KEY_set_public_key(Y_ec, Y) != 1)
  6075. goto fail;
  6076. pkex->y = EVP_PKEY_new();
  6077. if (!pkex->y ||
  6078. EVP_PKEY_set1_EC_KEY(pkex->y, Y_ec) != 1)
  6079. goto fail;
  6080. ctx = EVP_PKEY_CTX_new(pkex->own_bi->pubkey, NULL);
  6081. if (!ctx ||
  6082. EVP_PKEY_derive_init(ctx) != 1 ||
  6083. EVP_PKEY_derive_set_peer(ctx, pkex->y) != 1 ||
  6084. EVP_PKEY_derive(ctx, NULL, &Jx_len) != 1 ||
  6085. Jx_len > DPP_MAX_SHARED_SECRET_LEN ||
  6086. EVP_PKEY_derive(ctx, Jx, &Jx_len) != 1) {
  6087. wpa_printf(MSG_ERROR,
  6088. "DPP: Failed to derive ECDH shared secret: %s",
  6089. ERR_error_string(ERR_get_error(), NULL));
  6090. goto fail;
  6091. }
  6092. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (J.x)",
  6093. Jx, Jx_len);
  6094. /* u = HMAC(J.x, MAC-Initiator | A.x | Y’.x | X.x ) */
  6095. A_pub = dpp_get_pubkey_point(pkex->own_bi->pubkey, 0);
  6096. Y_pub = dpp_get_pubkey_point(pkex->y, 0);
  6097. X_pub = dpp_get_pubkey_point(pkex->x, 0);
  6098. if (!A_pub || !Y_pub || !X_pub)
  6099. goto fail;
  6100. addr[0] = pkex->own_mac;
  6101. len[0] = ETH_ALEN;
  6102. addr[1] = wpabuf_head(A_pub);
  6103. len[1] = wpabuf_len(A_pub) / 2;
  6104. addr[2] = wpabuf_head(Y_pub);
  6105. len[2] = wpabuf_len(Y_pub) / 2;
  6106. addr[3] = wpabuf_head(X_pub);
  6107. len[3] = wpabuf_len(X_pub) / 2;
  6108. if (dpp_hmac_vector(curve->hash_len, Jx, Jx_len, 4, addr, len, u) < 0)
  6109. goto fail;
  6110. wpa_hexdump(MSG_DEBUG, "DPP: u", u, curve->hash_len);
  6111. /* K = x * Y’ */
  6112. EVP_PKEY_CTX_free(ctx);
  6113. ctx = EVP_PKEY_CTX_new(pkex->x, NULL);
  6114. if (!ctx ||
  6115. EVP_PKEY_derive_init(ctx) != 1 ||
  6116. EVP_PKEY_derive_set_peer(ctx, pkex->y) != 1 ||
  6117. EVP_PKEY_derive(ctx, NULL, &Kx_len) != 1 ||
  6118. Kx_len > DPP_MAX_SHARED_SECRET_LEN ||
  6119. EVP_PKEY_derive(ctx, Kx, &Kx_len) != 1) {
  6120. wpa_printf(MSG_ERROR,
  6121. "DPP: Failed to derive ECDH shared secret: %s",
  6122. ERR_error_string(ERR_get_error(), NULL));
  6123. goto fail;
  6124. }
  6125. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (K.x)",
  6126. Kx, Kx_len);
  6127. /* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x)
  6128. */
  6129. res = dpp_pkex_derive_z(pkex->own_mac, pkex->peer_mac,
  6130. pkex->Mx, curve->prime_len,
  6131. attr_key /* N.x */, attr_key_len / 2,
  6132. pkex->code, Kx, Kx_len,
  6133. pkex->z, curve->hash_len);
  6134. os_memset(Kx, 0, Kx_len);
  6135. if (res < 0)
  6136. goto fail;
  6137. msg = dpp_pkex_build_commit_reveal_req(pkex, A_pub, u);
  6138. if (!msg)
  6139. goto fail;
  6140. out:
  6141. wpabuf_free(A_pub);
  6142. wpabuf_free(X_pub);
  6143. wpabuf_free(Y_pub);
  6144. EC_POINT_free(Qr);
  6145. EC_POINT_free(Y);
  6146. EC_POINT_free(N);
  6147. BN_free(Nx);
  6148. BN_free(Ny);
  6149. EC_KEY_free(Y_ec);
  6150. EVP_PKEY_CTX_free(ctx);
  6151. BN_CTX_free(bnctx);
  6152. return msg;
  6153. fail:
  6154. wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response processing failed");
  6155. goto out;
  6156. }
  6157. static struct wpabuf *
  6158. dpp_pkex_build_commit_reveal_resp(struct dpp_pkex *pkex,
  6159. const struct wpabuf *B_pub, const u8 *v)
  6160. {
  6161. const struct dpp_curve_params *curve = pkex->own_bi->curve;
  6162. struct wpabuf *msg = NULL;
  6163. const u8 *addr[2];
  6164. size_t len[2];
  6165. u8 octet;
  6166. u8 *wrapped;
  6167. struct wpabuf *clear = NULL;
  6168. size_t clear_len, attr_len;
  6169. /* {B, v [bootstrapping info]}z */
  6170. clear_len = 4 + 2 * curve->prime_len + 4 + curve->hash_len;
  6171. clear = wpabuf_alloc(clear_len);
  6172. attr_len = 4 + clear_len + AES_BLOCK_SIZE;
  6173. #ifdef CONFIG_TESTING_OPTIONS
  6174. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_RESP)
  6175. attr_len += 5;
  6176. #endif /* CONFIG_TESTING_OPTIONS */
  6177. msg = dpp_alloc_msg(DPP_PA_PKEX_COMMIT_REVEAL_RESP, attr_len);
  6178. if (!clear || !msg)
  6179. goto fail;
  6180. #ifdef CONFIG_TESTING_OPTIONS
  6181. if (dpp_test == DPP_TEST_NO_BOOTSTRAP_KEY_PKEX_CR_RESP) {
  6182. wpa_printf(MSG_INFO, "DPP: TESTING - no Bootstrap Key");
  6183. goto skip_bootstrap_key;
  6184. }
  6185. if (dpp_test == DPP_TEST_INVALID_BOOTSTRAP_KEY_PKEX_CR_RESP) {
  6186. wpa_printf(MSG_INFO, "DPP: TESTING - invalid Bootstrap Key");
  6187. wpabuf_put_le16(clear, DPP_ATTR_BOOTSTRAP_KEY);
  6188. wpabuf_put_le16(clear, 2 * curve->prime_len);
  6189. if (dpp_test_gen_invalid_key(clear, curve) < 0)
  6190. goto fail;
  6191. goto skip_bootstrap_key;
  6192. }
  6193. #endif /* CONFIG_TESTING_OPTIONS */
  6194. /* B in Bootstrap Key attribute */
  6195. wpabuf_put_le16(clear, DPP_ATTR_BOOTSTRAP_KEY);
  6196. wpabuf_put_le16(clear, wpabuf_len(B_pub));
  6197. wpabuf_put_buf(clear, B_pub);
  6198. #ifdef CONFIG_TESTING_OPTIONS
  6199. skip_bootstrap_key:
  6200. if (dpp_test == DPP_TEST_NO_R_AUTH_TAG_PKEX_CR_RESP) {
  6201. wpa_printf(MSG_INFO, "DPP: TESTING - no R-Auth tag");
  6202. goto skip_r_auth_tag;
  6203. }
  6204. if (dpp_test == DPP_TEST_R_AUTH_TAG_MISMATCH_PKEX_CR_RESP) {
  6205. wpa_printf(MSG_INFO, "DPP: TESTING - R-Auth tag mismatch");
  6206. wpabuf_put_le16(clear, DPP_ATTR_R_AUTH_TAG);
  6207. wpabuf_put_le16(clear, curve->hash_len);
  6208. wpabuf_put_data(clear, v, curve->hash_len - 1);
  6209. wpabuf_put_u8(clear, v[curve->hash_len - 1] ^ 0x01);
  6210. goto skip_r_auth_tag;
  6211. }
  6212. #endif /* CONFIG_TESTING_OPTIONS */
  6213. /* v in R-Auth tag attribute */
  6214. wpabuf_put_le16(clear, DPP_ATTR_R_AUTH_TAG);
  6215. wpabuf_put_le16(clear, curve->hash_len);
  6216. wpabuf_put_data(clear, v, curve->hash_len);
  6217. #ifdef CONFIG_TESTING_OPTIONS
  6218. skip_r_auth_tag:
  6219. if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_PKEX_CR_RESP) {
  6220. wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data");
  6221. goto skip_wrapped_data;
  6222. }
  6223. #endif /* CONFIG_TESTING_OPTIONS */
  6224. addr[0] = wpabuf_head_u8(msg) + 2;
  6225. len[0] = DPP_HDR_LEN;
  6226. octet = 1;
  6227. addr[1] = &octet;
  6228. len[1] = sizeof(octet);
  6229. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  6230. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  6231. wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
  6232. wpabuf_put_le16(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
  6233. wrapped = wpabuf_put(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
  6234. wpa_hexdump_buf(MSG_DEBUG, "DPP: AES-SIV cleartext", clear);
  6235. if (aes_siv_encrypt(pkex->z, curve->hash_len,
  6236. wpabuf_head(clear), wpabuf_len(clear),
  6237. 2, addr, len, wrapped) < 0)
  6238. goto fail;
  6239. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  6240. wrapped, wpabuf_len(clear) + AES_BLOCK_SIZE);
  6241. #ifdef CONFIG_TESTING_OPTIONS
  6242. if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_RESP) {
  6243. wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
  6244. dpp_build_attr_status(msg, DPP_STATUS_OK);
  6245. }
  6246. skip_wrapped_data:
  6247. #endif /* CONFIG_TESTING_OPTIONS */
  6248. out:
  6249. wpabuf_free(clear);
  6250. return msg;
  6251. fail:
  6252. wpabuf_free(msg);
  6253. msg = NULL;
  6254. goto out;
  6255. }
  6256. struct wpabuf * dpp_pkex_rx_commit_reveal_req(struct dpp_pkex *pkex,
  6257. const u8 *hdr,
  6258. const u8 *buf, size_t buflen)
  6259. {
  6260. const struct dpp_curve_params *curve = pkex->own_bi->curve;
  6261. EVP_PKEY_CTX *ctx = NULL;
  6262. size_t Jx_len, Lx_len;
  6263. u8 Jx[DPP_MAX_SHARED_SECRET_LEN];
  6264. u8 Lx[DPP_MAX_SHARED_SECRET_LEN];
  6265. const u8 *wrapped_data, *b_key, *peer_u;
  6266. u16 wrapped_data_len, b_key_len, peer_u_len = 0;
  6267. const u8 *addr[4];
  6268. size_t len[4];
  6269. u8 octet;
  6270. u8 *unwrapped = NULL;
  6271. size_t unwrapped_len = 0;
  6272. struct wpabuf *msg = NULL, *A_pub = NULL, *X_pub = NULL, *Y_pub = NULL;
  6273. struct wpabuf *B_pub = NULL;
  6274. u8 u[DPP_MAX_HASH_LEN], v[DPP_MAX_HASH_LEN];
  6275. if (!pkex->exchange_done || pkex->failed ||
  6276. pkex->t >= PKEX_COUNTER_T_LIMIT || pkex->initiator)
  6277. goto fail;
  6278. wrapped_data = dpp_get_attr(buf, buflen, DPP_ATTR_WRAPPED_DATA,
  6279. &wrapped_data_len);
  6280. if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
  6281. dpp_pkex_fail(pkex,
  6282. "Missing or invalid required Wrapped Data attribute");
  6283. goto fail;
  6284. }
  6285. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  6286. wrapped_data, wrapped_data_len);
  6287. unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
  6288. unwrapped = os_malloc(unwrapped_len);
  6289. if (!unwrapped)
  6290. goto fail;
  6291. addr[0] = hdr;
  6292. len[0] = DPP_HDR_LEN;
  6293. octet = 0;
  6294. addr[1] = &octet;
  6295. len[1] = sizeof(octet);
  6296. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  6297. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  6298. if (aes_siv_decrypt(pkex->z, curve->hash_len,
  6299. wrapped_data, wrapped_data_len,
  6300. 2, addr, len, unwrapped) < 0) {
  6301. dpp_pkex_fail(pkex,
  6302. "AES-SIV decryption failed - possible PKEX code mismatch");
  6303. pkex->failed = 1;
  6304. pkex->t++;
  6305. goto fail;
  6306. }
  6307. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
  6308. unwrapped, unwrapped_len);
  6309. if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
  6310. dpp_pkex_fail(pkex, "Invalid attribute in unwrapped data");
  6311. goto fail;
  6312. }
  6313. b_key = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_BOOTSTRAP_KEY,
  6314. &b_key_len);
  6315. if (!b_key || b_key_len != 2 * curve->prime_len) {
  6316. dpp_pkex_fail(pkex, "No valid peer bootstrapping key found");
  6317. goto fail;
  6318. }
  6319. pkex->peer_bootstrap_key = dpp_set_pubkey_point(pkex->x, b_key,
  6320. b_key_len);
  6321. if (!pkex->peer_bootstrap_key) {
  6322. dpp_pkex_fail(pkex, "Peer bootstrapping key is invalid");
  6323. goto fail;
  6324. }
  6325. dpp_debug_print_key("DPP: Peer bootstrap public key",
  6326. pkex->peer_bootstrap_key);
  6327. /* ECDH: J' = y * A' */
  6328. ctx = EVP_PKEY_CTX_new(pkex->y, NULL);
  6329. if (!ctx ||
  6330. EVP_PKEY_derive_init(ctx) != 1 ||
  6331. EVP_PKEY_derive_set_peer(ctx, pkex->peer_bootstrap_key) != 1 ||
  6332. EVP_PKEY_derive(ctx, NULL, &Jx_len) != 1 ||
  6333. Jx_len > DPP_MAX_SHARED_SECRET_LEN ||
  6334. EVP_PKEY_derive(ctx, Jx, &Jx_len) != 1) {
  6335. wpa_printf(MSG_ERROR,
  6336. "DPP: Failed to derive ECDH shared secret: %s",
  6337. ERR_error_string(ERR_get_error(), NULL));
  6338. goto fail;
  6339. }
  6340. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (J.x)",
  6341. Jx, Jx_len);
  6342. /* u' = HMAC(J'.x, MAC-Initiator | A'.x | Y.x | X'.x) */
  6343. A_pub = dpp_get_pubkey_point(pkex->peer_bootstrap_key, 0);
  6344. Y_pub = dpp_get_pubkey_point(pkex->y, 0);
  6345. X_pub = dpp_get_pubkey_point(pkex->x, 0);
  6346. if (!A_pub || !Y_pub || !X_pub)
  6347. goto fail;
  6348. addr[0] = pkex->peer_mac;
  6349. len[0] = ETH_ALEN;
  6350. addr[1] = wpabuf_head(A_pub);
  6351. len[1] = wpabuf_len(A_pub) / 2;
  6352. addr[2] = wpabuf_head(Y_pub);
  6353. len[2] = wpabuf_len(Y_pub) / 2;
  6354. addr[3] = wpabuf_head(X_pub);
  6355. len[3] = wpabuf_len(X_pub) / 2;
  6356. if (dpp_hmac_vector(curve->hash_len, Jx, Jx_len, 4, addr, len, u) < 0)
  6357. goto fail;
  6358. peer_u = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_AUTH_TAG,
  6359. &peer_u_len);
  6360. if (!peer_u || peer_u_len != curve->hash_len ||
  6361. os_memcmp(peer_u, u, curve->hash_len) != 0) {
  6362. dpp_pkex_fail(pkex, "No valid u (I-Auth tag) found");
  6363. wpa_hexdump(MSG_DEBUG, "DPP: Calculated u'",
  6364. u, curve->hash_len);
  6365. wpa_hexdump(MSG_DEBUG, "DPP: Received u", peer_u, peer_u_len);
  6366. pkex->t++;
  6367. goto fail;
  6368. }
  6369. wpa_printf(MSG_DEBUG, "DPP: Valid u (I-Auth tag) received");
  6370. /* ECDH: L = b * X' */
  6371. EVP_PKEY_CTX_free(ctx);
  6372. ctx = EVP_PKEY_CTX_new(pkex->own_bi->pubkey, NULL);
  6373. if (!ctx ||
  6374. EVP_PKEY_derive_init(ctx) != 1 ||
  6375. EVP_PKEY_derive_set_peer(ctx, pkex->x) != 1 ||
  6376. EVP_PKEY_derive(ctx, NULL, &Lx_len) != 1 ||
  6377. Lx_len > DPP_MAX_SHARED_SECRET_LEN ||
  6378. EVP_PKEY_derive(ctx, Lx, &Lx_len) != 1) {
  6379. wpa_printf(MSG_ERROR,
  6380. "DPP: Failed to derive ECDH shared secret: %s",
  6381. ERR_error_string(ERR_get_error(), NULL));
  6382. goto fail;
  6383. }
  6384. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (L.x)",
  6385. Lx, Lx_len);
  6386. /* v = HMAC(L.x, MAC-Responder | B.x | X'.x | Y.x) */
  6387. B_pub = dpp_get_pubkey_point(pkex->own_bi->pubkey, 0);
  6388. if (!B_pub)
  6389. goto fail;
  6390. addr[0] = pkex->own_mac;
  6391. len[0] = ETH_ALEN;
  6392. addr[1] = wpabuf_head(B_pub);
  6393. len[1] = wpabuf_len(B_pub) / 2;
  6394. addr[2] = wpabuf_head(X_pub);
  6395. len[2] = wpabuf_len(X_pub) / 2;
  6396. addr[3] = wpabuf_head(Y_pub);
  6397. len[3] = wpabuf_len(Y_pub) / 2;
  6398. if (dpp_hmac_vector(curve->hash_len, Lx, Lx_len, 4, addr, len, v) < 0)
  6399. goto fail;
  6400. wpa_hexdump(MSG_DEBUG, "DPP: v", v, curve->hash_len);
  6401. msg = dpp_pkex_build_commit_reveal_resp(pkex, B_pub, v);
  6402. if (!msg)
  6403. goto fail;
  6404. out:
  6405. EVP_PKEY_CTX_free(ctx);
  6406. os_free(unwrapped);
  6407. wpabuf_free(A_pub);
  6408. wpabuf_free(B_pub);
  6409. wpabuf_free(X_pub);
  6410. wpabuf_free(Y_pub);
  6411. return msg;
  6412. fail:
  6413. wpa_printf(MSG_DEBUG,
  6414. "DPP: PKEX Commit-Reveal Request processing failed");
  6415. goto out;
  6416. }
  6417. int dpp_pkex_rx_commit_reveal_resp(struct dpp_pkex *pkex, const u8 *hdr,
  6418. const u8 *buf, size_t buflen)
  6419. {
  6420. const struct dpp_curve_params *curve = pkex->own_bi->curve;
  6421. const u8 *wrapped_data, *b_key, *peer_v;
  6422. u16 wrapped_data_len, b_key_len, peer_v_len = 0;
  6423. const u8 *addr[4];
  6424. size_t len[4];
  6425. u8 octet;
  6426. u8 *unwrapped = NULL;
  6427. size_t unwrapped_len = 0;
  6428. int ret = -1;
  6429. u8 v[DPP_MAX_HASH_LEN];
  6430. size_t Lx_len;
  6431. u8 Lx[DPP_MAX_SHARED_SECRET_LEN];
  6432. EVP_PKEY_CTX *ctx = NULL;
  6433. struct wpabuf *B_pub = NULL, *X_pub = NULL, *Y_pub = NULL;
  6434. if (!pkex->exchange_done || pkex->failed ||
  6435. pkex->t >= PKEX_COUNTER_T_LIMIT || !pkex->initiator)
  6436. goto fail;
  6437. wrapped_data = dpp_get_attr(buf, buflen, DPP_ATTR_WRAPPED_DATA,
  6438. &wrapped_data_len);
  6439. if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
  6440. dpp_pkex_fail(pkex,
  6441. "Missing or invalid required Wrapped Data attribute");
  6442. goto fail;
  6443. }
  6444. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
  6445. wrapped_data, wrapped_data_len);
  6446. unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
  6447. unwrapped = os_malloc(unwrapped_len);
  6448. if (!unwrapped)
  6449. goto fail;
  6450. addr[0] = hdr;
  6451. len[0] = DPP_HDR_LEN;
  6452. octet = 1;
  6453. addr[1] = &octet;
  6454. len[1] = sizeof(octet);
  6455. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
  6456. wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
  6457. if (aes_siv_decrypt(pkex->z, curve->hash_len,
  6458. wrapped_data, wrapped_data_len,
  6459. 2, addr, len, unwrapped) < 0) {
  6460. dpp_pkex_fail(pkex,
  6461. "AES-SIV decryption failed - possible PKEX code mismatch");
  6462. pkex->t++;
  6463. goto fail;
  6464. }
  6465. wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
  6466. unwrapped, unwrapped_len);
  6467. if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
  6468. dpp_pkex_fail(pkex, "Invalid attribute in unwrapped data");
  6469. goto fail;
  6470. }
  6471. b_key = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_BOOTSTRAP_KEY,
  6472. &b_key_len);
  6473. if (!b_key || b_key_len != 2 * curve->prime_len) {
  6474. dpp_pkex_fail(pkex, "No valid peer bootstrapping key found");
  6475. goto fail;
  6476. }
  6477. pkex->peer_bootstrap_key = dpp_set_pubkey_point(pkex->x, b_key,
  6478. b_key_len);
  6479. if (!pkex->peer_bootstrap_key) {
  6480. dpp_pkex_fail(pkex, "Peer bootstrapping key is invalid");
  6481. goto fail;
  6482. }
  6483. dpp_debug_print_key("DPP: Peer bootstrap public key",
  6484. pkex->peer_bootstrap_key);
  6485. /* ECDH: L' = x * B' */
  6486. ctx = EVP_PKEY_CTX_new(pkex->x, NULL);
  6487. if (!ctx ||
  6488. EVP_PKEY_derive_init(ctx) != 1 ||
  6489. EVP_PKEY_derive_set_peer(ctx, pkex->peer_bootstrap_key) != 1 ||
  6490. EVP_PKEY_derive(ctx, NULL, &Lx_len) != 1 ||
  6491. Lx_len > DPP_MAX_SHARED_SECRET_LEN ||
  6492. EVP_PKEY_derive(ctx, Lx, &Lx_len) != 1) {
  6493. wpa_printf(MSG_ERROR,
  6494. "DPP: Failed to derive ECDH shared secret: %s",
  6495. ERR_error_string(ERR_get_error(), NULL));
  6496. goto fail;
  6497. }
  6498. wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (L.x)",
  6499. Lx, Lx_len);
  6500. /* v' = HMAC(L.x, MAC-Responder | B'.x | X.x | Y'.x) */
  6501. B_pub = dpp_get_pubkey_point(pkex->peer_bootstrap_key, 0);
  6502. X_pub = dpp_get_pubkey_point(pkex->x, 0);
  6503. Y_pub = dpp_get_pubkey_point(pkex->y, 0);
  6504. if (!B_pub || !X_pub || !Y_pub)
  6505. goto fail;
  6506. addr[0] = pkex->peer_mac;
  6507. len[0] = ETH_ALEN;
  6508. addr[1] = wpabuf_head(B_pub);
  6509. len[1] = wpabuf_len(B_pub) / 2;
  6510. addr[2] = wpabuf_head(X_pub);
  6511. len[2] = wpabuf_len(X_pub) / 2;
  6512. addr[3] = wpabuf_head(Y_pub);
  6513. len[3] = wpabuf_len(Y_pub) / 2;
  6514. if (dpp_hmac_vector(curve->hash_len, Lx, Lx_len, 4, addr, len, v) < 0)
  6515. goto fail;
  6516. peer_v = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_AUTH_TAG,
  6517. &peer_v_len);
  6518. if (!peer_v || peer_v_len != curve->hash_len ||
  6519. os_memcmp(peer_v, v, curve->hash_len) != 0) {
  6520. dpp_pkex_fail(pkex, "No valid v (R-Auth tag) found");
  6521. wpa_hexdump(MSG_DEBUG, "DPP: Calculated v'",
  6522. v, curve->hash_len);
  6523. wpa_hexdump(MSG_DEBUG, "DPP: Received v", peer_v, peer_v_len);
  6524. pkex->t++;
  6525. goto fail;
  6526. }
  6527. wpa_printf(MSG_DEBUG, "DPP: Valid v (R-Auth tag) received");
  6528. ret = 0;
  6529. out:
  6530. wpabuf_free(B_pub);
  6531. wpabuf_free(X_pub);
  6532. wpabuf_free(Y_pub);
  6533. EVP_PKEY_CTX_free(ctx);
  6534. os_free(unwrapped);
  6535. return ret;
  6536. fail:
  6537. goto out;
  6538. }
  6539. void dpp_pkex_free(struct dpp_pkex *pkex)
  6540. {
  6541. if (!pkex)
  6542. return;
  6543. os_free(pkex->identifier);
  6544. os_free(pkex->code);
  6545. EVP_PKEY_free(pkex->x);
  6546. EVP_PKEY_free(pkex->y);
  6547. EVP_PKEY_free(pkex->peer_bootstrap_key);
  6548. wpabuf_free(pkex->exchange_req);
  6549. wpabuf_free(pkex->exchange_resp);
  6550. os_free(pkex);
  6551. }
  6552. #ifdef CONFIG_TESTING_OPTIONS
  6553. char * dpp_corrupt_connector_signature(const char *connector)
  6554. {
  6555. char *tmp, *pos, *signed3 = NULL;
  6556. unsigned char *signature = NULL;
  6557. size_t signature_len = 0, signed3_len;
  6558. tmp = os_zalloc(os_strlen(connector) + 5);
  6559. if (!tmp)
  6560. goto fail;
  6561. os_memcpy(tmp, connector, os_strlen(connector));
  6562. pos = os_strchr(tmp, '.');
  6563. if (!pos)
  6564. goto fail;
  6565. pos = os_strchr(pos + 1, '.');
  6566. if (!pos)
  6567. goto fail;
  6568. pos++;
  6569. wpa_printf(MSG_DEBUG, "DPP: Original base64url encoded signature: %s",
  6570. pos);
  6571. signature = base64_url_decode((const unsigned char *) pos,
  6572. os_strlen(pos), &signature_len);
  6573. if (!signature || signature_len == 0)
  6574. goto fail;
  6575. wpa_hexdump(MSG_DEBUG, "DPP: Original Connector signature",
  6576. signature, signature_len);
  6577. signature[signature_len - 1] ^= 0x01;
  6578. wpa_hexdump(MSG_DEBUG, "DPP: Corrupted Connector signature",
  6579. signature, signature_len);
  6580. signed3 = (char *) base64_url_encode(signature, signature_len,
  6581. &signed3_len, 0);
  6582. if (!signed3)
  6583. goto fail;
  6584. os_memcpy(pos, signed3, signed3_len);
  6585. pos[signed3_len] = '\0';
  6586. wpa_printf(MSG_DEBUG, "DPP: Corrupted base64url encoded signature: %s",
  6587. pos);
  6588. out:
  6589. os_free(signature);
  6590. os_free(signed3);
  6591. return tmp;
  6592. fail:
  6593. os_free(tmp);
  6594. tmp = NULL;
  6595. goto out;
  6596. }
  6597. #endif /* CONFIG_TESTING_OPTIONS */