ieee802_1x_kay.c 88 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566
  1. /*
  2. * IEEE 802.1X-2010 Key Agree Protocol of PAE state machine
  3. * Copyright (c) 2013, 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 <time.h>
  9. #include "includes.h"
  10. #include "common.h"
  11. #include "list.h"
  12. #include "eloop.h"
  13. #include "wpabuf.h"
  14. #include "state_machine.h"
  15. #include "l2_packet/l2_packet.h"
  16. #include "common/eapol_common.h"
  17. #include "crypto/aes_wrap.h"
  18. #include "ieee802_1x_cp.h"
  19. #include "ieee802_1x_key.h"
  20. #include "ieee802_1x_kay.h"
  21. #include "ieee802_1x_kay_i.h"
  22. #include "ieee802_1x_secy_ops.h"
  23. #define DEFAULT_SA_KEY_LEN 16
  24. #define DEFAULT_ICV_LEN 16
  25. #define MAX_ICV_LEN 32 /* 32 bytes, 256 bits */
  26. #define PENDING_PN_EXHAUSTION 0xC0000000
  27. /* IEEE Std 802.1X-2010, Table 9-1 - MKA Algorithm Agility */
  28. #define MKA_ALGO_AGILITY_2009 { 0x00, 0x80, 0xC2, 0x01 }
  29. static u8 mka_algo_agility[4] = MKA_ALGO_AGILITY_2009;
  30. /* IEEE802.1AE-2006 Table 14-1 MACsec Cipher Suites */
  31. static struct macsec_ciphersuite cipher_suite_tbl[] = {
  32. /* GCM-AES-128 */
  33. {
  34. CS_ID_GCM_AES_128,
  35. CS_NAME_GCM_AES_128,
  36. MACSEC_CAP_INTEG_AND_CONF_0_30_50,
  37. 16,
  38. 0 /* index */
  39. },
  40. };
  41. #define CS_TABLE_SIZE (ARRAY_SIZE(cipher_suite_tbl))
  42. #define DEFAULT_CS_INDEX 0
  43. static struct mka_alg mka_alg_tbl[] = {
  44. {
  45. MKA_ALGO_AGILITY_2009,
  46. /* 128-bit CAK, KEK, ICK, ICV */
  47. 16, 16, 16, 16,
  48. ieee802_1x_cak_128bits_aes_cmac,
  49. ieee802_1x_ckn_128bits_aes_cmac,
  50. ieee802_1x_kek_128bits_aes_cmac,
  51. ieee802_1x_ick_128bits_aes_cmac,
  52. ieee802_1x_icv_128bits_aes_cmac,
  53. 1, /* index */
  54. },
  55. };
  56. #define MKA_ALG_TABLE_SIZE (ARRAY_SIZE(mka_alg_tbl))
  57. static int is_ki_equal(struct ieee802_1x_mka_ki *ki1,
  58. struct ieee802_1x_mka_ki *ki2)
  59. {
  60. return os_memcmp(ki1->mi, ki2->mi, MI_LEN) == 0 &&
  61. ki1->kn == ki2->kn;
  62. }
  63. struct mka_param_body_handler {
  64. int (*body_tx)(struct ieee802_1x_mka_participant *participant,
  65. struct wpabuf *buf);
  66. int (*body_rx)(struct ieee802_1x_mka_participant *participant,
  67. const u8 *mka_msg, size_t msg_len);
  68. int (*body_length)(struct ieee802_1x_mka_participant *participant);
  69. Boolean (*body_present)(struct ieee802_1x_mka_participant *participant);
  70. };
  71. static void set_mka_param_body_len(void *body, unsigned int len)
  72. {
  73. struct ieee802_1x_mka_hdr *hdr = body;
  74. hdr->length = (len >> 8) & 0x0f;
  75. hdr->length1 = len & 0xff;
  76. }
  77. static unsigned int get_mka_param_body_len(const void *body)
  78. {
  79. const struct ieee802_1x_mka_hdr *hdr = body;
  80. return (hdr->length << 8) | hdr->length1;
  81. }
  82. static u8 get_mka_param_body_type(const void *body)
  83. {
  84. const struct ieee802_1x_mka_hdr *hdr = body;
  85. return hdr->type;
  86. }
  87. /**
  88. * ieee802_1x_mka_dump_basic_body -
  89. */
  90. static void
  91. ieee802_1x_mka_dump_basic_body(struct ieee802_1x_mka_basic_body *body)
  92. {
  93. size_t body_len;
  94. if (!body)
  95. return;
  96. body_len = get_mka_param_body_len(body);
  97. wpa_printf(MSG_DEBUG, "*** MKA Basic Parameter set ***");
  98. wpa_printf(MSG_DEBUG, "\tVersion.......: %d", body->version);
  99. wpa_printf(MSG_DEBUG, "\tPriority......: %d", body->priority);
  100. wpa_printf(MSG_DEBUG, "\tKeySvr........: %d", body->key_server);
  101. wpa_printf(MSG_DEBUG, "\tMACSecDesired.: %d", body->macsec_desired);
  102. wpa_printf(MSG_DEBUG, "\tMACSecCapable.: %d", body->macsec_capability);
  103. wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len);
  104. wpa_printf(MSG_DEBUG, "\tSCI MAC.......: " MACSTR,
  105. MAC2STR(body->actor_sci.addr));
  106. wpa_printf(MSG_DEBUG, "\tSCI Port .....: %d",
  107. be_to_host16(body->actor_sci.port));
  108. wpa_hexdump(MSG_DEBUG, "\tMember Id.....:",
  109. body->actor_mi, sizeof(body->actor_mi));
  110. wpa_printf(MSG_DEBUG, "\tMessage Number: %d",
  111. be_to_host32(body->actor_mn));
  112. wpa_hexdump(MSG_DEBUG, "\tAlgo Agility..:",
  113. body->algo_agility, sizeof(body->algo_agility));
  114. wpa_hexdump_ascii(MSG_DEBUG, "\tCAK Name......:", body->ckn,
  115. body_len + MKA_HDR_LEN - sizeof(*body));
  116. }
  117. /**
  118. * ieee802_1x_mka_dump_peer_body -
  119. */
  120. static void
  121. ieee802_1x_mka_dump_peer_body(struct ieee802_1x_mka_peer_body *body)
  122. {
  123. size_t body_len;
  124. size_t i;
  125. u8 *mi;
  126. be32 mn;
  127. if (body == NULL)
  128. return;
  129. body_len = get_mka_param_body_len(body);
  130. if (body->type == MKA_LIVE_PEER_LIST) {
  131. wpa_printf(MSG_DEBUG, "*** Live Peer List ***");
  132. wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len);
  133. } else if (body->type == MKA_POTENTIAL_PEER_LIST) {
  134. wpa_printf(MSG_DEBUG, "*** Potential Live Peer List ***");
  135. wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len);
  136. }
  137. for (i = 0; i < body_len; i += MI_LEN + sizeof(mn)) {
  138. mi = body->peer + i;
  139. os_memcpy(&mn, mi + MI_LEN, sizeof(mn));
  140. wpa_hexdump_ascii(MSG_DEBUG, "\tMember Id.....:", mi, MI_LEN);
  141. wpa_printf(MSG_DEBUG, "\tMessage Number: %d", be_to_host32(mn));
  142. }
  143. }
  144. /**
  145. * ieee802_1x_mka_dump_dist_sak_body -
  146. */
  147. static void
  148. ieee802_1x_mka_dump_dist_sak_body(struct ieee802_1x_mka_dist_sak_body *body)
  149. {
  150. size_t body_len;
  151. if (body == NULL)
  152. return;
  153. body_len = get_mka_param_body_len(body);
  154. wpa_printf(MSG_INFO, "*** Distributed SAK ***");
  155. wpa_printf(MSG_INFO, "\tDistributed AN........: %d", body->dan);
  156. wpa_printf(MSG_INFO, "\tConfidentiality Offset: %d",
  157. body->confid_offset);
  158. wpa_printf(MSG_INFO, "\tBody Length...........: %d", (int) body_len);
  159. if (!body_len)
  160. return;
  161. wpa_printf(MSG_INFO, "\tKey Number............: %d",
  162. be_to_host32(body->kn));
  163. wpa_hexdump(MSG_INFO, "\tAES Key Wrap of SAK...:", body->sak, 24);
  164. }
  165. static const char * yes_no(int val)
  166. {
  167. return val ? "Yes" : "No";
  168. }
  169. /**
  170. * ieee802_1x_mka_dump_sak_use_body -
  171. */
  172. static void
  173. ieee802_1x_mka_dump_sak_use_body(struct ieee802_1x_mka_sak_use_body *body)
  174. {
  175. int body_len;
  176. if (body == NULL)
  177. return;
  178. body_len = get_mka_param_body_len(body);
  179. wpa_printf(MSG_DEBUG, "*** MACsec SAK Use ***");
  180. wpa_printf(MSG_DEBUG, "\tLatest Key AN....: %d", body->lan);
  181. wpa_printf(MSG_DEBUG, "\tLatest Key Tx....: %s", yes_no(body->ltx));
  182. wpa_printf(MSG_DEBUG, "\tLatest Key Rx....: %s", yes_no(body->lrx));
  183. wpa_printf(MSG_DEBUG, "\tOld Key AN....: %d", body->oan);
  184. wpa_printf(MSG_DEBUG, "\tOld Key Tx....: %s", yes_no(body->otx));
  185. wpa_printf(MSG_DEBUG, "\tOld Key Rx....: %s", yes_no(body->orx));
  186. wpa_printf(MSG_DEBUG, "\tPlain Key Tx....: %s", yes_no(body->ptx));
  187. wpa_printf(MSG_DEBUG, "\tPlain Key Rx....: %s", yes_no(body->prx));
  188. wpa_printf(MSG_DEBUG, "\tDelay Protect....: %s",
  189. yes_no(body->delay_protect));
  190. wpa_printf(MSG_DEBUG, "\tBody Length......: %d", body_len);
  191. if (!body_len)
  192. return;
  193. wpa_hexdump(MSG_DEBUG, "\tKey Server MI....:",
  194. body->lsrv_mi, sizeof(body->lsrv_mi));
  195. wpa_printf(MSG_DEBUG, "\tKey Number.......: %u",
  196. be_to_host32(body->lkn));
  197. wpa_printf(MSG_DEBUG, "\tLowest PN........: %u",
  198. be_to_host32(body->llpn));
  199. wpa_hexdump_ascii(MSG_DEBUG, "\tOld Key Server MI....:",
  200. body->osrv_mi, sizeof(body->osrv_mi));
  201. wpa_printf(MSG_DEBUG, "\tOld Key Number.......: %u",
  202. be_to_host32(body->okn));
  203. wpa_printf(MSG_DEBUG, "\tOld Lowest PN........: %u",
  204. be_to_host32(body->olpn));
  205. }
  206. /**
  207. * ieee802_1x_kay_get_participant -
  208. */
  209. static struct ieee802_1x_mka_participant *
  210. ieee802_1x_kay_get_participant(struct ieee802_1x_kay *kay, const u8 *ckn)
  211. {
  212. struct ieee802_1x_mka_participant *participant;
  213. dl_list_for_each(participant, &kay->participant_list,
  214. struct ieee802_1x_mka_participant, list) {
  215. if (os_memcmp(participant->ckn.name, ckn,
  216. participant->ckn.len) == 0)
  217. return participant;
  218. }
  219. wpa_printf(MSG_DEBUG, "KaY: participant is not found");
  220. return NULL;
  221. }
  222. /**
  223. * ieee802_1x_kay_get_principal_participant -
  224. */
  225. static struct ieee802_1x_mka_participant *
  226. ieee802_1x_kay_get_principal_participant(struct ieee802_1x_kay *kay)
  227. {
  228. struct ieee802_1x_mka_participant *participant;
  229. dl_list_for_each(participant, &kay->participant_list,
  230. struct ieee802_1x_mka_participant, list) {
  231. if (participant->principal)
  232. return participant;
  233. }
  234. wpa_printf(MSG_DEBUG, "KaY: principal participant is not founded");
  235. return NULL;
  236. }
  237. static struct ieee802_1x_kay_peer * get_peer_mi(struct dl_list *peers,
  238. const u8 *mi)
  239. {
  240. struct ieee802_1x_kay_peer *peer;
  241. dl_list_for_each(peer, peers, struct ieee802_1x_kay_peer, list) {
  242. if (os_memcmp(peer->mi, mi, MI_LEN) == 0)
  243. return peer;
  244. }
  245. return NULL;
  246. }
  247. /**
  248. * ieee802_1x_kay_get_potential_peer
  249. */
  250. static struct ieee802_1x_kay_peer *
  251. ieee802_1x_kay_get_potential_peer(
  252. struct ieee802_1x_mka_participant *participant, const u8 *mi)
  253. {
  254. return get_peer_mi(&participant->potential_peers, mi);
  255. }
  256. /**
  257. * ieee802_1x_kay_get_live_peer
  258. */
  259. static struct ieee802_1x_kay_peer *
  260. ieee802_1x_kay_get_live_peer(struct ieee802_1x_mka_participant *participant,
  261. const u8 *mi)
  262. {
  263. return get_peer_mi(&participant->live_peers, mi);
  264. }
  265. /**
  266. * ieee802_1x_kay_is_in_potential_peer
  267. */
  268. static Boolean
  269. ieee802_1x_kay_is_in_potential_peer(
  270. struct ieee802_1x_mka_participant *participant, const u8 *mi)
  271. {
  272. return ieee802_1x_kay_get_potential_peer(participant, mi) != NULL;
  273. }
  274. /**
  275. * ieee802_1x_kay_is_in_live_peer
  276. */
  277. static Boolean
  278. ieee802_1x_kay_is_in_live_peer(
  279. struct ieee802_1x_mka_participant *participant, const u8 *mi)
  280. {
  281. return ieee802_1x_kay_get_live_peer(participant, mi) != NULL;
  282. }
  283. /**
  284. * ieee802_1x_kay_is_in_peer
  285. */
  286. static Boolean
  287. ieee802_1x_kay_is_in_peer(struct ieee802_1x_mka_participant *participant,
  288. const u8 *mi)
  289. {
  290. return ieee802_1x_kay_is_in_live_peer(participant, mi) ||
  291. ieee802_1x_kay_is_in_potential_peer(participant, mi);
  292. }
  293. /**
  294. * ieee802_1x_kay_get_peer
  295. */
  296. static struct ieee802_1x_kay_peer *
  297. ieee802_1x_kay_get_peer(struct ieee802_1x_mka_participant *participant,
  298. const u8 *mi)
  299. {
  300. struct ieee802_1x_kay_peer *peer;
  301. peer = ieee802_1x_kay_get_live_peer(participant, mi);
  302. if (peer)
  303. return peer;
  304. return ieee802_1x_kay_get_potential_peer(participant, mi);
  305. }
  306. /**
  307. * ieee802_1x_kay_get_cipher_suite
  308. */
  309. static struct macsec_ciphersuite *
  310. ieee802_1x_kay_get_cipher_suite(struct ieee802_1x_mka_participant *participant,
  311. u8 *cs_id)
  312. {
  313. unsigned int i;
  314. for (i = 0; i < CS_TABLE_SIZE; i++) {
  315. if (os_memcmp(cipher_suite_tbl[i].id, cs_id, CS_ID_LEN) == 0)
  316. return &cipher_suite_tbl[i];
  317. }
  318. return NULL;
  319. }
  320. static Boolean sci_equal(const struct ieee802_1x_mka_sci *a,
  321. const struct ieee802_1x_mka_sci *b)
  322. {
  323. return os_memcmp(a, b, sizeof(struct ieee802_1x_mka_sci)) == 0;
  324. }
  325. /**
  326. * ieee802_1x_kay_get_peer_sci
  327. */
  328. static struct ieee802_1x_kay_peer *
  329. ieee802_1x_kay_get_peer_sci(struct ieee802_1x_mka_participant *participant,
  330. const struct ieee802_1x_mka_sci *sci)
  331. {
  332. struct ieee802_1x_kay_peer *peer;
  333. dl_list_for_each(peer, &participant->live_peers,
  334. struct ieee802_1x_kay_peer, list) {
  335. if (sci_equal(&peer->sci, sci))
  336. return peer;
  337. }
  338. dl_list_for_each(peer, &participant->potential_peers,
  339. struct ieee802_1x_kay_peer, list) {
  340. if (sci_equal(&peer->sci, sci))
  341. return peer;
  342. }
  343. return NULL;
  344. }
  345. /**
  346. * ieee802_1x_kay_init_receive_sa -
  347. */
  348. static struct receive_sa *
  349. ieee802_1x_kay_init_receive_sa(struct receive_sc *psc, u8 an, u32 lowest_pn,
  350. struct data_key *key)
  351. {
  352. struct receive_sa *psa;
  353. if (!psc || !key)
  354. return NULL;
  355. psa = os_zalloc(sizeof(*psa));
  356. if (!psa) {
  357. wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
  358. return NULL;
  359. }
  360. psa->pkey = key;
  361. psa->lowest_pn = lowest_pn;
  362. psa->next_pn = lowest_pn;
  363. psa->an = an;
  364. psa->sc = psc;
  365. os_get_time(&psa->created_time);
  366. psa->in_use = FALSE;
  367. dl_list_add(&psc->sa_list, &psa->list);
  368. wpa_printf(MSG_DEBUG,
  369. "KaY: Create receive SA(AN: %d lowest_pn: %u of SC(channel: %d)",
  370. (int) an, lowest_pn, psc->channel);
  371. return psa;
  372. }
  373. /**
  374. * ieee802_1x_kay_deinit_receive_sa -
  375. */
  376. static void ieee802_1x_kay_deinit_receive_sa(struct receive_sa *psa)
  377. {
  378. psa->pkey = NULL;
  379. wpa_printf(MSG_DEBUG,
  380. "KaY: Delete receive SA(an: %d) of SC(channel: %d)",
  381. psa->an, psa->sc->channel);
  382. dl_list_del(&psa->list);
  383. os_free(psa);
  384. }
  385. /**
  386. * ieee802_1x_kay_init_receive_sc -
  387. */
  388. static struct receive_sc *
  389. ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci,
  390. int channel)
  391. {
  392. struct receive_sc *psc;
  393. if (!psci)
  394. return NULL;
  395. psc = os_zalloc(sizeof(*psc));
  396. if (!psc) {
  397. wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
  398. return NULL;
  399. }
  400. os_memcpy(&psc->sci, psci, sizeof(psc->sci));
  401. psc->channel = channel;
  402. os_get_time(&psc->created_time);
  403. psc->receiving = FALSE;
  404. dl_list_init(&psc->sa_list);
  405. wpa_printf(MSG_DEBUG, "KaY: Create receive SC(channel: %d)", channel);
  406. wpa_hexdump(MSG_DEBUG, "SCI: ", (u8 *)psci, sizeof(*psci));
  407. return psc;
  408. }
  409. /**
  410. * ieee802_1x_kay_deinit_receive_sc -
  411. **/
  412. static void
  413. ieee802_1x_kay_deinit_receive_sc(
  414. struct ieee802_1x_mka_participant *participant, struct receive_sc *psc)
  415. {
  416. struct receive_sa *psa, *pre_sa;
  417. wpa_printf(MSG_DEBUG, "KaY: Delete receive SC(channel: %d)",
  418. psc->channel);
  419. dl_list_for_each_safe(psa, pre_sa, &psc->sa_list, struct receive_sa,
  420. list) {
  421. secy_disable_receive_sa(participant->kay, psa);
  422. ieee802_1x_kay_deinit_receive_sa(psa);
  423. }
  424. dl_list_del(&psc->list);
  425. os_free(psc);
  426. }
  427. /**
  428. * ieee802_1x_kay_create_live_peer
  429. */
  430. static struct ieee802_1x_kay_peer *
  431. ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant,
  432. u8 *mi, u32 mn)
  433. {
  434. struct ieee802_1x_kay_peer *peer;
  435. struct receive_sc *rxsc;
  436. u32 sc_ch = 0;
  437. peer = os_zalloc(sizeof(*peer));
  438. if (peer == NULL) {
  439. wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
  440. return NULL;
  441. }
  442. os_memcpy(peer->mi, mi, MI_LEN);
  443. peer->mn = mn;
  444. peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
  445. peer->sak_used = FALSE;
  446. os_memcpy(&peer->sci, &participant->current_peer_sci,
  447. sizeof(peer->sci));
  448. secy_get_available_receive_sc(participant->kay, &sc_ch);
  449. rxsc = ieee802_1x_kay_init_receive_sc(&peer->sci, sc_ch);
  450. if (!rxsc) {
  451. os_free(peer);
  452. return NULL;
  453. }
  454. dl_list_add(&participant->live_peers, &peer->list);
  455. dl_list_add(&participant->rxsc_list, &rxsc->list);
  456. secy_create_receive_sc(participant->kay, rxsc);
  457. wpa_printf(MSG_DEBUG, "KaY: Live peer created");
  458. wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
  459. wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
  460. wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
  461. wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
  462. return peer;
  463. }
  464. /**
  465. * ieee802_1x_kay_create_potential_peer
  466. */
  467. static struct ieee802_1x_kay_peer *
  468. ieee802_1x_kay_create_potential_peer(
  469. struct ieee802_1x_mka_participant *participant, const u8 *mi, u32 mn)
  470. {
  471. struct ieee802_1x_kay_peer *peer;
  472. peer = os_zalloc(sizeof(*peer));
  473. if (peer == NULL) {
  474. wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
  475. return NULL;
  476. }
  477. os_memcpy(peer->mi, mi, MI_LEN);
  478. peer->mn = mn;
  479. peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
  480. peer->sak_used = FALSE;
  481. dl_list_add(&participant->potential_peers, &peer->list);
  482. wpa_printf(MSG_DEBUG, "KaY: potential peer created");
  483. wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
  484. wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
  485. wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
  486. wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
  487. return peer;
  488. }
  489. /**
  490. * ieee802_1x_kay_move_live_peer
  491. */
  492. static struct ieee802_1x_kay_peer *
  493. ieee802_1x_kay_move_live_peer(struct ieee802_1x_mka_participant *participant,
  494. u8 *mi, u32 mn)
  495. {
  496. struct ieee802_1x_kay_peer *peer;
  497. struct receive_sc *rxsc;
  498. u32 sc_ch = 0;
  499. peer = ieee802_1x_kay_get_potential_peer(participant, mi);
  500. rxsc = ieee802_1x_kay_init_receive_sc(&participant->current_peer_sci,
  501. sc_ch);
  502. if (!rxsc)
  503. return NULL;
  504. os_memcpy(&peer->sci, &participant->current_peer_sci,
  505. sizeof(peer->sci));
  506. peer->mn = mn;
  507. peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
  508. wpa_printf(MSG_DEBUG, "KaY: move potential peer to live peer");
  509. wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
  510. wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
  511. wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
  512. wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
  513. dl_list_del(&peer->list);
  514. dl_list_add_tail(&participant->live_peers, &peer->list);
  515. secy_get_available_receive_sc(participant->kay, &sc_ch);
  516. dl_list_add(&participant->rxsc_list, &rxsc->list);
  517. secy_create_receive_sc(participant->kay, rxsc);
  518. return peer;
  519. }
  520. /**
  521. * ieee802_1x_mka_basic_body_present -
  522. */
  523. static Boolean
  524. ieee802_1x_mka_basic_body_present(
  525. struct ieee802_1x_mka_participant *participant)
  526. {
  527. return TRUE;
  528. }
  529. /**
  530. * ieee802_1x_mka_basic_body_length -
  531. */
  532. static int
  533. ieee802_1x_mka_basic_body_length(struct ieee802_1x_mka_participant *participant)
  534. {
  535. int length;
  536. length = sizeof(struct ieee802_1x_mka_basic_body);
  537. length += participant->ckn.len;
  538. return (length + 0x3) & ~0x3;
  539. }
  540. /**
  541. * ieee802_1x_mka_encode_basic_body
  542. */
  543. static int
  544. ieee802_1x_mka_encode_basic_body(
  545. struct ieee802_1x_mka_participant *participant,
  546. struct wpabuf *buf)
  547. {
  548. struct ieee802_1x_mka_basic_body *body;
  549. struct ieee802_1x_kay *kay = participant->kay;
  550. unsigned int length = ieee802_1x_mka_basic_body_length(participant);
  551. body = wpabuf_put(buf, length);
  552. body->version = kay->mka_version;
  553. body->priority = kay->actor_priority;
  554. if (participant->is_elected)
  555. body->key_server = participant->is_key_server;
  556. else
  557. body->key_server = participant->can_be_key_server;
  558. body->macsec_desired = kay->macsec_desired;
  559. body->macsec_capability = kay->macsec_capable;
  560. set_mka_param_body_len(body, length - MKA_HDR_LEN);
  561. os_memcpy(body->actor_sci.addr, kay->actor_sci.addr,
  562. sizeof(kay->actor_sci.addr));
  563. body->actor_sci.port = kay->actor_sci.port;
  564. os_memcpy(body->actor_mi, participant->mi, sizeof(body->actor_mi));
  565. participant->mn = participant->mn + 1;
  566. body->actor_mn = host_to_be32(participant->mn);
  567. os_memcpy(body->algo_agility, participant->kay->algo_agility,
  568. sizeof(body->algo_agility));
  569. os_memcpy(body->ckn, participant->ckn.name, participant->ckn.len);
  570. ieee802_1x_mka_dump_basic_body(body);
  571. return 0;
  572. }
  573. /**
  574. * ieee802_1x_mka_decode_basic_body -
  575. */
  576. static struct ieee802_1x_mka_participant *
  577. ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg,
  578. size_t msg_len)
  579. {
  580. struct ieee802_1x_mka_participant *participant;
  581. const struct ieee802_1x_mka_basic_body *body;
  582. struct ieee802_1x_kay_peer *peer;
  583. body = (const struct ieee802_1x_mka_basic_body *) mka_msg;
  584. if (body->version > MKA_VERSION_ID) {
  585. wpa_printf(MSG_DEBUG,
  586. "KaY: peer's version(%d) greater than mka current version(%d)",
  587. body->version, MKA_VERSION_ID);
  588. }
  589. if (kay->is_obliged_key_server && body->key_server) {
  590. wpa_printf(MSG_DEBUG, "I must be as key server");
  591. return NULL;
  592. }
  593. participant = ieee802_1x_kay_get_participant(kay, body->ckn);
  594. if (!participant) {
  595. wpa_printf(MSG_DEBUG, "Peer is not included in my CA");
  596. return NULL;
  597. }
  598. /* If the peer's MI is my MI, I will choose new MI */
  599. if (os_memcmp(body->actor_mi, participant->mi, MI_LEN) == 0) {
  600. if (os_get_random(participant->mi, sizeof(participant->mi)) < 0)
  601. return NULL;
  602. participant->mn = 0;
  603. }
  604. os_memcpy(participant->current_peer_id.mi, body->actor_mi, MI_LEN);
  605. participant->current_peer_id.mn = body->actor_mn;
  606. os_memcpy(participant->current_peer_sci.addr, body->actor_sci.addr,
  607. sizeof(participant->current_peer_sci.addr));
  608. participant->current_peer_sci.port = body->actor_sci.port;
  609. /* handler peer */
  610. peer = ieee802_1x_kay_get_peer(participant, body->actor_mi);
  611. if (!peer) {
  612. /* Check duplicated SCI */
  613. /* TODO: What policy should be applied to detect duplicated SCI
  614. * is active attacker or a valid peer whose MI is be changed?
  615. */
  616. peer = ieee802_1x_kay_get_peer_sci(participant,
  617. &body->actor_sci);
  618. if (peer) {
  619. wpa_printf(MSG_WARNING,
  620. "KaY: duplicated SCI detected, Maybe active attacker");
  621. dl_list_del(&peer->list);
  622. os_free(peer);
  623. }
  624. peer = ieee802_1x_kay_create_potential_peer(
  625. participant, body->actor_mi,
  626. be_to_host32(body->actor_mn));
  627. if (!peer)
  628. return NULL;
  629. peer->macsec_desired = body->macsec_desired;
  630. peer->macsec_capability = body->macsec_capability;
  631. peer->is_key_server = (Boolean) body->key_server;
  632. peer->key_server_priority = body->priority;
  633. } else if (peer->mn < be_to_host32(body->actor_mn)) {
  634. peer->mn = be_to_host32(body->actor_mn);
  635. peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
  636. peer->macsec_desired = body->macsec_desired;
  637. peer->macsec_capability = body->macsec_capability;
  638. peer->is_key_server = (Boolean) body->key_server;
  639. peer->key_server_priority = body->priority;
  640. } else {
  641. wpa_printf(MSG_WARNING, "KaY: The peer MN have received");
  642. return NULL;
  643. }
  644. return participant;
  645. }
  646. /**
  647. * ieee802_1x_mka_live_peer_body_present
  648. */
  649. static Boolean
  650. ieee802_1x_mka_live_peer_body_present(
  651. struct ieee802_1x_mka_participant *participant)
  652. {
  653. return !dl_list_empty(&participant->live_peers);
  654. }
  655. /**
  656. * ieee802_1x_kay_get_live_peer_length
  657. */
  658. static int
  659. ieee802_1x_mka_get_live_peer_length(
  660. struct ieee802_1x_mka_participant *participant)
  661. {
  662. int len = MKA_HDR_LEN;
  663. struct ieee802_1x_kay_peer *peer;
  664. dl_list_for_each(peer, &participant->live_peers,
  665. struct ieee802_1x_kay_peer, list)
  666. len += sizeof(struct ieee802_1x_mka_peer_id);
  667. return (len + 0x3) & ~0x3;
  668. }
  669. /**
  670. * ieee802_1x_mka_encode_live_peer_body -
  671. */
  672. static int
  673. ieee802_1x_mka_encode_live_peer_body(
  674. struct ieee802_1x_mka_participant *participant,
  675. struct wpabuf *buf)
  676. {
  677. struct ieee802_1x_mka_peer_body *body;
  678. struct ieee802_1x_kay_peer *peer;
  679. unsigned int length;
  680. struct ieee802_1x_mka_peer_id *body_peer;
  681. length = ieee802_1x_mka_get_live_peer_length(participant);
  682. body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_peer_body));
  683. body->type = MKA_LIVE_PEER_LIST;
  684. set_mka_param_body_len(body, length - MKA_HDR_LEN);
  685. dl_list_for_each(peer, &participant->live_peers,
  686. struct ieee802_1x_kay_peer, list) {
  687. body_peer = wpabuf_put(buf,
  688. sizeof(struct ieee802_1x_mka_peer_id));
  689. os_memcpy(body_peer->mi, peer->mi, MI_LEN);
  690. body_peer->mn = host_to_be32(peer->mn);
  691. body_peer++;
  692. }
  693. ieee802_1x_mka_dump_peer_body(body);
  694. return 0;
  695. }
  696. /**
  697. * ieee802_1x_mka_potential_peer_body_present
  698. */
  699. static Boolean
  700. ieee802_1x_mka_potential_peer_body_present(
  701. struct ieee802_1x_mka_participant *participant)
  702. {
  703. return !dl_list_empty(&participant->potential_peers);
  704. }
  705. /**
  706. * ieee802_1x_kay_get_potential_peer_length
  707. */
  708. static int
  709. ieee802_1x_mka_get_potential_peer_length(
  710. struct ieee802_1x_mka_participant *participant)
  711. {
  712. int len = MKA_HDR_LEN;
  713. struct ieee802_1x_kay_peer *peer;
  714. dl_list_for_each(peer, &participant->potential_peers,
  715. struct ieee802_1x_kay_peer, list)
  716. len += sizeof(struct ieee802_1x_mka_peer_id);
  717. return (len + 0x3) & ~0x3;
  718. }
  719. /**
  720. * ieee802_1x_mka_encode_potential_peer_body -
  721. */
  722. static int
  723. ieee802_1x_mka_encode_potential_peer_body(
  724. struct ieee802_1x_mka_participant *participant,
  725. struct wpabuf *buf)
  726. {
  727. struct ieee802_1x_mka_peer_body *body;
  728. struct ieee802_1x_kay_peer *peer;
  729. unsigned int length;
  730. struct ieee802_1x_mka_peer_id *body_peer;
  731. length = ieee802_1x_mka_get_potential_peer_length(participant);
  732. body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_peer_body));
  733. body->type = MKA_POTENTIAL_PEER_LIST;
  734. set_mka_param_body_len(body, length - MKA_HDR_LEN);
  735. dl_list_for_each(peer, &participant->potential_peers,
  736. struct ieee802_1x_kay_peer, list) {
  737. body_peer = wpabuf_put(buf,
  738. sizeof(struct ieee802_1x_mka_peer_id));
  739. os_memcpy(body_peer->mi, peer->mi, MI_LEN);
  740. body_peer->mn = host_to_be32(peer->mn);
  741. body_peer++;
  742. }
  743. ieee802_1x_mka_dump_peer_body(body);
  744. return 0;
  745. }
  746. /**
  747. * ieee802_1x_mka_i_in_peerlist -
  748. */
  749. static Boolean
  750. ieee802_1x_mka_i_in_peerlist(struct ieee802_1x_mka_participant *participant,
  751. const u8 *mka_msg, size_t msg_len)
  752. {
  753. Boolean included = FALSE;
  754. struct ieee802_1x_mka_hdr *hdr;
  755. size_t body_len;
  756. size_t left_len;
  757. u8 body_type;
  758. u32 peer_mn;
  759. be32 _peer_mn;
  760. const u8 *peer_mi;
  761. const u8 *pos;
  762. size_t i;
  763. pos = mka_msg;
  764. left_len = msg_len;
  765. while (left_len > (MKA_HDR_LEN + DEFAULT_ICV_LEN)) {
  766. hdr = (struct ieee802_1x_mka_hdr *) pos;
  767. body_len = get_mka_param_body_len(hdr);
  768. body_type = get_mka_param_body_type(hdr);
  769. if (body_type != MKA_LIVE_PEER_LIST &&
  770. body_type != MKA_POTENTIAL_PEER_LIST)
  771. goto SKIP_PEER;
  772. ieee802_1x_mka_dump_peer_body(
  773. (struct ieee802_1x_mka_peer_body *)pos);
  774. if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) {
  775. wpa_printf(MSG_ERROR,
  776. "KaY: MKA Peer Packet Body Length (%d bytes) is less than the Parameter Set Header Length (%d bytes) + the Parameter Set Body Length (%d bytes) + %d bytes of ICV",
  777. (int) left_len, (int) MKA_HDR_LEN,
  778. (int) body_len, DEFAULT_ICV_LEN);
  779. goto SKIP_PEER;
  780. }
  781. if ((body_len % 16) != 0) {
  782. wpa_printf(MSG_ERROR,
  783. "KaY: MKA Peer Packet Body Length (%d bytes) should multiple of 16 octets",
  784. (int) body_len);
  785. goto SKIP_PEER;
  786. }
  787. for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) {
  788. peer_mi = MKA_HDR_LEN + pos + i;
  789. os_memcpy(&_peer_mn, peer_mi + MI_LEN,
  790. sizeof(_peer_mn));
  791. peer_mn = be_to_host32(_peer_mn);
  792. if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0 &&
  793. peer_mn == participant->mn) {
  794. included = TRUE;
  795. break;
  796. }
  797. }
  798. if (included)
  799. return TRUE;
  800. SKIP_PEER:
  801. left_len -= body_len + MKA_HDR_LEN;
  802. pos += body_len + MKA_HDR_LEN;
  803. }
  804. return FALSE;
  805. }
  806. /**
  807. * ieee802_1x_mka_decode_live_peer_body -
  808. */
  809. static int ieee802_1x_mka_decode_live_peer_body(
  810. struct ieee802_1x_mka_participant *participant,
  811. const u8 *peer_msg, size_t msg_len)
  812. {
  813. const struct ieee802_1x_mka_hdr *hdr;
  814. struct ieee802_1x_kay_peer *peer;
  815. size_t body_len;
  816. u32 peer_mn;
  817. be32 _peer_mn;
  818. const u8 *peer_mi;
  819. size_t i;
  820. Boolean is_included;
  821. is_included = ieee802_1x_kay_is_in_live_peer(
  822. participant, participant->current_peer_id.mi);
  823. hdr = (const struct ieee802_1x_mka_hdr *) peer_msg;
  824. body_len = get_mka_param_body_len(hdr);
  825. if (body_len % 16 != 0) {
  826. wpa_printf(MSG_ERROR,
  827. "KaY: MKA Peer Packet Body Length (%zu bytes) should be a multiple of 16 octets",
  828. body_len);
  829. return -1;
  830. }
  831. for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) {
  832. peer_mi = MKA_HDR_LEN + peer_msg + i;
  833. os_memcpy(&_peer_mn, peer_mi + MI_LEN, sizeof(_peer_mn));
  834. peer_mn = be_to_host32(_peer_mn);
  835. /* it is myself */
  836. if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) {
  837. /* My message id is used by other participant */
  838. if (peer_mn > participant->mn) {
  839. if (os_get_random(participant->mi,
  840. sizeof(participant->mi)) < 0)
  841. wpa_printf(MSG_DEBUG,
  842. "KaY: Could not update mi");
  843. participant->mn = 0;
  844. }
  845. continue;
  846. }
  847. if (!is_included)
  848. continue;
  849. peer = ieee802_1x_kay_get_peer(participant, peer_mi);
  850. if (NULL != peer) {
  851. peer->mn = peer_mn;
  852. peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
  853. } else {
  854. if (!ieee802_1x_kay_create_potential_peer(
  855. participant, peer_mi, peer_mn)) {
  856. return -1;
  857. }
  858. }
  859. }
  860. return 0;
  861. }
  862. /**
  863. * ieee802_1x_mka_decode_potential_peer_body -
  864. */
  865. static int
  866. ieee802_1x_mka_decode_potential_peer_body(
  867. struct ieee802_1x_mka_participant *participant,
  868. const u8 *peer_msg, size_t msg_len)
  869. {
  870. struct ieee802_1x_mka_hdr *hdr;
  871. size_t body_len;
  872. u32 peer_mn;
  873. be32 _peer_mn;
  874. const u8 *peer_mi;
  875. size_t i;
  876. hdr = (struct ieee802_1x_mka_hdr *) peer_msg;
  877. body_len = get_mka_param_body_len(hdr);
  878. if (body_len % 16 != 0) {
  879. wpa_printf(MSG_ERROR,
  880. "KaY: MKA Peer Packet Body Length (%zu bytes) should be a multiple of 16 octets",
  881. body_len);
  882. return -1;
  883. }
  884. for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) {
  885. peer_mi = MKA_HDR_LEN + peer_msg + i;
  886. os_memcpy(&_peer_mn, peer_mi + MI_LEN, sizeof(_peer_mn));
  887. peer_mn = be_to_host32(_peer_mn);
  888. /* it is myself */
  889. if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) {
  890. /* My message id is used by other participant */
  891. if (peer_mn > participant->mn) {
  892. if (os_get_random(participant->mi,
  893. sizeof(participant->mi)) < 0)
  894. wpa_printf(MSG_DEBUG,
  895. "KaY: Could not update mi");
  896. participant->mn = 0;
  897. }
  898. continue;
  899. }
  900. }
  901. return 0;
  902. }
  903. /**
  904. * ieee802_1x_mka_sak_use_body_present
  905. */
  906. static Boolean
  907. ieee802_1x_mka_sak_use_body_present(
  908. struct ieee802_1x_mka_participant *participant)
  909. {
  910. if (participant->to_use_sak)
  911. return TRUE;
  912. else
  913. return FALSE;
  914. }
  915. /**
  916. * ieee802_1x_mka_get_sak_use_length
  917. */
  918. static int
  919. ieee802_1x_mka_get_sak_use_length(
  920. struct ieee802_1x_mka_participant *participant)
  921. {
  922. int length = MKA_HDR_LEN;
  923. if (participant->kay->macsec_desired && participant->advised_desired)
  924. length = sizeof(struct ieee802_1x_mka_sak_use_body);
  925. else
  926. length = MKA_HDR_LEN;
  927. length = (length + 0x3) & ~0x3;
  928. return length;
  929. }
  930. /**
  931. *
  932. */
  933. static u32
  934. ieee802_1x_mka_get_lpn(struct ieee802_1x_mka_participant *principal,
  935. struct ieee802_1x_mka_ki *ki)
  936. {
  937. struct receive_sa *rxsa;
  938. struct receive_sc *rxsc;
  939. u32 lpn = 0;
  940. dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) {
  941. dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list)
  942. {
  943. if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) {
  944. secy_get_receive_lowest_pn(principal->kay,
  945. rxsa);
  946. lpn = lpn > rxsa->lowest_pn ?
  947. lpn : rxsa->lowest_pn;
  948. break;
  949. }
  950. }
  951. }
  952. if (lpn == 0)
  953. lpn = 1;
  954. return lpn;
  955. }
  956. /**
  957. * ieee802_1x_mka_encode_sak_use_body -
  958. */
  959. static int
  960. ieee802_1x_mka_encode_sak_use_body(
  961. struct ieee802_1x_mka_participant *participant,
  962. struct wpabuf *buf)
  963. {
  964. struct ieee802_1x_mka_sak_use_body *body;
  965. unsigned int length;
  966. u32 pn = 1;
  967. length = ieee802_1x_mka_get_sak_use_length(participant);
  968. body = wpabuf_put(buf, length);
  969. body->type = MKA_SAK_USE;
  970. set_mka_param_body_len(body, length - MKA_HDR_LEN);
  971. if (length == MKA_HDR_LEN) {
  972. body->ptx = TRUE;
  973. body->prx = TRUE;
  974. body->lan = 0;
  975. body->lrx = FALSE;
  976. body->ltx = FALSE;
  977. body->delay_protect = FALSE;
  978. return 0;
  979. }
  980. /* data protect, lowest accept packet number */
  981. body->delay_protect = participant->kay->macsec_replay_protect;
  982. pn = ieee802_1x_mka_get_lpn(participant, &participant->lki);
  983. if (pn > participant->kay->pn_exhaustion) {
  984. wpa_printf(MSG_WARNING, "KaY: My LPN exhaustion");
  985. if (participant->is_key_server)
  986. participant->new_sak = TRUE;
  987. }
  988. body->llpn = host_to_be32(pn);
  989. pn = ieee802_1x_mka_get_lpn(participant, &participant->oki);
  990. body->olpn = host_to_be32(pn);
  991. /* plain tx, plain rx */
  992. if (participant->kay->macsec_protect)
  993. body->ptx = FALSE;
  994. else
  995. body->ptx = TRUE;
  996. if (participant->kay->macsec_validate == Strict)
  997. body->prx = FALSE;
  998. else
  999. body->prx = TRUE;
  1000. /* latest key: rx, tx, key server member identifier key number */
  1001. body->lan = participant->lan;
  1002. os_memcpy(body->lsrv_mi, participant->lki.mi,
  1003. sizeof(body->lsrv_mi));
  1004. body->lkn = host_to_be32(participant->lki.kn);
  1005. body->lrx = participant->lrx;
  1006. body->ltx = participant->ltx;
  1007. /* old key: rx, tx, key server member identifier key number */
  1008. body->oan = participant->oan;
  1009. if (participant->oki.kn != participant->lki.kn &&
  1010. participant->oki.kn != 0) {
  1011. body->otx = TRUE;
  1012. body->orx = TRUE;
  1013. os_memcpy(body->osrv_mi, participant->oki.mi,
  1014. sizeof(body->osrv_mi));
  1015. body->okn = host_to_be32(participant->oki.kn);
  1016. } else {
  1017. body->otx = FALSE;
  1018. body->orx = FALSE;
  1019. }
  1020. /* set CP's variable */
  1021. if (body->ltx) {
  1022. if (!participant->kay->tx_enable)
  1023. participant->kay->tx_enable = TRUE;
  1024. if (!participant->kay->port_enable)
  1025. participant->kay->port_enable = TRUE;
  1026. }
  1027. if (body->lrx) {
  1028. if (!participant->kay->rx_enable)
  1029. participant->kay->rx_enable = TRUE;
  1030. }
  1031. ieee802_1x_mka_dump_sak_use_body(body);
  1032. return 0;
  1033. }
  1034. /**
  1035. * ieee802_1x_mka_decode_sak_use_body -
  1036. */
  1037. static int
  1038. ieee802_1x_mka_decode_sak_use_body(
  1039. struct ieee802_1x_mka_participant *participant,
  1040. const u8 *mka_msg, size_t msg_len)
  1041. {
  1042. struct ieee802_1x_mka_hdr *hdr;
  1043. struct ieee802_1x_mka_sak_use_body *body;
  1044. struct ieee802_1x_kay_peer *peer;
  1045. struct transmit_sa *txsa;
  1046. struct data_key *sa_key = NULL;
  1047. size_t body_len;
  1048. struct ieee802_1x_mka_ki ki;
  1049. u32 lpn;
  1050. Boolean all_receiving;
  1051. Boolean founded;
  1052. if (!participant->principal) {
  1053. wpa_printf(MSG_WARNING, "KaY: Participant is not principal");
  1054. return -1;
  1055. }
  1056. peer = ieee802_1x_kay_get_live_peer(participant,
  1057. participant->current_peer_id.mi);
  1058. if (!peer) {
  1059. wpa_printf(MSG_WARNING, "KaY: the peer is not my live peer");
  1060. return -1;
  1061. }
  1062. hdr = (struct ieee802_1x_mka_hdr *) mka_msg;
  1063. body_len = get_mka_param_body_len(hdr);
  1064. body = (struct ieee802_1x_mka_sak_use_body *) mka_msg;
  1065. ieee802_1x_mka_dump_sak_use_body(body);
  1066. if ((body_len != 0) && (body_len < 40)) {
  1067. wpa_printf(MSG_ERROR,
  1068. "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 0, 40, or more octets",
  1069. (int) body_len);
  1070. return -1;
  1071. }
  1072. /* TODO: what action should I take when peer does not support MACsec */
  1073. if (body_len == 0) {
  1074. wpa_printf(MSG_WARNING, "KaY: Peer does not support MACsec");
  1075. return 0;
  1076. }
  1077. /* TODO: when the plain tx or rx of peer is true, should I change
  1078. * the attribute of controlled port
  1079. */
  1080. if (body->prx)
  1081. wpa_printf(MSG_WARNING, "KaY: peer's plain rx are TRUE");
  1082. if (body->ptx)
  1083. wpa_printf(MSG_WARNING, "KaY: peer's plain tx are TRUE");
  1084. /* check latest key is valid */
  1085. if (body->ltx || body->lrx) {
  1086. founded = FALSE;
  1087. os_memcpy(ki.mi, body->lsrv_mi, sizeof(ki.mi));
  1088. ki.kn = be_to_host32(body->lkn);
  1089. dl_list_for_each(sa_key, &participant->sak_list,
  1090. struct data_key, list) {
  1091. if (is_ki_equal(&sa_key->key_identifier, &ki)) {
  1092. founded = TRUE;
  1093. break;
  1094. }
  1095. }
  1096. if (!founded) {
  1097. wpa_printf(MSG_WARNING, "KaY: Latest key is invalid");
  1098. return -1;
  1099. }
  1100. if (os_memcmp(participant->lki.mi, body->lsrv_mi,
  1101. sizeof(participant->lki.mi)) == 0 &&
  1102. be_to_host32(body->lkn) == participant->lki.kn &&
  1103. body->lan == participant->lan) {
  1104. peer->sak_used = TRUE;
  1105. }
  1106. if (body->ltx && peer->is_key_server) {
  1107. ieee802_1x_cp_set_servertransmitting(
  1108. participant->kay->cp, TRUE);
  1109. ieee802_1x_cp_sm_step(participant->kay->cp);
  1110. }
  1111. }
  1112. /* check old key is valid */
  1113. if (body->otx || body->orx) {
  1114. if (os_memcmp(participant->oki.mi, body->osrv_mi,
  1115. sizeof(participant->oki.mi)) != 0 ||
  1116. be_to_host32(body->okn) != participant->oki.kn ||
  1117. body->oan != participant->oan) {
  1118. wpa_printf(MSG_WARNING, "KaY: Old key is invalid");
  1119. return -1;
  1120. }
  1121. }
  1122. /* TODO: how to set the MACsec hardware when delay_protect is true */
  1123. if (body->delay_protect &&
  1124. (!be_to_host32(body->llpn) || !be_to_host32(body->olpn))) {
  1125. wpa_printf(MSG_WARNING,
  1126. "KaY: Lowest packet number should greater than 0 when delay_protect is TRUE");
  1127. return -1;
  1128. }
  1129. /* check all live peer have used the sak for receiving sa */
  1130. all_receiving = TRUE;
  1131. dl_list_for_each(peer, &participant->live_peers,
  1132. struct ieee802_1x_kay_peer, list) {
  1133. if (!peer->sak_used) {
  1134. all_receiving = FALSE;
  1135. break;
  1136. }
  1137. }
  1138. if (all_receiving) {
  1139. participant->to_dist_sak = FALSE;
  1140. ieee802_1x_cp_set_allreceiving(participant->kay->cp, TRUE);
  1141. ieee802_1x_cp_sm_step(participant->kay->cp);
  1142. }
  1143. /* if i'm key server, and detects peer member pn exhaustion, rekey.*/
  1144. lpn = be_to_host32(body->llpn);
  1145. if (lpn > participant->kay->pn_exhaustion) {
  1146. if (participant->is_key_server) {
  1147. participant->new_sak = TRUE;
  1148. wpa_printf(MSG_WARNING, "KaY: Peer LPN exhaustion");
  1149. }
  1150. }
  1151. founded = FALSE;
  1152. dl_list_for_each(txsa, &participant->txsc->sa_list,
  1153. struct transmit_sa, list) {
  1154. if (sa_key != NULL && txsa->pkey == sa_key) {
  1155. founded = TRUE;
  1156. break;
  1157. }
  1158. }
  1159. if (!founded) {
  1160. wpa_printf(MSG_WARNING, "KaY: Can't find txsa");
  1161. return -1;
  1162. }
  1163. /* FIXME: Secy creates txsa with default npn. If MKA detected Latest Key
  1164. * npn is larger than txsa's npn, set it to txsa.
  1165. */
  1166. secy_get_transmit_next_pn(participant->kay, txsa);
  1167. if (lpn > txsa->next_pn) {
  1168. secy_set_transmit_next_pn(participant->kay, txsa);
  1169. wpa_printf(MSG_INFO, "KaY: update lpn =0x%x", lpn);
  1170. }
  1171. return 0;
  1172. }
  1173. /**
  1174. * ieee802_1x_mka_dist_sak_body_present
  1175. */
  1176. static Boolean
  1177. ieee802_1x_mka_dist_sak_body_present(
  1178. struct ieee802_1x_mka_participant *participant)
  1179. {
  1180. if (!participant->to_dist_sak || !participant->new_key)
  1181. return FALSE;
  1182. return TRUE;
  1183. }
  1184. /**
  1185. * ieee802_1x_kay_get_dist_sak_length
  1186. */
  1187. static int
  1188. ieee802_1x_mka_get_dist_sak_length(
  1189. struct ieee802_1x_mka_participant *participant)
  1190. {
  1191. int length;
  1192. int cs_index = participant->kay->macsec_csindex;
  1193. if (participant->advised_desired) {
  1194. length = sizeof(struct ieee802_1x_mka_dist_sak_body);
  1195. if (cs_index != DEFAULT_CS_INDEX)
  1196. length += CS_ID_LEN;
  1197. length += cipher_suite_tbl[cs_index].sak_len + 8;
  1198. } else {
  1199. length = MKA_HDR_LEN;
  1200. }
  1201. length = (length + 0x3) & ~0x3;
  1202. return length;
  1203. }
  1204. /**
  1205. * ieee802_1x_mka_encode_dist_sak_body -
  1206. */
  1207. static int
  1208. ieee802_1x_mka_encode_dist_sak_body(
  1209. struct ieee802_1x_mka_participant *participant,
  1210. struct wpabuf *buf)
  1211. {
  1212. struct ieee802_1x_mka_dist_sak_body *body;
  1213. struct data_key *sak;
  1214. unsigned int length;
  1215. int cs_index;
  1216. int sak_pos;
  1217. length = ieee802_1x_mka_get_dist_sak_length(participant);
  1218. body = wpabuf_put(buf, length);
  1219. body->type = MKA_DISTRIBUTED_SAK;
  1220. set_mka_param_body_len(body, length - MKA_HDR_LEN);
  1221. if (length == MKA_HDR_LEN) {
  1222. body->confid_offset = 0;
  1223. body->dan = 0;
  1224. return 0;
  1225. }
  1226. sak = participant->new_key;
  1227. body->confid_offset = sak->confidentiality_offset;
  1228. body->dan = sak->an;
  1229. body->kn = host_to_be32(sak->key_identifier.kn);
  1230. cs_index = participant->kay->macsec_csindex;
  1231. sak_pos = 0;
  1232. if (cs_index != DEFAULT_CS_INDEX) {
  1233. os_memcpy(body->sak, cipher_suite_tbl[cs_index].id, CS_ID_LEN);
  1234. sak_pos = CS_ID_LEN;
  1235. }
  1236. if (aes_wrap(participant->kek.key, 16,
  1237. cipher_suite_tbl[cs_index].sak_len / 8,
  1238. sak->key, body->sak + sak_pos)) {
  1239. wpa_printf(MSG_ERROR, "KaY: AES wrap failed");
  1240. return -1;
  1241. }
  1242. ieee802_1x_mka_dump_dist_sak_body(body);
  1243. return 0;
  1244. }
  1245. /**
  1246. * ieee802_1x_kay_init_data_key -
  1247. */
  1248. static struct data_key *
  1249. ieee802_1x_kay_init_data_key(const struct key_conf *conf)
  1250. {
  1251. struct data_key *pkey;
  1252. if (!conf)
  1253. return NULL;
  1254. pkey = os_zalloc(sizeof(*pkey));
  1255. if (pkey == NULL) {
  1256. wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
  1257. return NULL;
  1258. }
  1259. pkey->key = os_zalloc(conf->key_len);
  1260. if (pkey->key == NULL) {
  1261. wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
  1262. os_free(pkey);
  1263. return NULL;
  1264. }
  1265. os_memcpy(pkey->key, conf->key, conf->key_len);
  1266. os_memcpy(&pkey->key_identifier, &conf->ki,
  1267. sizeof(pkey->key_identifier));
  1268. pkey->confidentiality_offset = conf->offset;
  1269. pkey->an = conf->an;
  1270. pkey->transmits = conf->tx;
  1271. pkey->receives = conf->rx;
  1272. os_get_time(&pkey->created_time);
  1273. pkey->user = 1;
  1274. return pkey;
  1275. }
  1276. /**
  1277. * ieee802_1x_kay_decode_dist_sak_body -
  1278. */
  1279. static int
  1280. ieee802_1x_mka_decode_dist_sak_body(
  1281. struct ieee802_1x_mka_participant *participant,
  1282. const u8 *mka_msg, size_t msg_len)
  1283. {
  1284. struct ieee802_1x_mka_hdr *hdr;
  1285. struct ieee802_1x_mka_dist_sak_body *body;
  1286. struct ieee802_1x_kay_peer *peer;
  1287. struct macsec_ciphersuite *cs;
  1288. size_t body_len;
  1289. struct key_conf *conf;
  1290. struct data_key *sa_key = NULL;
  1291. struct ieee802_1x_mka_ki sak_ki;
  1292. int sak_len;
  1293. u8 *wrap_sak;
  1294. u8 *unwrap_sak;
  1295. hdr = (struct ieee802_1x_mka_hdr *) mka_msg;
  1296. body_len = get_mka_param_body_len(hdr);
  1297. if ((body_len != 0) && (body_len != 28) && (body_len < 36)) {
  1298. wpa_printf(MSG_ERROR,
  1299. "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 0, 28, 36, or more octets",
  1300. (int) body_len);
  1301. return -1;
  1302. }
  1303. if (!participant->principal) {
  1304. wpa_printf(MSG_ERROR,
  1305. "KaY: I can't accept the distributed SAK as I am not principal");
  1306. return -1;
  1307. }
  1308. if (participant->is_key_server) {
  1309. wpa_printf(MSG_ERROR,
  1310. "KaY: I can't accept the distributed SAK as myself is key server ");
  1311. return -1;
  1312. }
  1313. if (!participant->kay->macsec_desired ||
  1314. participant->kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) {
  1315. wpa_printf(MSG_ERROR,
  1316. "KaY: I am not MACsec-desired or without MACsec capable");
  1317. return -1;
  1318. }
  1319. peer = ieee802_1x_kay_get_live_peer(participant,
  1320. participant->current_peer_id.mi);
  1321. if (!peer) {
  1322. wpa_printf(MSG_ERROR,
  1323. "KaY: The key server is not in my live peers list");
  1324. return -1;
  1325. }
  1326. if (!sci_equal(&participant->kay->key_server_sci, &peer->sci)) {
  1327. wpa_printf(MSG_ERROR, "KaY: The key server is not elected");
  1328. return -1;
  1329. }
  1330. if (body_len == 0) {
  1331. participant->kay->authenticated = TRUE;
  1332. participant->kay->secured = FALSE;
  1333. participant->kay->failed = FALSE;
  1334. participant->advised_desired = FALSE;
  1335. ieee802_1x_cp_connect_authenticated(participant->kay->cp);
  1336. ieee802_1x_cp_sm_step(participant->kay->cp);
  1337. wpa_printf(MSG_WARNING, "KaY:The Key server advise no MACsec");
  1338. participant->to_use_sak = TRUE;
  1339. return 0;
  1340. }
  1341. participant->advised_desired = TRUE;
  1342. participant->kay->authenticated = FALSE;
  1343. participant->kay->secured = TRUE;
  1344. participant->kay->failed = FALSE;
  1345. ieee802_1x_cp_connect_secure(participant->kay->cp);
  1346. ieee802_1x_cp_sm_step(participant->kay->cp);
  1347. body = (struct ieee802_1x_mka_dist_sak_body *)mka_msg;
  1348. ieee802_1x_mka_dump_dist_sak_body(body);
  1349. dl_list_for_each(sa_key, &participant->sak_list, struct data_key, list)
  1350. {
  1351. if (os_memcmp(sa_key->key_identifier.mi,
  1352. participant->current_peer_id.mi, MI_LEN) == 0 &&
  1353. sa_key->key_identifier.kn == be_to_host32(body->kn)) {
  1354. wpa_printf(MSG_WARNING, "KaY:The Key has installed");
  1355. return 0;
  1356. }
  1357. }
  1358. if (body_len == 28) {
  1359. sak_len = DEFAULT_SA_KEY_LEN;
  1360. wrap_sak = body->sak;
  1361. participant->kay->macsec_csindex = DEFAULT_CS_INDEX;
  1362. } else {
  1363. cs = ieee802_1x_kay_get_cipher_suite(participant, body->sak);
  1364. if (!cs) {
  1365. wpa_printf(MSG_ERROR,
  1366. "KaY: I can't support the Cipher Suite advised by key server");
  1367. return -1;
  1368. }
  1369. sak_len = cs->sak_len;
  1370. wrap_sak = body->sak + CS_ID_LEN;
  1371. participant->kay->macsec_csindex = cs->index;
  1372. }
  1373. unwrap_sak = os_zalloc(sak_len);
  1374. if (!unwrap_sak) {
  1375. wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
  1376. return -1;
  1377. }
  1378. if (aes_unwrap(participant->kek.key, 16, sak_len >> 3, wrap_sak,
  1379. unwrap_sak)) {
  1380. wpa_printf(MSG_ERROR, "KaY: AES unwrap failed");
  1381. os_free(unwrap_sak);
  1382. return -1;
  1383. }
  1384. wpa_hexdump(MSG_DEBUG, "\tAES Key Unwrap of SAK:", unwrap_sak, sak_len);
  1385. conf = os_zalloc(sizeof(*conf));
  1386. if (!conf) {
  1387. wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
  1388. os_free(unwrap_sak);
  1389. return -1;
  1390. }
  1391. conf->key_len = sak_len;
  1392. conf->key = os_zalloc(conf->key_len);
  1393. if (!conf->key) {
  1394. wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
  1395. os_free(unwrap_sak);
  1396. os_free(conf);
  1397. return -1;
  1398. }
  1399. os_memcpy(conf->key, unwrap_sak, conf->key_len);
  1400. os_memcpy(&sak_ki.mi, &participant->current_peer_id.mi,
  1401. sizeof(sak_ki.mi));
  1402. sak_ki.kn = be_to_host32(body->kn);
  1403. os_memcpy(conf->ki.mi, sak_ki.mi, MI_LEN);
  1404. conf->ki.kn = sak_ki.kn;
  1405. conf->an = body->dan;
  1406. conf->offset = body->confid_offset;
  1407. conf->rx = TRUE;
  1408. conf->tx = TRUE;
  1409. sa_key = ieee802_1x_kay_init_data_key(conf);
  1410. if (!sa_key) {
  1411. os_free(unwrap_sak);
  1412. os_free(conf->key);
  1413. os_free(conf);
  1414. return -1;
  1415. }
  1416. dl_list_add(&participant->sak_list, &sa_key->list);
  1417. ieee802_1x_cp_set_ciphersuite(
  1418. participant->kay->cp,
  1419. cipher_suite_tbl[participant->kay->macsec_csindex].id);
  1420. ieee802_1x_cp_sm_step(participant->kay->cp);
  1421. ieee802_1x_cp_set_offset(participant->kay->cp, body->confid_offset);
  1422. ieee802_1x_cp_sm_step(participant->kay->cp);
  1423. ieee802_1x_cp_set_distributedki(participant->kay->cp, &sak_ki);
  1424. ieee802_1x_cp_set_distributedan(participant->kay->cp, body->dan);
  1425. ieee802_1x_cp_signal_newsak(participant->kay->cp);
  1426. ieee802_1x_cp_sm_step(participant->kay->cp);
  1427. participant->to_use_sak = TRUE;
  1428. os_free(unwrap_sak);
  1429. os_free(conf->key);
  1430. os_free(conf);
  1431. return 0;
  1432. }
  1433. /**
  1434. * ieee802_1x_mka_icv_body_present
  1435. */
  1436. static Boolean
  1437. ieee802_1x_mka_icv_body_present(struct ieee802_1x_mka_participant *participant)
  1438. {
  1439. return TRUE;
  1440. }
  1441. /**
  1442. * ieee802_1x_kay_get_icv_length
  1443. */
  1444. static int
  1445. ieee802_1x_mka_get_icv_length(struct ieee802_1x_mka_participant *participant)
  1446. {
  1447. int length;
  1448. length = sizeof(struct ieee802_1x_mka_icv_body);
  1449. length += mka_alg_tbl[participant->kay->mka_algindex].icv_len;
  1450. return (length + 0x3) & ~0x3;
  1451. }
  1452. /**
  1453. * ieee802_1x_mka_encode_icv_body -
  1454. */
  1455. static int
  1456. ieee802_1x_mka_encode_icv_body(struct ieee802_1x_mka_participant *participant,
  1457. struct wpabuf *buf)
  1458. {
  1459. struct ieee802_1x_mka_icv_body *body;
  1460. unsigned int length;
  1461. u8 cmac[MAX_ICV_LEN];
  1462. length = ieee802_1x_mka_get_icv_length(participant);
  1463. if (length != DEFAULT_ICV_LEN) {
  1464. body = wpabuf_put(buf, MKA_HDR_LEN);
  1465. body->type = MKA_ICV_INDICATOR;
  1466. set_mka_param_body_len(body, length - MKA_HDR_LEN);
  1467. }
  1468. if (mka_alg_tbl[participant->kay->mka_algindex].icv_hash(
  1469. participant->ick.key, wpabuf_head(buf), buf->used, cmac)) {
  1470. wpa_printf(MSG_ERROR, "KaY, omac1_aes_128 failed");
  1471. return -1;
  1472. }
  1473. if (length != DEFAULT_ICV_LEN) {
  1474. os_memcpy(wpabuf_put(buf, length - MKA_HDR_LEN), cmac,
  1475. length - MKA_HDR_LEN);
  1476. } else {
  1477. os_memcpy(wpabuf_put(buf, length), cmac, length);
  1478. }
  1479. return 0;
  1480. }
  1481. /**
  1482. * ieee802_1x_mka_decode_icv_body -
  1483. */
  1484. static u8 *
  1485. ieee802_1x_mka_decode_icv_body(struct ieee802_1x_mka_participant *participant,
  1486. const u8 *mka_msg, size_t msg_len)
  1487. {
  1488. struct ieee802_1x_mka_hdr *hdr;
  1489. struct ieee802_1x_mka_icv_body *body;
  1490. size_t body_len;
  1491. size_t left_len;
  1492. u8 body_type;
  1493. const u8 *pos;
  1494. pos = mka_msg;
  1495. left_len = msg_len;
  1496. while (left_len > (MKA_HDR_LEN + DEFAULT_ICV_LEN)) {
  1497. hdr = (struct ieee802_1x_mka_hdr *) pos;
  1498. body_len = get_mka_param_body_len(hdr);
  1499. body_type = get_mka_param_body_type(hdr);
  1500. if (left_len < (body_len + MKA_HDR_LEN))
  1501. break;
  1502. if (body_type != MKA_ICV_INDICATOR) {
  1503. left_len -= MKA_HDR_LEN + body_len;
  1504. pos += MKA_HDR_LEN + body_len;
  1505. continue;
  1506. }
  1507. body = (struct ieee802_1x_mka_icv_body *)pos;
  1508. if (body_len
  1509. < mka_alg_tbl[participant->kay->mka_algindex].icv_len) {
  1510. return NULL;
  1511. }
  1512. return body->icv;
  1513. }
  1514. return (u8 *) (mka_msg + msg_len - DEFAULT_ICV_LEN);
  1515. }
  1516. /**
  1517. * ieee802_1x_mka_decode_dist_cak_body-
  1518. */
  1519. static int
  1520. ieee802_1x_mka_decode_dist_cak_body(
  1521. struct ieee802_1x_mka_participant *participant,
  1522. const u8 *mka_msg, size_t msg_len)
  1523. {
  1524. struct ieee802_1x_mka_hdr *hdr;
  1525. size_t body_len;
  1526. hdr = (struct ieee802_1x_mka_hdr *) mka_msg;
  1527. body_len = get_mka_param_body_len(hdr);
  1528. if (body_len < 28) {
  1529. wpa_printf(MSG_ERROR,
  1530. "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 28 or more octets",
  1531. (int) body_len);
  1532. return -1;
  1533. }
  1534. return 0;
  1535. }
  1536. /**
  1537. * ieee802_1x_mka_decode_kmd_body -
  1538. */
  1539. static int
  1540. ieee802_1x_mka_decode_kmd_body(
  1541. struct ieee802_1x_mka_participant *participant,
  1542. const u8 *mka_msg, size_t msg_len)
  1543. {
  1544. struct ieee802_1x_mka_hdr *hdr;
  1545. size_t body_len;
  1546. hdr = (struct ieee802_1x_mka_hdr *) mka_msg;
  1547. body_len = get_mka_param_body_len(hdr);
  1548. if (body_len < 5) {
  1549. wpa_printf(MSG_ERROR,
  1550. "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 5 or more octets",
  1551. (int) body_len);
  1552. return -1;
  1553. }
  1554. return 0;
  1555. }
  1556. /**
  1557. * ieee802_1x_mka_decode_announce_body -
  1558. */
  1559. static int ieee802_1x_mka_decode_announce_body(
  1560. struct ieee802_1x_mka_participant *participant,
  1561. const u8 *mka_msg, size_t msg_len)
  1562. {
  1563. return 0;
  1564. }
  1565. static struct mka_param_body_handler mka_body_handler[] = {
  1566. /* basic parameter set */
  1567. {
  1568. ieee802_1x_mka_encode_basic_body,
  1569. NULL,
  1570. ieee802_1x_mka_basic_body_length,
  1571. ieee802_1x_mka_basic_body_present
  1572. },
  1573. /* live peer list parameter set */
  1574. {
  1575. ieee802_1x_mka_encode_live_peer_body,
  1576. ieee802_1x_mka_decode_live_peer_body,
  1577. ieee802_1x_mka_get_live_peer_length,
  1578. ieee802_1x_mka_live_peer_body_present
  1579. },
  1580. /* potential peer list parameter set */
  1581. {
  1582. ieee802_1x_mka_encode_potential_peer_body,
  1583. ieee802_1x_mka_decode_potential_peer_body,
  1584. ieee802_1x_mka_get_potential_peer_length,
  1585. ieee802_1x_mka_potential_peer_body_present
  1586. },
  1587. /* sak use parameter set */
  1588. {
  1589. ieee802_1x_mka_encode_sak_use_body,
  1590. ieee802_1x_mka_decode_sak_use_body,
  1591. ieee802_1x_mka_get_sak_use_length,
  1592. ieee802_1x_mka_sak_use_body_present
  1593. },
  1594. /* distribute sak parameter set */
  1595. {
  1596. ieee802_1x_mka_encode_dist_sak_body,
  1597. ieee802_1x_mka_decode_dist_sak_body,
  1598. ieee802_1x_mka_get_dist_sak_length,
  1599. ieee802_1x_mka_dist_sak_body_present
  1600. },
  1601. /* distribute cak parameter set */
  1602. {
  1603. NULL,
  1604. ieee802_1x_mka_decode_dist_cak_body,
  1605. NULL,
  1606. NULL
  1607. },
  1608. /* kmd parameter set */
  1609. {
  1610. NULL,
  1611. ieee802_1x_mka_decode_kmd_body,
  1612. NULL,
  1613. NULL
  1614. },
  1615. /* announce parameter set */
  1616. {
  1617. NULL,
  1618. ieee802_1x_mka_decode_announce_body,
  1619. NULL,
  1620. NULL
  1621. },
  1622. /* icv parameter set */
  1623. {
  1624. ieee802_1x_mka_encode_icv_body,
  1625. NULL,
  1626. ieee802_1x_mka_get_icv_length,
  1627. ieee802_1x_mka_icv_body_present
  1628. },
  1629. };
  1630. /**
  1631. * ieee802_1x_kay_deinit_data_key -
  1632. */
  1633. static void ieee802_1x_kay_deinit_data_key(struct data_key *pkey)
  1634. {
  1635. if (!pkey)
  1636. return;
  1637. pkey->user--;
  1638. if (pkey->user > 1)
  1639. return;
  1640. dl_list_del(&pkey->list);
  1641. os_free(pkey->key);
  1642. os_free(pkey);
  1643. }
  1644. /**
  1645. * ieee802_1x_kay_generate_new_sak -
  1646. */
  1647. static int
  1648. ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
  1649. {
  1650. struct data_key *sa_key = NULL;
  1651. struct key_conf *conf;
  1652. struct ieee802_1x_kay_peer *peer;
  1653. struct ieee802_1x_kay *kay = participant->kay;
  1654. int ctx_len, ctx_offset;
  1655. u8 *context;
  1656. /* check condition for generating a fresh SAK:
  1657. * must have one live peer
  1658. * and MKA life time elapse since last distribution
  1659. * or potential peer is empty
  1660. */
  1661. if (dl_list_empty(&participant->live_peers)) {
  1662. wpa_printf(MSG_ERROR,
  1663. "KaY: Live peers list must not empty when generating fresh SAK");
  1664. return -1;
  1665. }
  1666. /* FIXME: A fresh SAK not generated until
  1667. * the live peer list contains at least one peer and
  1668. * MKA life time has elapsed since the prior SAK was first distributed,
  1669. * or the Key server's potential peer is empty
  1670. * but I can't understand the second item, so
  1671. * here only check first item and ingore
  1672. * && (!dl_list_empty(&participant->potential_peers))) {
  1673. */
  1674. if ((time(NULL) - kay->dist_time) < MKA_LIFE_TIME / 1000) {
  1675. wpa_printf(MSG_ERROR,
  1676. "KaY: Life time have not elapsed since prior SAK distributed");
  1677. return -1;
  1678. }
  1679. conf = os_zalloc(sizeof(*conf));
  1680. if (!conf) {
  1681. wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
  1682. return -1;
  1683. }
  1684. conf->key_len = cipher_suite_tbl[kay->macsec_csindex].sak_len;
  1685. conf->key = os_zalloc(conf->key_len);
  1686. if (!conf->key) {
  1687. os_free(conf);
  1688. wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
  1689. return -1;
  1690. }
  1691. ctx_len = conf->key_len + sizeof(kay->dist_kn);
  1692. dl_list_for_each(peer, &participant->live_peers,
  1693. struct ieee802_1x_kay_peer, list)
  1694. ctx_len += sizeof(peer->mi);
  1695. ctx_len += sizeof(participant->mi);
  1696. context = os_zalloc(ctx_len);
  1697. if (!context) {
  1698. os_free(conf->key);
  1699. os_free(conf);
  1700. return -1;
  1701. }
  1702. ctx_offset = 0;
  1703. if (os_get_random(context + ctx_offset, conf->key_len) < 0) {
  1704. os_free(context);
  1705. os_free(conf->key);
  1706. os_free(conf);
  1707. return -1;
  1708. }
  1709. ctx_offset += conf->key_len;
  1710. dl_list_for_each(peer, &participant->live_peers,
  1711. struct ieee802_1x_kay_peer, list) {
  1712. os_memcpy(context + ctx_offset, peer->mi, sizeof(peer->mi));
  1713. ctx_offset += sizeof(peer->mi);
  1714. }
  1715. os_memcpy(context + ctx_offset, participant->mi,
  1716. sizeof(participant->mi));
  1717. ctx_offset += sizeof(participant->mi);
  1718. os_memcpy(context + ctx_offset, &kay->dist_kn, sizeof(kay->dist_kn));
  1719. if (conf->key_len == 16) {
  1720. ieee802_1x_sak_128bits_aes_cmac(participant->cak.key,
  1721. context, ctx_len, conf->key);
  1722. } else if (conf->key_len == 32) {
  1723. ieee802_1x_sak_128bits_aes_cmac(participant->cak.key,
  1724. context, ctx_len, conf->key);
  1725. } else {
  1726. wpa_printf(MSG_ERROR, "KaY: SAK Length not support");
  1727. os_free(conf->key);
  1728. os_free(conf);
  1729. os_free(context);
  1730. return -1;
  1731. }
  1732. wpa_hexdump(MSG_DEBUG, "KaY: generated new SAK",
  1733. conf->key, conf->key_len);
  1734. os_memcpy(conf->ki.mi, participant->mi, MI_LEN);
  1735. conf->ki.kn = participant->kay->dist_kn;
  1736. conf->an = participant->kay->dist_an;
  1737. conf->offset = kay->macsec_confidentiality;
  1738. conf->rx = TRUE;
  1739. conf->tx = TRUE;
  1740. sa_key = ieee802_1x_kay_init_data_key(conf);
  1741. if (!sa_key) {
  1742. os_free(conf->key);
  1743. os_free(conf);
  1744. os_free(context);
  1745. return -1;
  1746. }
  1747. participant->new_key = sa_key;
  1748. dl_list_add(&participant->sak_list, &sa_key->list);
  1749. ieee802_1x_cp_set_ciphersuite(participant->kay->cp,
  1750. cipher_suite_tbl[kay->macsec_csindex].id);
  1751. ieee802_1x_cp_sm_step(kay->cp);
  1752. ieee802_1x_cp_set_offset(kay->cp, conf->offset);
  1753. ieee802_1x_cp_sm_step(kay->cp);
  1754. ieee802_1x_cp_set_distributedki(kay->cp, &conf->ki);
  1755. ieee802_1x_cp_set_distributedan(kay->cp, conf->an);
  1756. ieee802_1x_cp_signal_newsak(kay->cp);
  1757. ieee802_1x_cp_sm_step(kay->cp);
  1758. dl_list_for_each(peer, &participant->live_peers,
  1759. struct ieee802_1x_kay_peer, list)
  1760. peer->sak_used = FALSE;
  1761. participant->kay->dist_kn++;
  1762. participant->kay->dist_an++;
  1763. if (participant->kay->dist_an > 3)
  1764. participant->kay->dist_an = 0;
  1765. participant->kay->dist_time = time(NULL);
  1766. os_free(conf->key);
  1767. os_free(conf);
  1768. os_free(context);
  1769. return 0;
  1770. }
  1771. /**
  1772. * ieee802_1x_kay_elect_key_server - elect the key server
  1773. * when to elect: whenever the live peers list changes
  1774. */
  1775. static int
  1776. ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
  1777. {
  1778. struct ieee802_1x_kay_peer *peer;
  1779. struct ieee802_1x_kay_peer *key_server = NULL;
  1780. struct ieee802_1x_kay *kay = participant->kay;
  1781. Boolean i_is_key_server;
  1782. if (participant->is_obliged_key_server) {
  1783. participant->new_sak = TRUE;
  1784. participant->to_dist_sak = FALSE;
  1785. ieee802_1x_cp_set_electedself(kay->cp, TRUE);
  1786. return 0;
  1787. }
  1788. /* elect the key server among the peers */
  1789. dl_list_for_each(peer, &participant->live_peers,
  1790. struct ieee802_1x_kay_peer, list) {
  1791. if (!peer->is_key_server)
  1792. continue;
  1793. if (!key_server) {
  1794. key_server = peer;
  1795. continue;
  1796. }
  1797. if (peer->key_server_priority <
  1798. key_server->key_server_priority) {
  1799. key_server = peer;
  1800. } else if (peer->key_server_priority ==
  1801. key_server->key_server_priority) {
  1802. if (os_memcmp(peer->sci.addr, key_server->sci.addr,
  1803. ETH_ALEN) < 0)
  1804. key_server = peer;
  1805. }
  1806. }
  1807. /* elect the key server between me and the above elected peer */
  1808. i_is_key_server = FALSE;
  1809. if (key_server && participant->can_be_key_server) {
  1810. if (kay->actor_priority
  1811. < key_server->key_server_priority) {
  1812. i_is_key_server = TRUE;
  1813. } else if (kay->actor_priority
  1814. == key_server->key_server_priority) {
  1815. if (os_memcmp(kay->actor_sci.addr, key_server->sci.addr,
  1816. ETH_ALEN) < 0)
  1817. i_is_key_server = TRUE;
  1818. }
  1819. } else if (participant->can_be_key_server) {
  1820. i_is_key_server = TRUE;
  1821. }
  1822. if (i_is_key_server) {
  1823. ieee802_1x_cp_set_electedself(kay->cp, TRUE);
  1824. if (!sci_equal(&kay->key_server_sci, &kay->actor_sci)) {
  1825. ieee802_1x_cp_signal_chgdserver(kay->cp);
  1826. ieee802_1x_cp_sm_step(kay->cp);
  1827. }
  1828. participant->is_key_server = TRUE;
  1829. participant->principal = TRUE;
  1830. participant->new_sak = TRUE;
  1831. wpa_printf(MSG_DEBUG, "KaY: I is elected as key server");
  1832. participant->to_dist_sak = FALSE;
  1833. participant->is_elected = TRUE;
  1834. os_memcpy(&kay->key_server_sci, &kay->actor_sci,
  1835. sizeof(kay->key_server_sci));
  1836. kay->key_server_priority = kay->actor_priority;
  1837. } else if (key_server) {
  1838. ieee802_1x_cp_set_electedself(kay->cp, FALSE);
  1839. if (!sci_equal(&kay->key_server_sci, &key_server->sci)) {
  1840. ieee802_1x_cp_signal_chgdserver(kay->cp);
  1841. ieee802_1x_cp_sm_step(kay->cp);
  1842. }
  1843. participant->is_key_server = FALSE;
  1844. participant->principal = TRUE;
  1845. participant->is_elected = TRUE;
  1846. os_memcpy(&kay->key_server_sci, &key_server->sci,
  1847. sizeof(kay->key_server_sci));
  1848. kay->key_server_priority = key_server->key_server_priority;
  1849. } else {
  1850. participant->principal = FALSE;
  1851. participant->is_key_server = FALSE;
  1852. participant->is_elected = FALSE;
  1853. }
  1854. return 0;
  1855. }
  1856. /**
  1857. * ieee802_1x_kay_decide_macsec_use - the key server determinate
  1858. * how to use MACsec: whether use MACsec and its capability
  1859. * protectFrames will be advised if the key server and one of its live peers are
  1860. * MACsec capable and one of those request MACsec protection
  1861. */
  1862. static int
  1863. ieee802_1x_kay_decide_macsec_use(
  1864. struct ieee802_1x_mka_participant *participant)
  1865. {
  1866. struct ieee802_1x_kay *kay = participant->kay;
  1867. struct ieee802_1x_kay_peer *peer;
  1868. enum macsec_cap less_capability;
  1869. Boolean has_peer;
  1870. if (!participant->is_key_server)
  1871. return -1;
  1872. /* key server self is MACsec-desired and requesting MACsec */
  1873. if (!kay->macsec_desired) {
  1874. participant->advised_desired = FALSE;
  1875. return -1;
  1876. }
  1877. if (kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) {
  1878. participant->advised_desired = FALSE;
  1879. return -1;
  1880. }
  1881. less_capability = kay->macsec_capable;
  1882. /* at least one of peers is MACsec-desired and requesting MACsec */
  1883. has_peer = FALSE;
  1884. dl_list_for_each(peer, &participant->live_peers,
  1885. struct ieee802_1x_kay_peer, list) {
  1886. if (!peer->macsec_desired)
  1887. continue;
  1888. if (peer->macsec_capability == MACSEC_CAP_NOT_IMPLEMENTED)
  1889. continue;
  1890. less_capability = (less_capability < peer->macsec_capability) ?
  1891. less_capability : peer->macsec_capability;
  1892. has_peer = TRUE;
  1893. }
  1894. if (has_peer) {
  1895. participant->advised_desired = TRUE;
  1896. participant->advised_capability = less_capability;
  1897. kay->authenticated = FALSE;
  1898. kay->secured = TRUE;
  1899. kay->failed = FALSE;
  1900. ieee802_1x_cp_connect_secure(kay->cp);
  1901. ieee802_1x_cp_sm_step(kay->cp);
  1902. } else {
  1903. participant->advised_desired = FALSE;
  1904. participant->advised_capability = MACSEC_CAP_NOT_IMPLEMENTED;
  1905. participant->to_use_sak = FALSE;
  1906. kay->authenticated = TRUE;
  1907. kay->secured = FALSE;
  1908. kay->failed = FALSE;
  1909. kay->ltx_kn = 0;
  1910. kay->ltx_an = 0;
  1911. kay->lrx_kn = 0;
  1912. kay->lrx_an = 0;
  1913. kay->otx_kn = 0;
  1914. kay->otx_an = 0;
  1915. kay->orx_kn = 0;
  1916. kay->orx_an = 0;
  1917. ieee802_1x_cp_connect_authenticated(kay->cp);
  1918. ieee802_1x_cp_sm_step(kay->cp);
  1919. }
  1920. return 0;
  1921. }
  1922. static const u8 pae_group_addr[ETH_ALEN] = {
  1923. 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03
  1924. };
  1925. /**
  1926. * ieee802_1x_kay_encode_mkpdu -
  1927. */
  1928. static int
  1929. ieee802_1x_kay_encode_mkpdu(struct ieee802_1x_mka_participant *participant,
  1930. struct wpabuf *pbuf)
  1931. {
  1932. unsigned int i;
  1933. struct ieee8023_hdr *ether_hdr;
  1934. struct ieee802_1x_hdr *eapol_hdr;
  1935. ether_hdr = wpabuf_put(pbuf, sizeof(*ether_hdr));
  1936. os_memcpy(ether_hdr->dest, pae_group_addr, sizeof(ether_hdr->dest));
  1937. os_memcpy(ether_hdr->src, participant->kay->actor_sci.addr,
  1938. sizeof(ether_hdr->dest));
  1939. ether_hdr->ethertype = host_to_be16(ETH_P_EAPOL);
  1940. eapol_hdr = wpabuf_put(pbuf, sizeof(*eapol_hdr));
  1941. eapol_hdr->version = EAPOL_VERSION;
  1942. eapol_hdr->type = IEEE802_1X_TYPE_EAPOL_MKA;
  1943. eapol_hdr->length = host_to_be16(pbuf->size - pbuf->used);
  1944. for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) {
  1945. if (mka_body_handler[i].body_present &&
  1946. mka_body_handler[i].body_present(participant)) {
  1947. if (mka_body_handler[i].body_tx(participant, pbuf))
  1948. return -1;
  1949. }
  1950. }
  1951. return 0;
  1952. }
  1953. /**
  1954. * ieee802_1x_participant_send_mkpdu -
  1955. */
  1956. static int
  1957. ieee802_1x_participant_send_mkpdu(
  1958. struct ieee802_1x_mka_participant *participant)
  1959. {
  1960. struct wpabuf *buf;
  1961. struct ieee802_1x_kay *kay = participant->kay;
  1962. size_t length = 0;
  1963. unsigned int i;
  1964. wpa_printf(MSG_DEBUG, "KaY: to enpacket and send the MKPDU");
  1965. length += sizeof(struct ieee802_1x_hdr) + sizeof(struct ieee8023_hdr);
  1966. for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) {
  1967. if (mka_body_handler[i].body_present &&
  1968. mka_body_handler[i].body_present(participant))
  1969. length += mka_body_handler[i].body_length(participant);
  1970. }
  1971. buf = wpabuf_alloc(length);
  1972. if (!buf) {
  1973. wpa_printf(MSG_ERROR, "KaY: out of memory");
  1974. return -1;
  1975. }
  1976. if (ieee802_1x_kay_encode_mkpdu(participant, buf)) {
  1977. wpa_printf(MSG_ERROR, "KaY: encode mkpdu fail!");
  1978. return -1;
  1979. }
  1980. l2_packet_send(kay->l2_mka, NULL, 0, wpabuf_head(buf), wpabuf_len(buf));
  1981. wpabuf_free(buf);
  1982. kay->active = TRUE;
  1983. participant->active = TRUE;
  1984. return 0;
  1985. }
  1986. static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa);
  1987. /**
  1988. * ieee802_1x_participant_timer -
  1989. */
  1990. static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
  1991. {
  1992. struct ieee802_1x_mka_participant *participant;
  1993. struct ieee802_1x_kay *kay;
  1994. struct ieee802_1x_kay_peer *peer, *pre_peer;
  1995. time_t now = time(NULL);
  1996. Boolean lp_changed;
  1997. struct receive_sc *rxsc, *pre_rxsc;
  1998. struct transmit_sa *txsa, *pre_txsa;
  1999. participant = (struct ieee802_1x_mka_participant *)eloop_ctx;
  2000. kay = participant->kay;
  2001. if (participant->cak_life) {
  2002. if (now > participant->cak_life) {
  2003. kay->authenticated = FALSE;
  2004. kay->secured = FALSE;
  2005. kay->failed = TRUE;
  2006. ieee802_1x_kay_delete_mka(kay, &participant->ckn);
  2007. return;
  2008. }
  2009. }
  2010. /* should delete MKA instance if there are not live peers
  2011. * when the MKA life elapsed since its creating */
  2012. if (participant->mka_life) {
  2013. if (dl_list_empty(&participant->live_peers)) {
  2014. if (now > participant->mka_life) {
  2015. kay->authenticated = FALSE;
  2016. kay->secured = FALSE;
  2017. kay->failed = TRUE;
  2018. ieee802_1x_kay_delete_mka(kay,
  2019. &participant->ckn);
  2020. return;
  2021. }
  2022. } else {
  2023. participant->mka_life = 0;
  2024. }
  2025. }
  2026. lp_changed = FALSE;
  2027. dl_list_for_each_safe(peer, pre_peer, &participant->live_peers,
  2028. struct ieee802_1x_kay_peer, list) {
  2029. if (now > peer->expire) {
  2030. wpa_printf(MSG_DEBUG, "KaY: Live peer removed");
  2031. wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi,
  2032. sizeof(peer->mi));
  2033. wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
  2034. dl_list_for_each_safe(rxsc, pre_rxsc,
  2035. &participant->rxsc_list,
  2036. struct receive_sc, list) {
  2037. if (sci_equal(&rxsc->sci, &peer->sci)) {
  2038. secy_delete_receive_sc(kay, rxsc);
  2039. ieee802_1x_kay_deinit_receive_sc(
  2040. participant, rxsc);
  2041. }
  2042. }
  2043. dl_list_del(&peer->list);
  2044. os_free(peer);
  2045. lp_changed = TRUE;
  2046. }
  2047. }
  2048. if (lp_changed) {
  2049. if (dl_list_empty(&participant->live_peers)) {
  2050. participant->advised_desired = FALSE;
  2051. participant->advised_capability =
  2052. MACSEC_CAP_NOT_IMPLEMENTED;
  2053. participant->to_use_sak = FALSE;
  2054. kay->authenticated = TRUE;
  2055. kay->secured = FALSE;
  2056. kay->failed = FALSE;
  2057. kay->ltx_kn = 0;
  2058. kay->ltx_an = 0;
  2059. kay->lrx_kn = 0;
  2060. kay->lrx_an = 0;
  2061. kay->otx_kn = 0;
  2062. kay->otx_an = 0;
  2063. kay->orx_kn = 0;
  2064. kay->orx_an = 0;
  2065. dl_list_for_each_safe(txsa, pre_txsa,
  2066. &participant->txsc->sa_list,
  2067. struct transmit_sa, list) {
  2068. secy_disable_transmit_sa(kay, txsa);
  2069. ieee802_1x_kay_deinit_transmit_sa(txsa);
  2070. }
  2071. ieee802_1x_cp_connect_authenticated(kay->cp);
  2072. ieee802_1x_cp_sm_step(kay->cp);
  2073. } else {
  2074. ieee802_1x_kay_elect_key_server(participant);
  2075. ieee802_1x_kay_decide_macsec_use(participant);
  2076. }
  2077. }
  2078. dl_list_for_each_safe(peer, pre_peer, &participant->potential_peers,
  2079. struct ieee802_1x_kay_peer, list) {
  2080. if (now > peer->expire) {
  2081. wpa_printf(MSG_DEBUG, "KaY: Potential peer removed");
  2082. wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi,
  2083. sizeof(peer->mi));
  2084. wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
  2085. dl_list_del(&peer->list);
  2086. os_free(peer);
  2087. }
  2088. }
  2089. if (participant->new_sak) {
  2090. if (!ieee802_1x_kay_generate_new_sak(participant))
  2091. participant->to_dist_sak = TRUE;
  2092. participant->new_sak = FALSE;
  2093. }
  2094. if (participant->retry_count < MAX_RETRY_CNT) {
  2095. ieee802_1x_participant_send_mkpdu(participant);
  2096. participant->retry_count++;
  2097. }
  2098. eloop_register_timeout(MKA_HELLO_TIME / 1000, 0,
  2099. ieee802_1x_participant_timer,
  2100. participant, NULL);
  2101. }
  2102. /**
  2103. * ieee802_1x_kay_init_transmit_sa -
  2104. */
  2105. static struct transmit_sa *
  2106. ieee802_1x_kay_init_transmit_sa(struct transmit_sc *psc, u8 an, u32 next_PN,
  2107. struct data_key *key)
  2108. {
  2109. struct transmit_sa *psa;
  2110. key->tx_latest = TRUE;
  2111. key->rx_latest = TRUE;
  2112. psa = os_zalloc(sizeof(*psa));
  2113. if (!psa) {
  2114. wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
  2115. return NULL;
  2116. }
  2117. if (key->confidentiality_offset >= CONFIDENTIALITY_OFFSET_0 &&
  2118. key->confidentiality_offset <= CONFIDENTIALITY_OFFSET_50)
  2119. psa->confidentiality = TRUE;
  2120. else
  2121. psa->confidentiality = FALSE;
  2122. psa->an = an;
  2123. psa->pkey = key;
  2124. psa->next_pn = next_PN;
  2125. psa->sc = psc;
  2126. os_get_time(&psa->created_time);
  2127. psa->in_use = FALSE;
  2128. dl_list_add(&psc->sa_list, &psa->list);
  2129. wpa_printf(MSG_DEBUG,
  2130. "KaY: Create transmit SA(an: %d, next_PN: %u) of SC(channel: %d)",
  2131. (int) an, next_PN, psc->channel);
  2132. return psa;
  2133. }
  2134. /**
  2135. * ieee802_1x_kay_deinit_transmit_sa -
  2136. */
  2137. static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa)
  2138. {
  2139. psa->pkey = NULL;
  2140. wpa_printf(MSG_DEBUG,
  2141. "KaY: Delete transmit SA(an: %d) of SC(channel: %d)",
  2142. psa->an, psa->sc->channel);
  2143. dl_list_del(&psa->list);
  2144. os_free(psa);
  2145. }
  2146. /**
  2147. * init_transmit_sc -
  2148. */
  2149. static struct transmit_sc *
  2150. ieee802_1x_kay_init_transmit_sc(const struct ieee802_1x_mka_sci *sci,
  2151. int channel)
  2152. {
  2153. struct transmit_sc *psc;
  2154. psc = os_zalloc(sizeof(*psc));
  2155. if (!psc) {
  2156. wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
  2157. return NULL;
  2158. }
  2159. os_memcpy(&psc->sci, sci, sizeof(psc->sci));
  2160. psc->channel = channel;
  2161. os_get_time(&psc->created_time);
  2162. psc->transmitting = FALSE;
  2163. psc->encoding_sa = FALSE;
  2164. psc->enciphering_sa = FALSE;
  2165. dl_list_init(&psc->sa_list);
  2166. wpa_printf(MSG_DEBUG, "KaY: Create transmit SC(channel: %d)", channel);
  2167. wpa_hexdump(MSG_DEBUG, "SCI: ", (u8 *)sci , sizeof(*sci));
  2168. return psc;
  2169. }
  2170. /**
  2171. * ieee802_1x_kay_deinit_transmit_sc -
  2172. */
  2173. static void
  2174. ieee802_1x_kay_deinit_transmit_sc(
  2175. struct ieee802_1x_mka_participant *participant, struct transmit_sc *psc)
  2176. {
  2177. struct transmit_sa *psa, *tmp;
  2178. wpa_printf(MSG_DEBUG, "KaY: Delete transmit SC(channel: %d)",
  2179. psc->channel);
  2180. dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa,
  2181. list) {
  2182. secy_disable_transmit_sa(participant->kay, psa);
  2183. ieee802_1x_kay_deinit_transmit_sa(psa);
  2184. }
  2185. os_free(psc);
  2186. }
  2187. /****************** Interface between CP and KAY *********************/
  2188. /**
  2189. * ieee802_1x_kay_set_latest_sa_attr -
  2190. */
  2191. int ieee802_1x_kay_set_latest_sa_attr(struct ieee802_1x_kay *kay,
  2192. struct ieee802_1x_mka_ki *lki, u8 lan,
  2193. Boolean ltx, Boolean lrx)
  2194. {
  2195. struct ieee802_1x_mka_participant *principal;
  2196. principal = ieee802_1x_kay_get_principal_participant(kay);
  2197. if (!principal)
  2198. return -1;
  2199. if (!lki)
  2200. os_memset(&principal->lki, 0, sizeof(principal->lki));
  2201. else
  2202. os_memcpy(&principal->lki, lki, sizeof(principal->lki));
  2203. principal->lan = lan;
  2204. principal->ltx = ltx;
  2205. principal->lrx = lrx;
  2206. if (!lki) {
  2207. kay->ltx_kn = 0;
  2208. kay->lrx_kn = 0;
  2209. } else {
  2210. kay->ltx_kn = lki->kn;
  2211. kay->lrx_kn = lki->kn;
  2212. }
  2213. kay->ltx_an = lan;
  2214. kay->lrx_an = lan;
  2215. return 0;
  2216. }
  2217. /**
  2218. * ieee802_1x_kay_set_old_sa_attr -
  2219. */
  2220. int ieee802_1x_kay_set_old_sa_attr(struct ieee802_1x_kay *kay,
  2221. struct ieee802_1x_mka_ki *oki,
  2222. u8 oan, Boolean otx, Boolean orx)
  2223. {
  2224. struct ieee802_1x_mka_participant *principal;
  2225. principal = ieee802_1x_kay_get_principal_participant(kay);
  2226. if (!principal)
  2227. return -1;
  2228. if (!oki)
  2229. os_memset(&principal->oki, 0, sizeof(principal->oki));
  2230. else
  2231. os_memcpy(&principal->oki, oki, sizeof(principal->oki));
  2232. principal->oan = oan;
  2233. principal->otx = otx;
  2234. principal->orx = orx;
  2235. if (!oki) {
  2236. kay->otx_kn = 0;
  2237. kay->orx_kn = 0;
  2238. } else {
  2239. kay->otx_kn = oki->kn;
  2240. kay->orx_kn = oki->kn;
  2241. }
  2242. kay->otx_an = oan;
  2243. kay->orx_an = oan;
  2244. return 0;
  2245. }
  2246. /**
  2247. * ieee802_1x_kay_create_sas -
  2248. */
  2249. int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay,
  2250. struct ieee802_1x_mka_ki *lki)
  2251. {
  2252. struct data_key *sa_key, *latest_sak;
  2253. struct ieee802_1x_mka_participant *principal;
  2254. struct receive_sc *rxsc;
  2255. struct receive_sa *rxsa;
  2256. struct transmit_sa *txsa;
  2257. principal = ieee802_1x_kay_get_principal_participant(kay);
  2258. if (!principal)
  2259. return -1;
  2260. latest_sak = NULL;
  2261. dl_list_for_each(sa_key, &principal->sak_list, struct data_key, list) {
  2262. if (is_ki_equal(&sa_key->key_identifier, lki)) {
  2263. sa_key->rx_latest = TRUE;
  2264. sa_key->tx_latest = TRUE;
  2265. latest_sak = sa_key;
  2266. principal->to_use_sak = TRUE;
  2267. } else {
  2268. sa_key->rx_latest = FALSE;
  2269. sa_key->tx_latest = FALSE;
  2270. }
  2271. }
  2272. if (!latest_sak) {
  2273. wpa_printf(MSG_ERROR, "lki related sak not found");
  2274. return -1;
  2275. }
  2276. dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) {
  2277. rxsa = ieee802_1x_kay_init_receive_sa(rxsc, latest_sak->an, 1,
  2278. latest_sak);
  2279. if (!rxsa)
  2280. return -1;
  2281. secy_create_receive_sa(kay, rxsa);
  2282. }
  2283. txsa = ieee802_1x_kay_init_transmit_sa(principal->txsc, latest_sak->an,
  2284. 1, latest_sak);
  2285. if (!txsa)
  2286. return -1;
  2287. secy_create_transmit_sa(kay, txsa);
  2288. return 0;
  2289. }
  2290. /**
  2291. * ieee802_1x_kay_delete_sas -
  2292. */
  2293. int ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay,
  2294. struct ieee802_1x_mka_ki *ki)
  2295. {
  2296. struct data_key *sa_key, *pre_key;
  2297. struct transmit_sa *txsa, *pre_txsa;
  2298. struct receive_sa *rxsa, *pre_rxsa;
  2299. struct receive_sc *rxsc;
  2300. struct ieee802_1x_mka_participant *principal;
  2301. wpa_printf(MSG_DEBUG, "KaY: Entry into %s", __func__);
  2302. principal = ieee802_1x_kay_get_principal_participant(kay);
  2303. if (!principal)
  2304. return -1;
  2305. /* remove the transmit sa */
  2306. dl_list_for_each_safe(txsa, pre_txsa, &principal->txsc->sa_list,
  2307. struct transmit_sa, list) {
  2308. if (is_ki_equal(&txsa->pkey->key_identifier, ki)) {
  2309. secy_disable_transmit_sa(kay, txsa);
  2310. ieee802_1x_kay_deinit_transmit_sa(txsa);
  2311. }
  2312. }
  2313. /* remove the receive sa */
  2314. dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) {
  2315. dl_list_for_each_safe(rxsa, pre_rxsa, &rxsc->sa_list,
  2316. struct receive_sa, list) {
  2317. if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) {
  2318. secy_disable_receive_sa(kay, rxsa);
  2319. ieee802_1x_kay_deinit_receive_sa(rxsa);
  2320. }
  2321. }
  2322. }
  2323. /* remove the sak */
  2324. dl_list_for_each_safe(sa_key, pre_key, &principal->sak_list,
  2325. struct data_key, list) {
  2326. if (is_ki_equal(&sa_key->key_identifier, ki)) {
  2327. ieee802_1x_kay_deinit_data_key(sa_key);
  2328. break;
  2329. }
  2330. if (principal->new_key == sa_key)
  2331. principal->new_key = NULL;
  2332. }
  2333. return 0;
  2334. }
  2335. /**
  2336. * ieee802_1x_kay_enable_tx_sas -
  2337. */
  2338. int ieee802_1x_kay_enable_tx_sas(struct ieee802_1x_kay *kay,
  2339. struct ieee802_1x_mka_ki *lki)
  2340. {
  2341. struct ieee802_1x_mka_participant *principal;
  2342. struct transmit_sa *txsa;
  2343. principal = ieee802_1x_kay_get_principal_participant(kay);
  2344. if (!principal)
  2345. return -1;
  2346. dl_list_for_each(txsa, &principal->txsc->sa_list, struct transmit_sa,
  2347. list) {
  2348. if (is_ki_equal(&txsa->pkey->key_identifier, lki)) {
  2349. txsa->in_use = TRUE;
  2350. secy_enable_transmit_sa(kay, txsa);
  2351. ieee802_1x_cp_set_usingtransmitas(
  2352. principal->kay->cp, TRUE);
  2353. ieee802_1x_cp_sm_step(principal->kay->cp);
  2354. }
  2355. }
  2356. return 0;
  2357. }
  2358. /**
  2359. * ieee802_1x_kay_enable_rx_sas -
  2360. */
  2361. int ieee802_1x_kay_enable_rx_sas(struct ieee802_1x_kay *kay,
  2362. struct ieee802_1x_mka_ki *lki)
  2363. {
  2364. struct ieee802_1x_mka_participant *principal;
  2365. struct receive_sa *rxsa;
  2366. struct receive_sc *rxsc;
  2367. principal = ieee802_1x_kay_get_principal_participant(kay);
  2368. if (!principal)
  2369. return -1;
  2370. dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) {
  2371. dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list)
  2372. {
  2373. if (is_ki_equal(&rxsa->pkey->key_identifier, lki)) {
  2374. rxsa->in_use = TRUE;
  2375. secy_enable_receive_sa(kay, rxsa);
  2376. ieee802_1x_cp_set_usingreceivesas(
  2377. principal->kay->cp, TRUE);
  2378. ieee802_1x_cp_sm_step(principal->kay->cp);
  2379. }
  2380. }
  2381. }
  2382. return 0;
  2383. }
  2384. /**
  2385. * ieee802_1x_kay_enable_new_info -
  2386. */
  2387. int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay)
  2388. {
  2389. struct ieee802_1x_mka_participant *principal;
  2390. principal = ieee802_1x_kay_get_principal_participant(kay);
  2391. if (!principal)
  2392. return -1;
  2393. if (principal->retry_count < MAX_RETRY_CNT) {
  2394. ieee802_1x_participant_send_mkpdu(principal);
  2395. principal->retry_count++;
  2396. }
  2397. return 0;
  2398. }
  2399. /**
  2400. * ieee802_1x_kay_cp_conf -
  2401. */
  2402. int ieee802_1x_kay_cp_conf(struct ieee802_1x_kay *kay,
  2403. struct ieee802_1x_cp_conf *pconf)
  2404. {
  2405. pconf->protect = kay->macsec_protect;
  2406. pconf->replay_protect = kay->macsec_replay_protect;
  2407. pconf->validate = kay->macsec_validate;
  2408. return 0;
  2409. }
  2410. /**
  2411. * ieee802_1x_kay_alloc_cp_sm -
  2412. */
  2413. static struct ieee802_1x_cp_sm *
  2414. ieee802_1x_kay_alloc_cp_sm(struct ieee802_1x_kay *kay)
  2415. {
  2416. struct ieee802_1x_cp_conf conf;
  2417. os_memset(&conf, 0, sizeof(conf));
  2418. conf.protect = kay->macsec_protect;
  2419. conf.replay_protect = kay->macsec_replay_protect;
  2420. conf.validate = kay->macsec_validate;
  2421. conf.replay_window = kay->macsec_replay_window;
  2422. return ieee802_1x_cp_sm_init(kay, &conf);
  2423. }
  2424. /**
  2425. * ieee802_1x_kay_mkpdu_sanity_check -
  2426. * sanity check specified in clause 11.11.2 of IEEE802.1X-2010
  2427. */
  2428. static int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay,
  2429. const u8 *buf, size_t len)
  2430. {
  2431. struct ieee8023_hdr *eth_hdr;
  2432. struct ieee802_1x_hdr *eapol_hdr;
  2433. struct ieee802_1x_mka_hdr *mka_hdr;
  2434. struct ieee802_1x_mka_basic_body *body;
  2435. size_t mka_msg_len;
  2436. struct ieee802_1x_mka_participant *participant;
  2437. size_t body_len;
  2438. u8 icv[MAX_ICV_LEN];
  2439. u8 *msg_icv;
  2440. eth_hdr = (struct ieee8023_hdr *) buf;
  2441. eapol_hdr = (struct ieee802_1x_hdr *) (eth_hdr + 1);
  2442. mka_hdr = (struct ieee802_1x_mka_hdr *) (eapol_hdr + 1);
  2443. /* destination address should be not individual address */
  2444. if (os_memcmp(eth_hdr->dest, pae_group_addr, ETH_ALEN) != 0) {
  2445. wpa_printf(MSG_MSGDUMP,
  2446. "KaY: ethernet destination address is not PAE group address");
  2447. return -1;
  2448. }
  2449. /* MKPDU should not less than 32 octets */
  2450. mka_msg_len = be_to_host16(eapol_hdr->length);
  2451. if (mka_msg_len < 32) {
  2452. wpa_printf(MSG_MSGDUMP, "KaY: MKPDU is less than 32 octets");
  2453. return -1;
  2454. }
  2455. /* MKPDU should multiple 4 octets */
  2456. if ((mka_msg_len % 4) != 0) {
  2457. wpa_printf(MSG_MSGDUMP,
  2458. "KaY: MKPDU is not multiple of 4 octets");
  2459. return -1;
  2460. }
  2461. body = (struct ieee802_1x_mka_basic_body *) mka_hdr;
  2462. ieee802_1x_mka_dump_basic_body(body);
  2463. body_len = get_mka_param_body_len(body);
  2464. /* EAPOL-MKA body should comprise basic parameter set and ICV */
  2465. if (mka_msg_len < MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN) {
  2466. wpa_printf(MSG_ERROR,
  2467. "KaY: Received EAPOL-MKA Packet Body Length (%d bytes) is less than the Basic Parameter Set Header Length (%d bytes) + the Basic Parameter Set Body Length (%d bytes) + %d bytes of ICV",
  2468. (int) mka_msg_len, (int) MKA_HDR_LEN,
  2469. (int) body_len, DEFAULT_ICV_LEN);
  2470. return -1;
  2471. }
  2472. /* CKN should be owned by I */
  2473. participant = ieee802_1x_kay_get_participant(kay, body->ckn);
  2474. if (!participant) {
  2475. wpa_printf(MSG_DEBUG, "CKN is not included in my CA");
  2476. return -1;
  2477. }
  2478. /* algorithm agility check */
  2479. if (os_memcmp(body->algo_agility, mka_algo_agility,
  2480. sizeof(body->algo_agility)) != 0) {
  2481. wpa_printf(MSG_ERROR,
  2482. "KaY: peer's algorithm agility not supported for me");
  2483. return -1;
  2484. }
  2485. /* ICV check */
  2486. /*
  2487. * The ICV will comprise the final octets of the packet body, whatever
  2488. * its size, not the fixed length 16 octets, indicated by the EAPOL
  2489. * packet body length.
  2490. */
  2491. if (mka_alg_tbl[kay->mka_algindex].icv_hash(
  2492. participant->ick.key,
  2493. buf, len - mka_alg_tbl[kay->mka_algindex].icv_len, icv)) {
  2494. wpa_printf(MSG_ERROR, "KaY: omac1_aes_128 failed");
  2495. return -1;
  2496. }
  2497. msg_icv = ieee802_1x_mka_decode_icv_body(participant, (u8 *) mka_hdr,
  2498. mka_msg_len);
  2499. if (msg_icv) {
  2500. if (os_memcmp_const(msg_icv, icv,
  2501. mka_alg_tbl[kay->mka_algindex].icv_len) !=
  2502. 0) {
  2503. wpa_printf(MSG_ERROR,
  2504. "KaY: Computed ICV is not equal to Received ICV");
  2505. return -1;
  2506. }
  2507. } else {
  2508. wpa_printf(MSG_ERROR, "KaY: No ICV");
  2509. return -1;
  2510. }
  2511. return 0;
  2512. }
  2513. /**
  2514. * ieee802_1x_kay_decode_mkpdu -
  2515. */
  2516. static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
  2517. const u8 *buf, size_t len)
  2518. {
  2519. struct ieee802_1x_mka_participant *participant;
  2520. struct ieee802_1x_mka_hdr *hdr;
  2521. size_t body_len;
  2522. size_t left_len;
  2523. u8 body_type;
  2524. int i;
  2525. const u8 *pos;
  2526. Boolean my_included;
  2527. Boolean handled[256];
  2528. if (ieee802_1x_kay_mkpdu_sanity_check(kay, buf, len))
  2529. return -1;
  2530. /* handle basic parameter set */
  2531. pos = buf + sizeof(struct ieee8023_hdr) + sizeof(struct ieee802_1x_hdr);
  2532. left_len = len - sizeof(struct ieee8023_hdr) -
  2533. sizeof(struct ieee802_1x_hdr);
  2534. participant = ieee802_1x_mka_decode_basic_body(kay, pos, left_len);
  2535. if (!participant)
  2536. return -1;
  2537. /* to skip basic parameter set */
  2538. hdr = (struct ieee802_1x_mka_hdr *) pos;
  2539. body_len = get_mka_param_body_len(hdr);
  2540. pos += body_len + MKA_HDR_LEN;
  2541. left_len -= body_len + MKA_HDR_LEN;
  2542. /* check i am in the peer's peer list */
  2543. my_included = ieee802_1x_mka_i_in_peerlist(participant, pos, left_len);
  2544. if (my_included) {
  2545. /* accept the peer as live peer */
  2546. if (!ieee802_1x_kay_is_in_peer(
  2547. participant,
  2548. participant->current_peer_id.mi)) {
  2549. if (!ieee802_1x_kay_create_live_peer(
  2550. participant,
  2551. participant->current_peer_id.mi,
  2552. be_to_host32(
  2553. participant->current_peer_id.mn)))
  2554. return -1;
  2555. ieee802_1x_kay_elect_key_server(participant);
  2556. ieee802_1x_kay_decide_macsec_use(participant);
  2557. }
  2558. if (ieee802_1x_kay_is_in_potential_peer(
  2559. participant, participant->current_peer_id.mi)) {
  2560. if (!ieee802_1x_kay_move_live_peer(
  2561. participant,
  2562. participant->current_peer_id.mi,
  2563. be_to_host32(participant->
  2564. current_peer_id.mn)))
  2565. return -1;
  2566. ieee802_1x_kay_elect_key_server(participant);
  2567. ieee802_1x_kay_decide_macsec_use(participant);
  2568. }
  2569. }
  2570. /*
  2571. * Handle other parameter set than basic parameter set.
  2572. * Each parameter set should be present only once.
  2573. */
  2574. for (i = 0; i < 256; i++)
  2575. handled[i] = FALSE;
  2576. handled[0] = TRUE;
  2577. while (left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN) {
  2578. hdr = (struct ieee802_1x_mka_hdr *) pos;
  2579. body_len = get_mka_param_body_len(hdr);
  2580. body_type = get_mka_param_body_type(hdr);
  2581. if (body_type == MKA_ICV_INDICATOR)
  2582. return 0;
  2583. if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) {
  2584. wpa_printf(MSG_ERROR,
  2585. "KaY: MKA Peer Packet Body Length (%d bytes) is less than the Parameter Set Header Length (%d bytes) + the Parameter Set Body Length (%d bytes) + %d bytes of ICV",
  2586. (int) left_len, (int) MKA_HDR_LEN,
  2587. (int) body_len, DEFAULT_ICV_LEN);
  2588. goto next_para_set;
  2589. }
  2590. if (handled[body_type])
  2591. goto next_para_set;
  2592. handled[body_type] = TRUE;
  2593. if (body_type < ARRAY_SIZE(mka_body_handler) &&
  2594. mka_body_handler[body_type].body_rx) {
  2595. mka_body_handler[body_type].body_rx
  2596. (participant, pos, left_len);
  2597. } else {
  2598. wpa_printf(MSG_ERROR,
  2599. "The type %d not supported in this MKA version %d",
  2600. body_type, MKA_VERSION_ID);
  2601. }
  2602. next_para_set:
  2603. pos += body_len + MKA_HDR_LEN;
  2604. left_len -= body_len + MKA_HDR_LEN;
  2605. }
  2606. kay->active = TRUE;
  2607. participant->retry_count = 0;
  2608. participant->active = TRUE;
  2609. return 0;
  2610. }
  2611. static void kay_l2_receive(void *ctx, const u8 *src_addr, const u8 *buf,
  2612. size_t len)
  2613. {
  2614. struct ieee802_1x_kay *kay = ctx;
  2615. struct ieee8023_hdr *eth_hdr;
  2616. struct ieee802_1x_hdr *eapol_hdr;
  2617. /* must contain at least ieee8023_hdr + ieee802_1x_hdr */
  2618. if (len < sizeof(*eth_hdr) + sizeof(*eapol_hdr)) {
  2619. wpa_printf(MSG_MSGDUMP, "KaY: EAPOL frame too short (%lu)",
  2620. (unsigned long) len);
  2621. return;
  2622. }
  2623. eth_hdr = (struct ieee8023_hdr *) buf;
  2624. eapol_hdr = (struct ieee802_1x_hdr *) (eth_hdr + 1);
  2625. if (len != sizeof(*eth_hdr) + sizeof(*eapol_hdr) +
  2626. be_to_host16(eapol_hdr->length)) {
  2627. wpa_printf(MSG_MSGDUMP, "KAY: EAPOL MPDU is invalid: (%lu-%lu)",
  2628. (unsigned long) len,
  2629. (unsigned long) be_to_host16(eapol_hdr->length));
  2630. return;
  2631. }
  2632. if (eapol_hdr->version < EAPOL_VERSION) {
  2633. wpa_printf(MSG_MSGDUMP, "KaY: version %d does not support MKA",
  2634. eapol_hdr->version);
  2635. return;
  2636. }
  2637. if (be_to_host16(eth_hdr->ethertype) != ETH_P_PAE ||
  2638. eapol_hdr->type != IEEE802_1X_TYPE_EAPOL_MKA)
  2639. return;
  2640. wpa_hexdump(MSG_DEBUG, "RX EAPOL-MKA: ", buf, len);
  2641. if (dl_list_empty(&kay->participant_list)) {
  2642. wpa_printf(MSG_ERROR, "KaY: no MKA participant instance");
  2643. return;
  2644. }
  2645. ieee802_1x_kay_decode_mkpdu(kay, buf, len);
  2646. }
  2647. /**
  2648. * ieee802_1x_kay_init -
  2649. */
  2650. struct ieee802_1x_kay *
  2651. ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
  2652. const char *ifname, const u8 *addr)
  2653. {
  2654. struct ieee802_1x_kay *kay;
  2655. kay = os_zalloc(sizeof(*kay));
  2656. if (!kay) {
  2657. wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
  2658. return NULL;
  2659. }
  2660. kay->ctx = ctx;
  2661. kay->enable = TRUE;
  2662. kay->active = FALSE;
  2663. kay->authenticated = FALSE;
  2664. kay->secured = FALSE;
  2665. kay->failed = FALSE;
  2666. kay->policy = policy;
  2667. os_strlcpy(kay->if_name, ifname, IFNAMSIZ);
  2668. os_memcpy(kay->actor_sci.addr, addr, ETH_ALEN);
  2669. kay->actor_sci.port = host_to_be16(0x0001);
  2670. kay->actor_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
  2671. /* While actor acts as a key server, shall distribute sakey */
  2672. kay->dist_kn = 1;
  2673. kay->dist_an = 0;
  2674. kay->dist_time = 0;
  2675. kay->pn_exhaustion = PENDING_PN_EXHAUSTION;
  2676. kay->macsec_csindex = DEFAULT_CS_INDEX;
  2677. kay->mka_algindex = DEFAULT_MKA_ALG_INDEX;
  2678. kay->mka_version = MKA_VERSION_ID;
  2679. os_memcpy(kay->algo_agility, mka_algo_agility,
  2680. sizeof(kay->algo_agility));
  2681. dl_list_init(&kay->participant_list);
  2682. if (policy == DO_NOT_SECURE) {
  2683. kay->macsec_capable = MACSEC_CAP_NOT_IMPLEMENTED;
  2684. kay->macsec_desired = FALSE;
  2685. kay->macsec_protect = FALSE;
  2686. kay->macsec_validate = Disabled;
  2687. kay->macsec_replay_protect = FALSE;
  2688. kay->macsec_replay_window = 0;
  2689. kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
  2690. } else {
  2691. kay->macsec_capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50;
  2692. kay->macsec_desired = TRUE;
  2693. kay->macsec_protect = TRUE;
  2694. kay->macsec_validate = Strict;
  2695. kay->macsec_replay_protect = FALSE;
  2696. kay->macsec_replay_window = 0;
  2697. kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
  2698. }
  2699. wpa_printf(MSG_DEBUG, "KaY: state machine created");
  2700. /* Initialize the SecY must be prio to CP, as CP will control SecY */
  2701. secy_init_macsec(kay);
  2702. secy_get_available_transmit_sc(kay, &kay->sc_ch);
  2703. wpa_printf(MSG_DEBUG, "KaY: secy init macsec done");
  2704. /* init CP */
  2705. kay->cp = ieee802_1x_kay_alloc_cp_sm(kay);
  2706. if (kay->cp == NULL) {
  2707. ieee802_1x_kay_deinit(kay);
  2708. return NULL;
  2709. }
  2710. if (policy == DO_NOT_SECURE) {
  2711. ieee802_1x_cp_connect_authenticated(kay->cp);
  2712. ieee802_1x_cp_sm_step(kay->cp);
  2713. } else {
  2714. kay->l2_mka = l2_packet_init(kay->if_name, NULL, ETH_P_PAE,
  2715. kay_l2_receive, kay, 1);
  2716. if (kay->l2_mka == NULL) {
  2717. wpa_printf(MSG_WARNING,
  2718. "KaY: Failed to initialize L2 packet processing for MKA packet");
  2719. ieee802_1x_kay_deinit(kay);
  2720. return NULL;
  2721. }
  2722. }
  2723. return kay;
  2724. }
  2725. /**
  2726. * ieee802_1x_kay_deinit -
  2727. */
  2728. void
  2729. ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay)
  2730. {
  2731. struct ieee802_1x_mka_participant *participant;
  2732. if (!kay)
  2733. return;
  2734. wpa_printf(MSG_DEBUG, "KaY: state machine removed");
  2735. while (!dl_list_empty(&kay->participant_list)) {
  2736. participant = dl_list_entry(kay->participant_list.next,
  2737. struct ieee802_1x_mka_participant,
  2738. list);
  2739. ieee802_1x_kay_delete_mka(kay, &participant->ckn);
  2740. }
  2741. ieee802_1x_cp_sm_deinit(kay->cp);
  2742. secy_deinit_macsec(kay);
  2743. if (kay->l2_mka) {
  2744. l2_packet_deinit(kay->l2_mka);
  2745. kay->l2_mka = NULL;
  2746. }
  2747. os_free(kay->ctx);
  2748. os_free(kay);
  2749. }
  2750. /**
  2751. * ieee802_1x_kay_create_mka -
  2752. */
  2753. struct ieee802_1x_mka_participant *
  2754. ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn,
  2755. struct mka_key *cak, u32 life,
  2756. enum mka_created_mode mode, Boolean is_authenticator)
  2757. {
  2758. struct ieee802_1x_mka_participant *participant;
  2759. unsigned int usecs;
  2760. if (!kay || !ckn || !cak) {
  2761. wpa_printf(MSG_ERROR, "KaY: ckn or cak is null");
  2762. return NULL;
  2763. }
  2764. if (cak->len != mka_alg_tbl[kay->mka_algindex].cak_len) {
  2765. wpa_printf(MSG_ERROR, "KaY: CAK length not follow key schema");
  2766. return NULL;
  2767. }
  2768. if (ckn->len > MAX_CKN_LEN) {
  2769. wpa_printf(MSG_ERROR, "KaY: CKN is out of range(<=32 bytes)");
  2770. return NULL;
  2771. }
  2772. if (!kay->enable) {
  2773. wpa_printf(MSG_ERROR, "KaY: Now is at disable state");
  2774. return NULL;
  2775. }
  2776. participant = os_zalloc(sizeof(*participant));
  2777. if (!participant) {
  2778. wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
  2779. return NULL;
  2780. }
  2781. participant->ckn.len = ckn->len;
  2782. os_memcpy(participant->ckn.name, ckn->name, ckn->len);
  2783. participant->cak.len = cak->len;
  2784. os_memcpy(participant->cak.key, cak->key, cak->len);
  2785. if (life)
  2786. participant->cak_life = life + time(NULL);
  2787. switch (mode) {
  2788. case EAP_EXCHANGE:
  2789. if (is_authenticator) {
  2790. participant->is_obliged_key_server = TRUE;
  2791. participant->can_be_key_server = TRUE;
  2792. participant->is_key_server = TRUE;
  2793. participant->principal = TRUE;
  2794. os_memcpy(&kay->key_server_sci, &kay->actor_sci,
  2795. sizeof(kay->key_server_sci));
  2796. kay->key_server_priority = kay->actor_priority;
  2797. participant->is_elected = TRUE;
  2798. } else {
  2799. participant->is_obliged_key_server = FALSE;
  2800. participant->can_be_key_server = FALSE;
  2801. participant->is_key_server = FALSE;
  2802. participant->is_elected = TRUE;
  2803. }
  2804. break;
  2805. default:
  2806. participant->is_obliged_key_server = FALSE;
  2807. participant->can_be_key_server = TRUE;
  2808. participant->is_key_server = TRUE;
  2809. participant->is_elected = FALSE;
  2810. break;
  2811. }
  2812. participant->cached = FALSE;
  2813. participant->active = FALSE;
  2814. participant->participant = FALSE;
  2815. participant->retain = FALSE;
  2816. participant->activate = DEFAULT;
  2817. if (participant->is_key_server)
  2818. participant->principal = TRUE;
  2819. dl_list_init(&participant->live_peers);
  2820. dl_list_init(&participant->potential_peers);
  2821. participant->retry_count = 0;
  2822. participant->kay = kay;
  2823. if (os_get_random(participant->mi, sizeof(participant->mi)) < 0)
  2824. goto fail;
  2825. participant->mn = 0;
  2826. participant->lrx = FALSE;
  2827. participant->ltx = FALSE;
  2828. participant->orx = FALSE;
  2829. participant->otx = FALSE;
  2830. participant->to_dist_sak = FALSE;
  2831. participant->to_use_sak = FALSE;
  2832. participant->new_sak = FALSE;
  2833. dl_list_init(&participant->sak_list);
  2834. participant->new_key = NULL;
  2835. dl_list_init(&participant->rxsc_list);
  2836. participant->txsc = ieee802_1x_kay_init_transmit_sc(&kay->actor_sci,
  2837. kay->sc_ch);
  2838. secy_cp_control_protect_frames(kay, kay->macsec_protect);
  2839. secy_cp_control_replay(kay, kay->macsec_replay_protect,
  2840. kay->macsec_replay_window);
  2841. secy_create_transmit_sc(kay, participant->txsc);
  2842. /* to derive KEK from CAK and CKN */
  2843. participant->kek.len = mka_alg_tbl[kay->mka_algindex].kek_len;
  2844. if (mka_alg_tbl[kay->mka_algindex].kek_trfm(participant->cak.key,
  2845. participant->ckn.name,
  2846. participant->ckn.len,
  2847. participant->kek.key)) {
  2848. wpa_printf(MSG_ERROR, "KaY: Derived KEK failed");
  2849. goto fail;
  2850. }
  2851. wpa_hexdump_key(MSG_DEBUG, "KaY: Derived KEK",
  2852. participant->kek.key, participant->kek.len);
  2853. /* to derive ICK from CAK and CKN */
  2854. participant->ick.len = mka_alg_tbl[kay->mka_algindex].ick_len;
  2855. if (mka_alg_tbl[kay->mka_algindex].ick_trfm(participant->cak.key,
  2856. participant->ckn.name,
  2857. participant->ckn.len,
  2858. participant->ick.key)) {
  2859. wpa_printf(MSG_ERROR, "KaY: Derived ICK failed");
  2860. goto fail;
  2861. }
  2862. wpa_hexdump_key(MSG_DEBUG, "KaY: Derived ICK",
  2863. participant->ick.key, participant->ick.len);
  2864. dl_list_add(&kay->participant_list, &participant->list);
  2865. wpa_hexdump(MSG_DEBUG, "KaY: Participant created:",
  2866. ckn->name, ckn->len);
  2867. usecs = os_random() % (MKA_HELLO_TIME * 1000);
  2868. eloop_register_timeout(0, usecs, ieee802_1x_participant_timer,
  2869. participant, NULL);
  2870. participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) +
  2871. usecs / 1000000;
  2872. return participant;
  2873. fail:
  2874. os_free(participant);
  2875. return NULL;
  2876. }
  2877. /**
  2878. * ieee802_1x_kay_delete_mka -
  2879. */
  2880. void
  2881. ieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn)
  2882. {
  2883. struct ieee802_1x_mka_participant *participant;
  2884. struct ieee802_1x_kay_peer *peer;
  2885. struct data_key *sak;
  2886. struct receive_sc *rxsc;
  2887. if (!kay || !ckn)
  2888. return;
  2889. wpa_printf(MSG_DEBUG, "KaY: participant removed");
  2890. /* get the participant */
  2891. participant = ieee802_1x_kay_get_participant(kay, ckn->name);
  2892. if (!participant) {
  2893. wpa_hexdump(MSG_DEBUG, "KaY: participant is not found",
  2894. ckn->name, ckn->len);
  2895. return;
  2896. }
  2897. eloop_cancel_timeout(ieee802_1x_participant_timer, participant, NULL);
  2898. dl_list_del(&participant->list);
  2899. /* remove live peer */
  2900. while (!dl_list_empty(&participant->live_peers)) {
  2901. peer = dl_list_entry(participant->live_peers.next,
  2902. struct ieee802_1x_kay_peer, list);
  2903. dl_list_del(&peer->list);
  2904. os_free(peer);
  2905. }
  2906. /* remove potential peer */
  2907. while (!dl_list_empty(&participant->potential_peers)) {
  2908. peer = dl_list_entry(participant->potential_peers.next,
  2909. struct ieee802_1x_kay_peer, list);
  2910. dl_list_del(&peer->list);
  2911. os_free(peer);
  2912. }
  2913. /* remove sak */
  2914. while (!dl_list_empty(&participant->sak_list)) {
  2915. sak = dl_list_entry(participant->sak_list.next,
  2916. struct data_key, list);
  2917. dl_list_del(&sak->list);
  2918. os_free(sak->key);
  2919. os_free(sak);
  2920. }
  2921. while (!dl_list_empty(&participant->rxsc_list)) {
  2922. rxsc = dl_list_entry(participant->rxsc_list.next,
  2923. struct receive_sc, list);
  2924. secy_delete_receive_sc(kay, rxsc);
  2925. ieee802_1x_kay_deinit_receive_sc(participant, rxsc);
  2926. }
  2927. secy_delete_transmit_sc(kay, participant->txsc);
  2928. ieee802_1x_kay_deinit_transmit_sc(participant, participant->txsc);
  2929. os_memset(&participant->cak, 0, sizeof(participant->cak));
  2930. os_memset(&participant->kek, 0, sizeof(participant->kek));
  2931. os_memset(&participant->ick, 0, sizeof(participant->ick));
  2932. os_free(participant);
  2933. }
  2934. /**
  2935. * ieee802_1x_kay_mka_participate -
  2936. */
  2937. void ieee802_1x_kay_mka_participate(struct ieee802_1x_kay *kay,
  2938. struct mka_key_name *ckn,
  2939. Boolean status)
  2940. {
  2941. struct ieee802_1x_mka_participant *participant;
  2942. if (!kay || !ckn)
  2943. return;
  2944. participant = ieee802_1x_kay_get_participant(kay, ckn->name);
  2945. if (!participant)
  2946. return;
  2947. participant->active = status;
  2948. }
  2949. /**
  2950. * ieee802_1x_kay_new_sak -
  2951. */
  2952. int
  2953. ieee802_1x_kay_new_sak(struct ieee802_1x_kay *kay)
  2954. {
  2955. struct ieee802_1x_mka_participant *participant;
  2956. if (!kay)
  2957. return -1;
  2958. participant = ieee802_1x_kay_get_principal_participant(kay);
  2959. if (!participant)
  2960. return -1;
  2961. participant->new_sak = TRUE;
  2962. wpa_printf(MSG_DEBUG, "KaY: new SAK signal");
  2963. return 0;
  2964. }
  2965. /**
  2966. * ieee802_1x_kay_change_cipher_suite -
  2967. */
  2968. int
  2969. ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay, int cs_index)
  2970. {
  2971. struct ieee802_1x_mka_participant *participant;
  2972. if (!kay)
  2973. return -1;
  2974. if ((unsigned int) cs_index >= CS_TABLE_SIZE) {
  2975. wpa_printf(MSG_ERROR,
  2976. "KaY: Configured cipher suite index is out of range");
  2977. return -1;
  2978. }
  2979. if (kay->macsec_csindex == cs_index)
  2980. return -2;
  2981. if (cs_index == 0)
  2982. kay->macsec_desired = FALSE;
  2983. kay->macsec_csindex = cs_index;
  2984. kay->macsec_capable = cipher_suite_tbl[kay->macsec_csindex].capable;
  2985. participant = ieee802_1x_kay_get_principal_participant(kay);
  2986. if (participant) {
  2987. wpa_printf(MSG_INFO, "KaY: Cipher Suite changed");
  2988. participant->new_sak = TRUE;
  2989. }
  2990. return 0;
  2991. }