dpp.c 167 KB

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