1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2001 Atsushi Onoe 8 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * Alternatively, this software may be distributed under the terms of the 23 * GNU General Public License ("GPL") version 2 as published by the Free 24 * Software Foundation. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #pragma ident "%Z%%M% %I% %E% SMI" 39 40 /* 41 * IEEE 802.11i TKIP crypto support. 42 */ 43 #include <sys/byteorder.h> 44 #include <sys/crypto/common.h> 45 #include <sys/crypto/api.h> 46 #include <sys/crc32.h> 47 #include <sys/random.h> 48 #include "net80211_impl.h" 49 50 static void *tkip_attach(struct ieee80211com *, struct ieee80211_key *); 51 static void tkip_detach(struct ieee80211_key *); 52 static int tkip_setkey(struct ieee80211_key *); 53 static int tkip_encap(struct ieee80211_key *, mblk_t *, uint8_t); 54 static int tkip_decap(struct ieee80211_key *, mblk_t *, int); 55 static int tkip_enmic(struct ieee80211_key *, mblk_t *, int); 56 static int tkip_demic(struct ieee80211_key *, mblk_t *, int); 57 58 const struct ieee80211_cipher tkip = { 59 "TKIP", 60 IEEE80211_CIPHER_TKIP, 61 IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + 62 IEEE80211_WEP_EXTIVLEN, 63 IEEE80211_WEP_CRCLEN, 64 IEEE80211_WEP_MICLEN, 65 tkip_attach, 66 tkip_detach, 67 tkip_setkey, 68 tkip_encap, 69 tkip_decap, 70 tkip_enmic, 71 tkip_demic, 72 }; 73 74 struct tkip_ctx { 75 struct ieee80211com *tc_ic; /* for diagnostics */ 76 uint16_t tx_ttak[5]; 77 int tx_phase1_done; 78 uint8_t tx_rc4key[16]; 79 uint16_t rx_ttak[5]; 80 int rx_phase1_done; 81 uint8_t rx_rc4key[16]; 82 uint64_t rx_rsc; /* held until MIC verified */ 83 }; 84 85 /* ARGSUSED */ 86 static void * 87 tkip_attach(struct ieee80211com *ic, struct ieee80211_key *k) 88 { 89 struct tkip_ctx *ctx; 90 91 ctx = kmem_zalloc(sizeof (struct tkip_ctx), KM_SLEEP); 92 if (ctx == NULL) 93 return (NULL); 94 95 ctx->tc_ic = ic; 96 return (ctx); 97 } 98 99 static void 100 tkip_detach(struct ieee80211_key *k) 101 { 102 struct tkip_ctx *ctx = k->wk_private; 103 104 if (ctx != NULL) 105 kmem_free(ctx, sizeof (struct tkip_ctx)); 106 } 107 108 static int 109 tkip_setkey(struct ieee80211_key *k) 110 { 111 if (k->wk_keylen != (128/NBBY)) 112 return (0); 113 114 k->wk_keytsc = 1; /* TSC starts at 1 */ 115 return (1); 116 } 117 118 /* 119 * Add privacy headers appropriate for the specified key. 120 */ 121 static int 122 tkip_encap(struct ieee80211_key *k, mblk_t *mp, uint8_t keyid) 123 { 124 struct tkip_ctx *ctx = k->wk_private; 125 struct ieee80211com *ic = ctx->tc_ic; 126 uint8_t *ivp; 127 int hdrlen; 128 129 /* 130 * Handle TKIP counter measures requirement. 131 */ 132 if (ic->ic_flags & IEEE80211_F_COUNTERM) 133 return (0); 134 135 hdrlen = ieee80211_hdrspace(mp->b_rptr); 136 /* 137 * Copy down 802.11 header and add the IV, KeyID, and ExtIV. 138 */ 139 ivp = mp->b_rptr; 140 ivp += hdrlen; 141 142 ivp[0] = k->wk_keytsc >> 8; /* TSC1 */ 143 ivp[1] = (ivp[0] | 0x20) & 0x7f; /* WEP seed */ 144 ivp[2] = k->wk_keytsc >> 0; /* TSC0 */ 145 ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ 146 ivp[4] = k->wk_keytsc >> 16; /* TSC2 */ 147 ivp[5] = k->wk_keytsc >> 24; /* TSC3 */ 148 ivp[6] = k->wk_keytsc >> 32; /* TSC4 */ 149 ivp[7] = k->wk_keytsc >> 40; /* TSC5 */ 150 151 /* 152 * NB: software TKIP is not supported. 153 */ 154 if (k->wk_flags & IEEE80211_KEY_SWCRYPT) 155 return (0); 156 else 157 k->wk_keytsc++; /* wrap at 48 bits */ 158 159 return (1); 160 } 161 162 uint64_t 163 ieee80211_read_6(uint8_t b0, uint8_t b1, uint8_t b2, 164 uint8_t b3, uint8_t b4, uint8_t b5) 165 { 166 uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24); 167 uint16_t iv16 = (b4 << 0) | (b5 << 8); 168 return ((((uint64_t)iv16) << 32) | iv32); 169 } 170 171 /* 172 * Validate and strip privacy headers (and trailer) for a 173 * received frame. If necessary, decrypt the frame using 174 * the specified key. 175 */ 176 static int 177 tkip_decap(struct ieee80211_key *k, mblk_t *mp, int hdrlen) 178 { 179 struct tkip_ctx *ctx = k->wk_private; 180 struct ieee80211com *ic = ctx->tc_ic; 181 struct ieee80211_frame tmp; 182 uint8_t *ivp; 183 uint64_t pn; 184 185 /* 186 * Header should have extended IV and sequence number; 187 * verify the former and validate the latter. 188 */ 189 ivp = mp->b_rptr + hdrlen; 190 if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) { 191 /* 192 * No extended IV; discard frame. 193 */ 194 return (0); 195 } 196 /* 197 * Handle TKIP counter measures requirement. 198 */ 199 if (ic->ic_flags & IEEE80211_F_COUNTERM) 200 return (0); 201 202 /* NB: assume IEEEE80211_WEP_MINLEN covers the extended IV */ 203 pn = ieee80211_read_6(ivp[2], ivp[0], ivp[4], ivp[5], ivp[6], ivp[7]); 204 ctx->rx_rsc = pn; 205 if (ctx->rx_rsc <= k->wk_keyrsc) 206 return (0); 207 /* 208 * NB: We can't update the rsc in the key until MIC is verified. 209 * 210 * We assume we are not preempted between doing the check above 211 * and updating wk_keyrsc when stripping the MIC in tkip_demic. 212 * Otherwise we might process another packet and discard it as 213 * a replay. 214 */ 215 216 /* 217 * NB: software TKIP is not supported. 218 */ 219 if (k->wk_flags & IEEE80211_KEY_SWCRYPT) 220 return (0); 221 222 /* 223 * Copy up 802.11 header and strip crypto bits. 224 */ 225 bcopy(mp->b_rptr, &tmp, hdrlen); 226 bcopy(&tmp, mp->b_rptr + tkip.ic_header, hdrlen); 227 mp->b_rptr += tkip.ic_header; 228 mp->b_wptr -= tkip.ic_trailer; 229 230 return (1); 231 } 232 233 /* 234 * Add MIC to the frame as needed. 235 */ 236 /* ARGSUSED */ 237 static int 238 tkip_enmic(struct ieee80211_key *k, mblk_t *mp, int force) 239 { 240 return (1); 241 } 242 243 /* 244 * Verify and strip MIC from the frame. 245 */ 246 /* ARGSUSED */ 247 static int 248 tkip_demic(struct ieee80211_key *k, mblk_t *mp, int force) 249 { 250 struct tkip_ctx *ctx = k->wk_private; 251 252 /* 253 * NB: software TKIP is not supported. 254 */ 255 if (k->wk_flags & IEEE80211_KEY_SWMIC) 256 return (0); 257 /* 258 * Strip MIC from the tail. 259 */ 260 mp->b_wptr -= tkip.ic_miclen; 261 /* 262 * Ok to update rsc now that MIC has been verified. 263 */ 264 k->wk_keyrsc = ctx->rx_rsc; 265 266 return (1); 267 } 268