1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012, Jouni Malinen <j@w1.fi> 5 * All rights reserved. 6 * 7 * Galois/Counter Mode (GCM) and GMAC with AES 8 * 9 * Originally sourced from hostapd 2.11 (src/crypto/aes-gcm.c). 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 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include "opt_wlan.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 38 #include <crypto/rijndael/rijndael.h> 39 #include <net80211/ieee80211_crypto_gcm.h> 40 41 #define AES_BLOCK_LEN 16 42 43 #define BIT(x) (1U << (x)) 44 45 static __inline void 46 xor_block(uint8_t *b, const uint8_t *a, size_t len) 47 { 48 int i; 49 for (i = 0; i < len; i++) 50 b[i] ^= a[i]; 51 } 52 53 static inline 54 void WPA_PUT_BE64(uint8_t *a, uint64_t val) 55 { 56 a[0] = val >> 56; 57 a[1] = val >> 48; 58 a[2] = val >> 40; 59 a[3] = val >> 32; 60 a[4] = val >> 24; 61 a[5] = val >> 16; 62 a[6] = val >> 8; 63 a[7] = val & 0xff; 64 } 65 66 static inline void 67 WPA_PUT_BE32(uint8_t *a, uint32_t val) 68 { 69 a[0] = (val >> 24) & 0xff; 70 a[1] = (val >> 16) & 0xff; 71 a[2] = (val >> 8) & 0xff; 72 a[3] = val & 0xff; 73 } 74 75 static inline uint32_t 76 WPA_GET_BE32(const uint8_t *a) 77 { 78 return (((uint32_t) a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]); 79 } 80 81 static void 82 inc32(uint8_t *block) 83 { 84 uint32_t val; 85 86 val = WPA_GET_BE32(block + AES_BLOCK_LEN - 4); 87 val++; 88 WPA_PUT_BE32(block + AES_BLOCK_LEN - 4, val); 89 } 90 91 static void 92 shift_right_block(uint8_t *v) 93 { 94 uint32_t val; 95 96 val = WPA_GET_BE32(v + 12); 97 val >>= 1; 98 if (v[11] & 0x01) 99 val |= 0x80000000; 100 WPA_PUT_BE32(v + 12, val); 101 102 val = WPA_GET_BE32(v + 8); 103 val >>= 1; 104 if (v[7] & 0x01) 105 val |= 0x80000000; 106 WPA_PUT_BE32(v + 8, val); 107 108 val = WPA_GET_BE32(v + 4); 109 val >>= 1; 110 if (v[3] & 0x01) 111 val |= 0x80000000; 112 WPA_PUT_BE32(v + 4, val); 113 114 val = WPA_GET_BE32(v); 115 val >>= 1; 116 WPA_PUT_BE32(v, val); 117 } 118 119 120 /* Multiplication in GF(2^128) */ 121 static void 122 gf_mult(const uint8_t *x, const uint8_t *y, uint8_t *z) 123 { 124 uint8_t v[16]; 125 int i, j; 126 127 memset(z, 0, 16); /* Z_0 = 0^128 */ 128 memcpy(v, y, 16); /* V_0 = Y */ 129 130 for (i = 0; i < 16; i++) { 131 for (j = 0; j < 8; j++) { 132 if (x[i] & BIT(7 - j)) { 133 /* Z_(i + 1) = Z_i XOR V_i */ 134 xor_block(z, v, AES_BLOCK_LEN); 135 } else { 136 /* Z_(i + 1) = Z_i */ 137 } 138 139 if (v[15] & 0x01) { 140 /* V_(i + 1) = (V_i >> 1) XOR R */ 141 shift_right_block(v); 142 /* R = 11100001 || 0^120 */ 143 v[0] ^= 0xe1; 144 } else { 145 /* V_(i + 1) = V_i >> 1 */ 146 shift_right_block(v); 147 } 148 } 149 } 150 } 151 152 static void 153 ghash_start(uint8_t *y) 154 { 155 /* Y_0 = 0^128 */ 156 memset(y, 0, 16); 157 } 158 159 static void 160 ghash(const uint8_t *h, const uint8_t *x, size_t xlen, uint8_t *y) 161 { 162 size_t m, i; 163 const uint8_t *xpos = x; 164 uint8_t tmp[16]; 165 166 m = xlen / 16; 167 168 for (i = 0; i < m; i++) { 169 /* Y_i = (Y^(i-1) XOR X_i) dot H */ 170 xor_block(y, xpos, AES_BLOCK_LEN); 171 xpos += 16; 172 173 /* dot operation: 174 * multiplication operation for binary Galois (finite) field of 175 * 2^128 elements */ 176 gf_mult(y, h, tmp); 177 memcpy(y, tmp, 16); 178 } 179 180 if (x + xlen > xpos) { 181 /* Add zero padded last block */ 182 size_t last = x + xlen - xpos; 183 memcpy(tmp, xpos, last); 184 memset(tmp + last, 0, sizeof(tmp) - last); 185 186 /* Y_i = (Y^(i-1) XOR X_i) dot H */ 187 xor_block(y, tmp, AES_BLOCK_LEN); 188 189 /* dot operation: 190 * multiplication operation for binary Galois (finite) field of 191 * 2^128 elements */ 192 gf_mult(y, h, tmp); 193 memcpy(y, tmp, 16); 194 } 195 196 /* Return Y_m */ 197 } 198 199 /* 200 * Execute the GCTR call with the counter block icb 201 * on payload x (size len), output into y. 202 */ 203 static void 204 aes_gctr(rijndael_ctx *aes, const uint8_t *icb, 205 const uint8_t *x, size_t xlen, uint8_t *y) 206 { 207 size_t i, n, last; 208 uint8_t cb[AES_BLOCK_LEN], tmp[AES_BLOCK_LEN]; 209 const uint8_t *xpos = x; 210 uint8_t *ypos = y; 211 212 if (xlen == 0) 213 return; 214 215 n = xlen / 16; 216 217 memcpy(cb, icb, AES_BLOCK_LEN); 218 219 /* Full blocks */ 220 for (i = 0; i < n; i++) { 221 rijndael_encrypt(aes, cb, ypos); 222 xor_block(ypos, xpos, AES_BLOCK_LEN); 223 xpos += AES_BLOCK_LEN; 224 ypos += AES_BLOCK_LEN; 225 inc32(cb); 226 } 227 228 last = x + xlen - xpos; 229 if (last) { 230 /* Last, partial block */ 231 rijndael_encrypt(aes, cb, tmp); 232 for (i = 0; i < last; i++) 233 *ypos++ = *xpos++ ^ tmp[i]; 234 } 235 } 236 237 static void 238 aes_gcm_init_hash_subkey(rijndael_ctx *aes, uint8_t *H) 239 { 240 /* Generate hash subkey H = AES_K(0^128) */ 241 memset(H, 0, AES_BLOCK_LEN); 242 243 rijndael_encrypt(aes, H, H); 244 } 245 246 static void 247 aes_gcm_prepare_j0(const uint8_t *iv, size_t iv_len, const uint8_t *H, 248 uint8_t *J0) 249 { 250 uint8_t len_buf[16]; 251 252 if (iv_len == 12) { 253 /* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */ 254 memcpy(J0, iv, iv_len); 255 memset(J0 + iv_len, 0, AES_BLOCK_LEN - iv_len); 256 J0[AES_BLOCK_LEN - 1] = 0x01; 257 } else { 258 /* 259 * s = 128 * ceil(len(IV)/128) - len(IV) 260 * J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64) 261 */ 262 ghash_start(J0); 263 ghash(H, iv, iv_len, J0); 264 WPA_PUT_BE64(len_buf, 0); 265 WPA_PUT_BE64(len_buf + 8, iv_len * 8); 266 ghash(H, len_buf, sizeof(len_buf), J0); 267 } 268 } 269 270 static void 271 aes_gcm_gctr(rijndael_ctx *aes, const uint8_t *J0, const uint8_t *in, 272 size_t len, uint8_t *out) 273 { 274 uint8_t J0inc[AES_BLOCK_LEN]; 275 276 if (len == 0) 277 return; 278 279 memcpy(J0inc, J0, AES_BLOCK_LEN); 280 inc32(J0inc); 281 282 aes_gctr(aes, J0inc, in, len, out); 283 } 284 285 static void 286 aes_gcm_ghash(const uint8_t *H, const uint8_t *aad, size_t aad_len, 287 const uint8_t *crypt, size_t crypt_len, uint8_t *S) 288 { 289 uint8_t len_buf[16]; 290 291 /* 292 * u = 128 * ceil[len(C)/128] - len(C) 293 * v = 128 * ceil[len(A)/128] - len(A) 294 * S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64) 295 * (i.e., zero padded to block size A || C and lengths of each in bits) 296 */ 297 ghash_start(S); 298 ghash(H, aad, aad_len, S); 299 ghash(H, crypt, crypt_len, S); 300 WPA_PUT_BE64(len_buf, aad_len * 8); 301 WPA_PUT_BE64(len_buf + 8, crypt_len * 8); 302 ghash(H, len_buf, sizeof(len_buf), S); 303 } 304 305 /** 306 * aes_gcm_ae - GCM-AE_K(IV, P, A) 307 */ 308 void 309 ieee80211_crypto_aes_gcm_ae(rijndael_ctx *aes, const uint8_t *iv, size_t iv_len, 310 const uint8_t *plain, size_t plain_len, 311 const uint8_t *aad, size_t aad_len, uint8_t *crypt, uint8_t *tag) 312 { 313 uint8_t H[AES_BLOCK_LEN]; 314 uint8_t J0[AES_BLOCK_LEN]; 315 uint8_t S[GCMP_MIC_LEN]; 316 317 aes_gcm_init_hash_subkey(aes, H); 318 319 aes_gcm_prepare_j0(iv, iv_len, H, J0); 320 321 /* C = GCTR_K(inc_32(J_0), P) */ 322 aes_gcm_gctr(aes, J0, plain, plain_len, crypt); 323 324 aes_gcm_ghash(H, aad, aad_len, crypt, plain_len, S); 325 326 /* T = MSB_t(GCTR_K(J_0, S)) */ 327 aes_gctr(aes, J0, S, sizeof(S), tag); 328 329 /* Return (C, T) */ 330 } 331 332 /** 333 * aes_gcm_ad - GCM-AD_K(IV, C, A, T) 334 * 335 * Return 0 if OK, -1 if decrypt failure. 336 */ 337 int 338 ieee80211_crypto_aes_gcm_ad(rijndael_ctx *aes, const uint8_t *iv, size_t iv_len, 339 const uint8_t *crypt, size_t crypt_len, 340 const uint8_t *aad, size_t aad_len, const uint8_t *tag, uint8_t *plain) 341 { 342 uint8_t H[AES_BLOCK_LEN]; 343 uint8_t J0[AES_BLOCK_LEN]; 344 uint8_t S[16], T[GCMP_MIC_LEN]; 345 346 aes_gcm_init_hash_subkey(aes, H); 347 348 aes_gcm_prepare_j0(iv, iv_len, H, J0); 349 350 /* P = GCTR_K(inc_32(J_0), C) */ 351 aes_gcm_gctr(aes, J0, crypt, crypt_len, plain); 352 353 aes_gcm_ghash(H, aad, aad_len, crypt, crypt_len, S); 354 355 /* T' = MSB_t(GCTR_K(J_0, S)) */ 356 aes_gctr(aes, J0, S, sizeof(S), T); 357 358 if (memcmp(tag, T, 16) != 0) { 359 return (-1); 360 } 361 362 return (0); 363 } 364