The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net80211/ieee80211_crypto.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: ieee80211_crypto.c,v 1.78 2021/05/11 08:46:31 stsp Exp $      */
    2 
    3 /*-
    4  * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 #include <sys/param.h>
   20 #include <sys/systm.h>
   21 #include <sys/mbuf.h>
   22 #include <sys/malloc.h>
   23 #include <sys/kernel.h>
   24 #include <sys/socket.h>
   25 #include <sys/sockio.h>
   26 #include <sys/endian.h>
   27 #include <sys/errno.h>
   28 #include <sys/sysctl.h>
   29 
   30 #include <net/if.h>
   31 #include <net/if_dl.h>
   32 #include <net/if_media.h>
   33 
   34 #include <netinet/in.h>
   35 #include <netinet/if_ether.h>
   36 
   37 #include <net80211/ieee80211_var.h>
   38 #include <net80211/ieee80211_priv.h>
   39 
   40 #include <crypto/arc4.h>
   41 #include <crypto/md5.h>
   42 #include <crypto/sha1.h>
   43 #include <crypto/sha2.h>
   44 #include <crypto/hmac.h>
   45 #include <crypto/aes.h>
   46 #include <crypto/cmac.h>
   47 #include <crypto/key_wrap.h>
   48 
   49 void    ieee80211_prf(const u_int8_t *, size_t, const u_int8_t *, size_t,
   50             const u_int8_t *, size_t, u_int8_t *, size_t);
   51 void    ieee80211_kdf(const u_int8_t *, size_t, const u_int8_t *, size_t,
   52             const u_int8_t *, size_t, u_int8_t *, size_t);
   53 void    ieee80211_derive_pmkid(enum ieee80211_akm, const u_int8_t *,
   54             const u_int8_t *, const u_int8_t *, u_int8_t *);
   55 
   56 void
   57 ieee80211_crypto_attach(struct ifnet *ifp)
   58 {
   59         struct ieee80211com *ic = (void *)ifp;
   60 
   61         TAILQ_INIT(&ic->ic_pmksa);
   62         if (ic->ic_caps & IEEE80211_C_RSN) {
   63                 ic->ic_rsnprotos = IEEE80211_PROTO_RSN;
   64                 ic->ic_rsnakms = IEEE80211_AKM_PSK;
   65                 ic->ic_rsnciphers = IEEE80211_CIPHER_CCMP;
   66                 ic->ic_rsngroupcipher = IEEE80211_CIPHER_CCMP;
   67                 ic->ic_rsngroupmgmtcipher = IEEE80211_CIPHER_BIP;
   68         }
   69         ic->ic_set_key = ieee80211_set_key;
   70         ic->ic_delete_key = ieee80211_delete_key;
   71 #ifndef IEEE80211_STA_ONLY
   72         timeout_set(&ic->ic_tkip_micfail_timeout,
   73             ieee80211_michael_mic_failure_timeout, ic);
   74 #endif
   75 }
   76 
   77 void
   78 ieee80211_crypto_detach(struct ifnet *ifp)
   79 {
   80         struct ieee80211com *ic = (void *)ifp;
   81         struct ieee80211_pmk *pmk;
   82 
   83         /* purge the PMKSA cache */
   84         while ((pmk = TAILQ_FIRST(&ic->ic_pmksa)) != NULL) {
   85                 TAILQ_REMOVE(&ic->ic_pmksa, pmk, pmk_next);
   86                 explicit_bzero(pmk, sizeof(*pmk));
   87                 free(pmk, M_DEVBUF, sizeof(*pmk));
   88         }
   89 
   90         /* clear all group keys from memory */
   91         ieee80211_crypto_clear_groupkeys(ic);
   92 
   93         /* clear pre-shared key from memory */
   94         explicit_bzero(ic->ic_psk, IEEE80211_PMK_LEN);
   95 
   96 #ifndef IEEE80211_STA_ONLY
   97         timeout_del(&ic->ic_tkip_micfail_timeout);
   98 #endif
   99 }
  100 
  101 void
  102 ieee80211_crypto_clear_groupkeys(struct ieee80211com *ic)
  103 {
  104         int i;
  105 
  106         for (i = 0; i < IEEE80211_GROUP_NKID; i++) {
  107                 struct ieee80211_key *k = &ic->ic_nw_keys[i];
  108                 if (k->k_cipher != IEEE80211_CIPHER_NONE)
  109                         (*ic->ic_delete_key)(ic, NULL, k);
  110                 explicit_bzero(k, sizeof(*k));
  111         }
  112 }
  113 
  114 /*
  115  * Return the length in bytes of a cipher suite key (see Table 60).
  116  */
  117 int
  118 ieee80211_cipher_keylen(enum ieee80211_cipher cipher)
  119 {
  120         switch (cipher) {
  121         case IEEE80211_CIPHER_WEP40:
  122                 return 5;
  123         case IEEE80211_CIPHER_TKIP:
  124                 return 32;
  125         case IEEE80211_CIPHER_CCMP:
  126                 return 16;
  127         case IEEE80211_CIPHER_WEP104:
  128                 return 13;
  129         case IEEE80211_CIPHER_BIP:
  130                 return 16;
  131         default:        /* unknown cipher */
  132                 return 0;
  133         }
  134 }
  135 
  136 int
  137 ieee80211_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
  138     struct ieee80211_key *k)
  139 {
  140         int error;
  141 
  142         switch (k->k_cipher) {
  143         case IEEE80211_CIPHER_WEP40:
  144         case IEEE80211_CIPHER_WEP104:
  145                 error = ieee80211_wep_set_key(ic, k);
  146                 break;
  147         case IEEE80211_CIPHER_TKIP:
  148                 error = ieee80211_tkip_set_key(ic, k);
  149                 break;
  150         case IEEE80211_CIPHER_CCMP:
  151                 error = ieee80211_ccmp_set_key(ic, k);
  152                 break;
  153         case IEEE80211_CIPHER_BIP:
  154                 error = ieee80211_bip_set_key(ic, k);
  155                 break;
  156         default:
  157                 /* should not get there */
  158                 error = EINVAL;
  159         }
  160 
  161         if (error == 0)
  162                 k->k_flags |= IEEE80211_KEY_SWCRYPTO;
  163 
  164         return error;
  165 }
  166 
  167 void
  168 ieee80211_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
  169     struct ieee80211_key *k)
  170 {
  171         switch (k->k_cipher) {
  172         case IEEE80211_CIPHER_WEP40:
  173         case IEEE80211_CIPHER_WEP104:
  174                 ieee80211_wep_delete_key(ic, k);
  175                 break;
  176         case IEEE80211_CIPHER_TKIP:
  177                 ieee80211_tkip_delete_key(ic, k);
  178                 break;
  179         case IEEE80211_CIPHER_CCMP:
  180                 ieee80211_ccmp_delete_key(ic, k);
  181                 break;
  182         case IEEE80211_CIPHER_BIP:
  183                 ieee80211_bip_delete_key(ic, k);
  184                 break;
  185         default:
  186                 /* should not get there */
  187                 break;
  188         }
  189         explicit_bzero(k, sizeof(*k));
  190 }
  191 
  192 struct ieee80211_key *
  193 ieee80211_get_txkey(struct ieee80211com *ic, const struct ieee80211_frame *wh,
  194     struct ieee80211_node *ni)
  195 {
  196         int kid;
  197 
  198         if ((ic->ic_flags & IEEE80211_F_RSNON) &&
  199             !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
  200             ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP)
  201                 return &ni->ni_pairwise_key;
  202 
  203         /* All other cases (including WEP) use a group key. */
  204         if (ni->ni_flags & IEEE80211_NODE_MFP)
  205                 kid = ic->ic_igtk_kid;
  206         else
  207                 kid = ic->ic_def_txkey;
  208 
  209         return &ic->ic_nw_keys[kid];
  210 }
  211 
  212 struct ieee80211_key *
  213 ieee80211_get_rxkey(struct ieee80211com *ic, struct mbuf *m,
  214     struct ieee80211_node *ni)
  215 {
  216         struct ieee80211_key *k = NULL;
  217         struct ieee80211_frame *wh;
  218         u_int16_t kid;
  219         u_int8_t *ivp, *mmie;
  220         int hdrlen;
  221 
  222         wh = mtod(m, struct ieee80211_frame *);
  223         if ((ic->ic_flags & IEEE80211_F_RSNON) &&
  224             !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
  225             ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP) {
  226                 k = &ni->ni_pairwise_key;
  227         } else if (!IEEE80211_IS_MULTICAST(wh->i_addr1) ||
  228             (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
  229             IEEE80211_FC0_TYPE_MGT) {
  230                 /* retrieve group data key id from IV field */
  231                 hdrlen = ieee80211_get_hdrlen(wh);
  232                 /* check that IV field is present */
  233                 if (m->m_len < hdrlen + 4)
  234                         return NULL;
  235                 ivp = (u_int8_t *)wh + hdrlen;
  236                 kid = ivp[3] >> 6;
  237                 k = &ic->ic_nw_keys[kid];
  238         } else {
  239                 /* retrieve integrity group key id from MMIE */
  240                 if (m->m_len < sizeof(*wh) + IEEE80211_MMIE_LEN)
  241                         return NULL;
  242                 /* it is assumed management frames are contiguous */
  243                 mmie = (u_int8_t *)wh + m->m_len - IEEE80211_MMIE_LEN;
  244                 /* check that MMIE is valid */
  245                 if (mmie[0] != IEEE80211_ELEMID_MMIE || mmie[1] != 16)
  246                         return NULL;
  247                 kid = LE_READ_2(&mmie[2]);
  248                 if (kid != 4 && kid != 5)
  249                         return NULL;
  250                 k = &ic->ic_nw_keys[kid];
  251         }
  252 
  253         return k;
  254 }
  255 
  256 struct mbuf *
  257 ieee80211_encrypt(struct ieee80211com *ic, struct mbuf *m0,
  258     struct ieee80211_key *k)
  259 {
  260         if ((k->k_flags & IEEE80211_KEY_SWCRYPTO) == 0)
  261                 panic("%s: key unset for sw crypto: id=%d cipher=%d flags=0x%x",
  262                     __func__, k->k_id, k->k_cipher, k->k_flags);
  263 
  264         switch (k->k_cipher) {
  265         case IEEE80211_CIPHER_WEP40:
  266         case IEEE80211_CIPHER_WEP104:
  267                 m0 = ieee80211_wep_encrypt(ic, m0, k);
  268                 break;
  269         case IEEE80211_CIPHER_TKIP:
  270                 m0 = ieee80211_tkip_encrypt(ic, m0, k);
  271                 break;
  272         case IEEE80211_CIPHER_CCMP:
  273                 m0 = ieee80211_ccmp_encrypt(ic, m0, k);
  274                 break;
  275         case IEEE80211_CIPHER_BIP:
  276                 m0 = ieee80211_bip_encap(ic, m0, k);
  277                 break;
  278         default:
  279                 /* should not get there */
  280                 panic("invalid key cipher 0x%x", k->k_cipher);
  281         }
  282         return m0;
  283 }
  284 
  285 struct mbuf *
  286 ieee80211_decrypt(struct ieee80211com *ic, struct mbuf *m0,
  287     struct ieee80211_node *ni)
  288 {
  289         struct ieee80211_key *k;
  290 
  291         /* find key for decryption */
  292         k = ieee80211_get_rxkey(ic, m0, ni);
  293         if (k == NULL || (k->k_flags & IEEE80211_KEY_SWCRYPTO) == 0) {
  294                 m_freem(m0);
  295                 return NULL;
  296         }
  297 
  298         switch (k->k_cipher) {
  299         case IEEE80211_CIPHER_WEP40:
  300         case IEEE80211_CIPHER_WEP104:
  301                 m0 = ieee80211_wep_decrypt(ic, m0, k);
  302                 break;
  303         case IEEE80211_CIPHER_TKIP:
  304                 m0 = ieee80211_tkip_decrypt(ic, m0, k);
  305                 break;
  306         case IEEE80211_CIPHER_CCMP:
  307                 m0 = ieee80211_ccmp_decrypt(ic, m0, k);
  308                 break;
  309         case IEEE80211_CIPHER_BIP:
  310                 m0 = ieee80211_bip_decap(ic, m0, k);
  311                 break;
  312         default:
  313                 /* key not defined */
  314                 m_freem(m0);
  315                 m0 = NULL;
  316         }
  317         return m0;
  318 }
  319 
  320 /*
  321  * SHA1-based Pseudo-Random Function (see 8.5.1.1).
  322  */
  323 void
  324 ieee80211_prf(const u_int8_t *key, size_t key_len, const u_int8_t *label,
  325     size_t label_len, const u_int8_t *context, size_t context_len,
  326     u_int8_t *output, size_t len)
  327 {
  328         HMAC_SHA1_CTX ctx;
  329         u_int8_t digest[SHA1_DIGEST_LENGTH];
  330         u_int8_t count;
  331 
  332         for (count = 0; len != 0; count++) {
  333                 HMAC_SHA1_Init(&ctx, key, key_len);
  334                 HMAC_SHA1_Update(&ctx, label, label_len);
  335                 HMAC_SHA1_Update(&ctx, context, context_len);
  336                 HMAC_SHA1_Update(&ctx, &count, 1);
  337                 if (len < SHA1_DIGEST_LENGTH) {
  338                         HMAC_SHA1_Final(digest, &ctx);
  339                         /* truncate HMAC-SHA1 to len bytes */
  340                         memcpy(output, digest, len);
  341                         break;
  342                 }
  343                 HMAC_SHA1_Final(output, &ctx);
  344                 output += SHA1_DIGEST_LENGTH;
  345                 len -= SHA1_DIGEST_LENGTH;
  346         }
  347 }
  348 
  349 /*
  350  * SHA256-based Key Derivation Function (see 8.5.1.5.2).
  351  */
  352 void
  353 ieee80211_kdf(const u_int8_t *key, size_t key_len, const u_int8_t *label,
  354     size_t label_len, const u_int8_t *context, size_t context_len,
  355     u_int8_t *output, size_t len)
  356 {
  357         HMAC_SHA256_CTX ctx;
  358         u_int8_t digest[SHA256_DIGEST_LENGTH];
  359         u_int16_t i, iter, length;
  360 
  361         length = htole16(len * NBBY);
  362         for (i = 1; len != 0; i++) {
  363                 HMAC_SHA256_Init(&ctx, key, key_len);
  364                 iter = htole16(i);
  365                 HMAC_SHA256_Update(&ctx, (u_int8_t *)&iter, sizeof iter);
  366                 HMAC_SHA256_Update(&ctx, label, label_len);
  367                 HMAC_SHA256_Update(&ctx, context, context_len);
  368                 HMAC_SHA256_Update(&ctx, (u_int8_t *)&length, sizeof length);
  369                 if (len < SHA256_DIGEST_LENGTH) {
  370                         HMAC_SHA256_Final(digest, &ctx);
  371                         /* truncate HMAC-SHA-256 to len bytes */
  372                         memcpy(output, digest, len);
  373                         break;
  374                 }
  375                 HMAC_SHA256_Final(output, &ctx);
  376                 output += SHA256_DIGEST_LENGTH;
  377                 len -= SHA256_DIGEST_LENGTH;
  378         }
  379 }
  380 
  381 /*
  382  * Derive Pairwise Transient Key (PTK) (see 8.5.1.2).
  383  */
  384 void
  385 ieee80211_derive_ptk(enum ieee80211_akm akm, const u_int8_t *pmk,
  386     const u_int8_t *aa, const u_int8_t *spa, const u_int8_t *anonce,
  387     const u_int8_t *snonce, struct ieee80211_ptk *ptk)
  388 {
  389         void (*kdf)(const u_int8_t *, size_t, const u_int8_t *, size_t,
  390             const u_int8_t *, size_t, u_int8_t *, size_t);
  391         u_int8_t buf[2 * IEEE80211_ADDR_LEN + 2 * EAPOL_KEY_NONCE_LEN];
  392         int ret;
  393 
  394         /* Min(AA,SPA) || Max(AA,SPA) */
  395         ret = memcmp(aa, spa, IEEE80211_ADDR_LEN) < 0;
  396         memcpy(&buf[ 0], ret ? aa : spa, IEEE80211_ADDR_LEN);
  397         memcpy(&buf[ 6], ret ? spa : aa, IEEE80211_ADDR_LEN);
  398 
  399         /* Min(ANonce,SNonce) || Max(ANonce,SNonce) */
  400         ret = memcmp(anonce, snonce, EAPOL_KEY_NONCE_LEN) < 0;
  401         memcpy(&buf[12], ret ? anonce : snonce, EAPOL_KEY_NONCE_LEN);
  402         memcpy(&buf[44], ret ? snonce : anonce, EAPOL_KEY_NONCE_LEN);
  403 
  404         kdf = ieee80211_is_sha256_akm(akm) ? ieee80211_kdf : ieee80211_prf;
  405         (*kdf)(pmk, IEEE80211_PMK_LEN, "Pairwise key expansion", 23,
  406             buf, sizeof buf, (u_int8_t *)ptk, sizeof(*ptk));
  407 }
  408 
  409 static void
  410 ieee80211_pmkid_sha1(const u_int8_t *pmk, const u_int8_t *aa,
  411     const u_int8_t *spa, u_int8_t *pmkid)
  412 {
  413         HMAC_SHA1_CTX ctx;
  414         u_int8_t digest[SHA1_DIGEST_LENGTH];
  415 
  416         HMAC_SHA1_Init(&ctx, pmk, IEEE80211_PMK_LEN);
  417         HMAC_SHA1_Update(&ctx, "PMK Name", 8);
  418         HMAC_SHA1_Update(&ctx, aa, IEEE80211_ADDR_LEN);
  419         HMAC_SHA1_Update(&ctx, spa, IEEE80211_ADDR_LEN);
  420         HMAC_SHA1_Final(digest, &ctx);
  421         /* use the first 128 bits of HMAC-SHA1 */
  422         memcpy(pmkid, digest, IEEE80211_PMKID_LEN);
  423 }
  424 
  425 static void
  426 ieee80211_pmkid_sha256(const u_int8_t *pmk, const u_int8_t *aa,
  427     const u_int8_t *spa, u_int8_t *pmkid)
  428 {
  429         HMAC_SHA256_CTX ctx;
  430         u_int8_t digest[SHA256_DIGEST_LENGTH];
  431 
  432         HMAC_SHA256_Init(&ctx, pmk, IEEE80211_PMK_LEN);
  433         HMAC_SHA256_Update(&ctx, "PMK Name", 8);
  434         HMAC_SHA256_Update(&ctx, aa, IEEE80211_ADDR_LEN);
  435         HMAC_SHA256_Update(&ctx, spa, IEEE80211_ADDR_LEN);
  436         HMAC_SHA256_Final(digest, &ctx);
  437         /* use the first 128 bits of HMAC-SHA-256 */
  438         memcpy(pmkid, digest, IEEE80211_PMKID_LEN);
  439 }
  440 
  441 /*
  442  * Derive Pairwise Master Key Identifier (PMKID) (see 8.5.1.2).
  443  */
  444 void
  445 ieee80211_derive_pmkid(enum ieee80211_akm akm, const u_int8_t *pmk,
  446     const u_int8_t *aa, const u_int8_t *spa, u_int8_t *pmkid)
  447 {
  448         if (ieee80211_is_sha256_akm(akm))
  449                 ieee80211_pmkid_sha256(pmk, aa, spa, pmkid);
  450         else
  451                 ieee80211_pmkid_sha1(pmk, aa, spa, pmkid);
  452 }
  453 
  454 typedef union _ANY_CTX {
  455         HMAC_MD5_CTX    md5;
  456         HMAC_SHA1_CTX   sha1;
  457         AES_CMAC_CTX    cmac;
  458 } ANY_CTX;
  459 
  460 /*
  461  * Compute the Key MIC field of an EAPOL-Key frame using the specified Key
  462  * Confirmation Key (KCK).  The hash function can be HMAC-MD5, HMAC-SHA1
  463  * or AES-128-CMAC depending on the EAPOL-Key Key Descriptor Version.
  464  */
  465 void
  466 ieee80211_eapol_key_mic(struct ieee80211_eapol_key *key, const u_int8_t *kck)
  467 {
  468         u_int8_t digest[SHA1_DIGEST_LENGTH];
  469         ANY_CTX ctx;    /* XXX off stack? */
  470         u_int len;
  471 
  472         len = BE_READ_2(key->len) + 4;
  473 
  474         switch (BE_READ_2(key->info) & EAPOL_KEY_VERSION_MASK) {
  475         case EAPOL_KEY_DESC_V1:
  476                 HMAC_MD5_Init(&ctx.md5, kck, 16);
  477                 HMAC_MD5_Update(&ctx.md5, (u_int8_t *)key, len);
  478                 HMAC_MD5_Final(key->mic, &ctx.md5);
  479                 break;
  480         case EAPOL_KEY_DESC_V2:
  481                 HMAC_SHA1_Init(&ctx.sha1, kck, 16);
  482                 HMAC_SHA1_Update(&ctx.sha1, (u_int8_t *)key, len);
  483                 HMAC_SHA1_Final(digest, &ctx.sha1);
  484                 /* truncate HMAC-SHA1 to its 128 MSBs */
  485                 memcpy(key->mic, digest, EAPOL_KEY_MIC_LEN);
  486                 break;
  487         case EAPOL_KEY_DESC_V3:
  488                 AES_CMAC_Init(&ctx.cmac);
  489                 AES_CMAC_SetKey(&ctx.cmac, kck);
  490                 AES_CMAC_Update(&ctx.cmac, (u_int8_t *)key, len);
  491                 AES_CMAC_Final(key->mic, &ctx.cmac);
  492                 break;
  493         }
  494 }
  495 
  496 /*
  497  * Check the MIC of a received EAPOL-Key frame using the specified Key
  498  * Confirmation Key (KCK).
  499  */
  500 int
  501 ieee80211_eapol_key_check_mic(struct ieee80211_eapol_key *key,
  502     const u_int8_t *kck)
  503 {
  504         u_int8_t mic[EAPOL_KEY_MIC_LEN];
  505 
  506         memcpy(mic, key->mic, EAPOL_KEY_MIC_LEN);
  507         memset(key->mic, 0, EAPOL_KEY_MIC_LEN);
  508         ieee80211_eapol_key_mic(key, kck);
  509 
  510         return timingsafe_bcmp(key->mic, mic, EAPOL_KEY_MIC_LEN) != 0;
  511 }
  512 
  513 #ifndef IEEE80211_STA_ONLY
  514 /*
  515  * Encrypt the Key Data field of an EAPOL-Key frame using the specified Key
  516  * Encryption Key (KEK).  The encryption algorithm can be either ARC4 or
  517  * AES Key Wrap depending on the EAPOL-Key Key Descriptor Version.
  518  */
  519 void
  520 ieee80211_eapol_key_encrypt(struct ieee80211com *ic,
  521     struct ieee80211_eapol_key *key, const u_int8_t *kek)
  522 {
  523         union {
  524                 struct rc4_ctx rc4;
  525                 aes_key_wrap_ctx aes;
  526         } ctx;  /* XXX off stack? */
  527         u_int8_t keybuf[EAPOL_KEY_IV_LEN + 16];
  528         u_int16_t len, info;
  529         u_int8_t *data;
  530         int n;
  531 
  532         len  = BE_READ_2(key->paylen);
  533         info = BE_READ_2(key->info);
  534         data = (u_int8_t *)(key + 1);
  535 
  536         switch (info & EAPOL_KEY_VERSION_MASK) {
  537         case EAPOL_KEY_DESC_V1:
  538                 /* set IV to the lower 16 octets of our global key counter */
  539                 memcpy(key->iv, ic->ic_globalcnt + 16, 16);
  540                 /* increment our global key counter (256-bit, big-endian) */
  541                 for (n = 31; n >= 0 && ++ic->ic_globalcnt[n] == 0; n--);
  542 
  543                 /* concatenate the EAPOL-Key IV field and the KEK */
  544                 memcpy(keybuf, key->iv, EAPOL_KEY_IV_LEN);
  545                 memcpy(keybuf + EAPOL_KEY_IV_LEN, kek, 16);
  546 
  547                 rc4_keysetup(&ctx.rc4, keybuf, sizeof keybuf);
  548                 /* discard the first 256 octets of the ARC4 key stream */
  549                 rc4_skip(&ctx.rc4, RC4STATE);
  550                 rc4_crypt(&ctx.rc4, data, data, len);
  551                 break;
  552         case EAPOL_KEY_DESC_V2:
  553         case EAPOL_KEY_DESC_V3:
  554                 if (len < 16 || (len & 7) != 0) {
  555                         /* insert padding */
  556                         n = (len < 16) ? 16 - len : 8 - (len & 7);
  557                         data[len++] = IEEE80211_ELEMID_VENDOR;
  558                         memset(&data[len], 0, n - 1);
  559                         len += n - 1;
  560                 }
  561                 aes_key_wrap_set_key_wrap_only(&ctx.aes, kek, 16);
  562                 aes_key_wrap(&ctx.aes, data, len / 8, data);
  563                 len += 8;       /* AES Key Wrap adds 8 bytes */
  564                 /* update key data length */
  565                 BE_WRITE_2(key->paylen, len);
  566                 /* update packet body length */
  567                 BE_WRITE_2(key->len, sizeof(*key) + len - 4);
  568                 break;
  569         }
  570 }
  571 #endif  /* IEEE80211_STA_ONLY */
  572 
  573 /*
  574  * Decrypt the Key Data field of an EAPOL-Key frame using the specified Key
  575  * Encryption Key (KEK).  The encryption algorithm can be either ARC4 or
  576  * AES Key Wrap depending on the EAPOL-Key Key Descriptor Version.
  577  */
  578 int
  579 ieee80211_eapol_key_decrypt(struct ieee80211_eapol_key *key,
  580     const u_int8_t *kek)
  581 {
  582         union {
  583                 struct rc4_ctx rc4;
  584                 aes_key_wrap_ctx aes;
  585         } ctx;  /* XXX off stack? */
  586         u_int8_t keybuf[EAPOL_KEY_IV_LEN + 16];
  587         u_int16_t len, info;
  588         u_int8_t *data;
  589 
  590         len  = BE_READ_2(key->paylen);
  591         info = BE_READ_2(key->info);
  592         data = (u_int8_t *)(key + 1);
  593 
  594         switch (info & EAPOL_KEY_VERSION_MASK) {
  595         case EAPOL_KEY_DESC_V1:
  596                 /* concatenate the EAPOL-Key IV field and the KEK */
  597                 memcpy(keybuf, key->iv, EAPOL_KEY_IV_LEN);
  598                 memcpy(keybuf + EAPOL_KEY_IV_LEN, kek, 16);
  599 
  600                 rc4_keysetup(&ctx.rc4, keybuf, sizeof keybuf);
  601                 /* discard the first 256 octets of the ARC4 key stream */
  602                 rc4_skip(&ctx.rc4, RC4STATE);
  603                 rc4_crypt(&ctx.rc4, data, data, len);
  604                 return 0;
  605         case EAPOL_KEY_DESC_V2:
  606         case EAPOL_KEY_DESC_V3:
  607                 /* Key Data Length must be a multiple of 8 */
  608                 if (len < 16 + 8 || (len & 7) != 0)
  609                         return 1;
  610                 len -= 8;       /* AES Key Wrap adds 8 bytes */
  611                 aes_key_wrap_set_key(&ctx.aes, kek, 16);
  612                 return aes_key_unwrap(&ctx.aes, data, data, len / 8);
  613         }
  614 
  615         return 1;       /* unknown Key Descriptor Version */
  616 }
  617 
  618 /*
  619  * Add a PMK entry to the PMKSA cache.
  620  */
  621 struct ieee80211_pmk *
  622 ieee80211_pmksa_add(struct ieee80211com *ic, enum ieee80211_akm akm,
  623     const u_int8_t *macaddr, const u_int8_t *key, u_int32_t lifetime)
  624 {
  625         struct ieee80211_pmk *pmk;
  626 
  627         /* check if an entry already exists for this (STA,AKMP) */
  628         TAILQ_FOREACH(pmk, &ic->ic_pmksa, pmk_next) {
  629                 if (pmk->pmk_akm == akm &&
  630                     IEEE80211_ADDR_EQ(pmk->pmk_macaddr, macaddr))
  631                         break;
  632         }
  633         if (pmk == NULL) {
  634                 /* allocate a new PMKSA entry */
  635                 if ((pmk = malloc(sizeof(*pmk), M_DEVBUF, M_NOWAIT)) == NULL)
  636                         return NULL;
  637                 pmk->pmk_akm = akm;
  638                 IEEE80211_ADDR_COPY(pmk->pmk_macaddr, macaddr);
  639                 TAILQ_INSERT_TAIL(&ic->ic_pmksa, pmk, pmk_next);
  640         }
  641         memcpy(pmk->pmk_key, key, IEEE80211_PMK_LEN);
  642         pmk->pmk_lifetime = lifetime;   /* XXX not used yet */
  643 #ifndef IEEE80211_STA_ONLY
  644         if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
  645                 ieee80211_derive_pmkid(pmk->pmk_akm, pmk->pmk_key,
  646                     ic->ic_myaddr, macaddr, pmk->pmk_pmkid);
  647         } else
  648 #endif
  649         {
  650                 ieee80211_derive_pmkid(pmk->pmk_akm, pmk->pmk_key,
  651                     macaddr, ic->ic_myaddr, pmk->pmk_pmkid);
  652         }
  653         return pmk;
  654 }
  655 
  656 /*
  657  * Check if we have a cached PMK entry for the specified node and PMKID.
  658  */
  659 struct ieee80211_pmk *
  660 ieee80211_pmksa_find(struct ieee80211com *ic, struct ieee80211_node *ni,
  661     const u_int8_t *pmkid)
  662 {
  663         struct ieee80211_pmk *pmk;
  664 
  665         TAILQ_FOREACH(pmk, &ic->ic_pmksa, pmk_next) {
  666                 if (pmk->pmk_akm == ni->ni_rsnakms &&
  667                     IEEE80211_ADDR_EQ(pmk->pmk_macaddr, ni->ni_macaddr) &&
  668                     (pmkid == NULL ||
  669                      memcmp(pmk->pmk_pmkid, pmkid, IEEE80211_PMKID_LEN) == 0))
  670                         break;
  671         }
  672         return pmk;
  673 }

Cache object: be326b38ab6fccc2475f0db152576579


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.