gcmp.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /*
  2. * GCM with GMAC Protocol (GCMP)
  3. * Copyright (c) 2012, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "utils/includes.h"
  9. #include "utils/common.h"
  10. #include "common/ieee802_11_defs.h"
  11. #include "crypto/aes.h"
  12. #include "wlantest.h"
  13. static void inc32(u8 *block)
  14. {
  15. u32 val;
  16. val = WPA_GET_BE32(block + AES_BLOCK_SIZE - 4);
  17. val++;
  18. WPA_PUT_BE32(block + AES_BLOCK_SIZE - 4, val);
  19. }
  20. static void xor_block(u8 *dst, const u8 *src)
  21. {
  22. u32 *d = (u32 *) dst;
  23. u32 *s = (u32 *) src;
  24. *d++ ^= *s++;
  25. *d++ ^= *s++;
  26. *d++ ^= *s++;
  27. *d++ ^= *s++;
  28. }
  29. static void shift_right_block(u8 *v)
  30. {
  31. u32 val;
  32. val = WPA_GET_BE32(v + 12);
  33. val >>= 1;
  34. if (v[11] & 0x01)
  35. val |= 0x80000000;
  36. WPA_PUT_BE32(v + 12, val);
  37. val = WPA_GET_BE32(v + 8);
  38. val >>= 1;
  39. if (v[7] & 0x01)
  40. val |= 0x80000000;
  41. WPA_PUT_BE32(v + 8, val);
  42. val = WPA_GET_BE32(v + 4);
  43. val >>= 1;
  44. if (v[3] & 0x01)
  45. val |= 0x80000000;
  46. WPA_PUT_BE32(v + 4, val);
  47. val = WPA_GET_BE32(v);
  48. val >>= 1;
  49. WPA_PUT_BE32(v, val);
  50. }
  51. /* Multiplication in GF(2^128) */
  52. static void gf_mult(const u8 *x, const u8 *y, u8 *z)
  53. {
  54. u8 v[16];
  55. int i, j;
  56. os_memset(z, 0, 16); /* Z_0 = 0^128 */
  57. os_memcpy(v, y, 16); /* V_0 = Y */
  58. for (i = 0; i < 16; i++) {
  59. for (j = 0; j < 8; j++) {
  60. if (x[i] & BIT(7 - j)) {
  61. /* Z_(i + 1) = Z_i XOR V_i */
  62. xor_block(z, v);
  63. } else {
  64. /* Z_(i + 1) = Z_i */
  65. }
  66. if (v[15] & 0x01) {
  67. /* V_(i + 1) = (V_i >> 1) XOR R */
  68. shift_right_block(v);
  69. /* R = 11100001 || 0^120 */
  70. v[0] ^= 0xe1;
  71. } else {
  72. /* V_(i + 1) = V_i >> 1 */
  73. shift_right_block(v);
  74. }
  75. }
  76. }
  77. }
  78. static void ghash(const u8 *h, const u8 *x, size_t xlen, u8 *y)
  79. {
  80. size_t m, i;
  81. const u8 *xpos = x;
  82. u8 tmp[16];
  83. m = xlen / 16;
  84. /* Y_0 = 0^128 */
  85. os_memset(y, 0, 16);
  86. for (i = 0; i < m; i++) {
  87. /* Y_i = (Y^(i-1) XOR X_i) dot H */
  88. xor_block(y, xpos);
  89. xpos += 16;
  90. /* dot operation:
  91. * multiplication operation for binary Galois (finite) field of
  92. * 2^128 elements */
  93. gf_mult(y, h, tmp);
  94. os_memcpy(y, tmp, 16);
  95. }
  96. /* Return Y_m */
  97. }
  98. static void aes_gctr(void *aes, const u8 *icb, const u8 *x, size_t xlen, u8 *y)
  99. {
  100. size_t i, n, last;
  101. u8 cb[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
  102. const u8 *xpos = x;
  103. u8 *ypos = y;
  104. if (xlen == 0)
  105. return;
  106. n = xlen / 16;
  107. os_memcpy(cb, icb, AES_BLOCK_SIZE);
  108. /* Full blocks */
  109. for (i = 0; i < n; i++) {
  110. aes_encrypt(aes, cb, ypos);
  111. xor_block(ypos, xpos);
  112. xpos += AES_BLOCK_SIZE;
  113. ypos += AES_BLOCK_SIZE;
  114. inc32(cb);
  115. }
  116. last = x + xlen - xpos;
  117. if (last) {
  118. /* Last, partial block */
  119. aes_encrypt(aes, cb, tmp);
  120. for (i = 0; i < last; i++)
  121. *ypos++ = *xpos++ ^ tmp[i];
  122. }
  123. }
  124. static void gcmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data,
  125. u8 *aad, size_t *aad_len, u8 *nonce)
  126. {
  127. u16 fc, stype, seq;
  128. int qos = 0, addr4 = 0;
  129. u8 *pos;
  130. fc = le_to_host16(hdr->frame_control);
  131. stype = WLAN_FC_GET_STYPE(fc);
  132. if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
  133. (WLAN_FC_TODS | WLAN_FC_FROMDS))
  134. addr4 = 1;
  135. if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) {
  136. fc &= ~0x0070; /* Mask subtype bits */
  137. if (stype & 0x08) {
  138. const u8 *qc;
  139. qos = 1;
  140. fc &= ~WLAN_FC_ORDER;
  141. qc = (const u8 *) (hdr + 1);
  142. if (addr4)
  143. qc += ETH_ALEN;
  144. }
  145. }
  146. fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
  147. fc |= WLAN_FC_ISWEP;
  148. WPA_PUT_LE16(aad, fc);
  149. pos = aad + 2;
  150. os_memcpy(pos, hdr->addr1, 3 * ETH_ALEN);
  151. pos += 3 * ETH_ALEN;
  152. seq = le_to_host16(hdr->seq_ctrl);
  153. seq &= ~0xfff0; /* Mask Seq#; do not modify Frag# */
  154. WPA_PUT_LE16(pos, seq);
  155. pos += 2;
  156. os_memcpy(pos, hdr + 1, addr4 * ETH_ALEN + qos * 2);
  157. pos += addr4 * ETH_ALEN;
  158. if (qos) {
  159. pos[0] &= ~0x70;
  160. if (1 /* FIX: either device has SPP A-MSDU Capab = 0 */)
  161. pos[0] &= ~0x80;
  162. pos++;
  163. *pos++ = 0x00;
  164. }
  165. *aad_len = pos - aad;
  166. os_memcpy(nonce, hdr->addr2, ETH_ALEN);
  167. nonce[6] = data[7]; /* PN5 */
  168. nonce[7] = data[6]; /* PN4 */
  169. nonce[8] = data[5]; /* PN3 */
  170. nonce[9] = data[4]; /* PN2 */
  171. nonce[10] = data[1]; /* PN1 */
  172. nonce[11] = data[0]; /* PN0 */
  173. }
  174. u8 * gcmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
  175. const u8 *data, size_t data_len, size_t *decrypted_len)
  176. {
  177. u8 aad[2 + 30], nonce[12], *plain, *auth, *apos;
  178. u8 H[AES_BLOCK_SIZE];
  179. u8 J0[AES_BLOCK_SIZE];
  180. u8 S[16], T[16];
  181. size_t aad_len, padlen, mlen;
  182. void *aes;
  183. const u8 *m;
  184. if (data_len < 8 + 16)
  185. return NULL;
  186. plain = os_malloc(data_len + AES_BLOCK_SIZE);
  187. if (plain == NULL)
  188. return NULL;
  189. aes = aes_encrypt_init(tk, 16);
  190. if (aes == NULL) {
  191. os_free(plain);
  192. return NULL;
  193. }
  194. m = data + 8;
  195. mlen = data_len - 8 - 16;
  196. os_memset(aad, 0, sizeof(aad));
  197. gcmp_aad_nonce(hdr, data, &aad[2], &aad_len, nonce);
  198. WPA_PUT_BE16(aad, aad_len);
  199. wpa_hexdump(MSG_EXCESSIVE, "GCMP AAD", &aad[2], aad_len);
  200. wpa_hexdump(MSG_EXCESSIVE, "GCMP nonce", nonce, sizeof(nonce));
  201. /* GCM-AD_K(IV, C, A, T)
  202. *
  203. * IV = GCMP nonce
  204. * A = AAD
  205. * C | T = received frame
  206. */
  207. /* 2. Generate hash subkey H = AES_K(0^128) */
  208. os_memset(H, 0, sizeof(H));
  209. aes_encrypt(aes, H, H);
  210. wpa_hexdump(MSG_EXCESSIVE, "Hash subkey H for GHASH", H, sizeof(H));
  211. /* 3. Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */
  212. os_memcpy(J0, nonce, sizeof(nonce));
  213. os_memset(J0 + sizeof(nonce), 0, AES_BLOCK_SIZE - sizeof(nonce));
  214. J0[AES_BLOCK_SIZE - 1] = 0x01;
  215. /* 4. C = GCTR_K(inc_32(J_0), C) */
  216. inc32(J0);
  217. aes_gctr(aes, J0, m, mlen, plain);
  218. /*
  219. * 5. u = 128 * ceil[len(C)/128] - len(C)
  220. * v = 128 * ceil[len(A)/128] - len(A)
  221. * 6. S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64)
  222. * (i.e., zero padded to block size A || C and lengths of each in bits)
  223. */
  224. auth = os_malloc(32 + 16 + data_len - 16 + 8 + 8);
  225. if (auth == NULL) {
  226. os_free(plain);
  227. return NULL;
  228. }
  229. apos = auth;
  230. /* Zero-padded AAD */
  231. os_memcpy(apos, &aad[2], aad_len);
  232. apos += aad_len;
  233. padlen = (16 - aad_len % 16) % 16;
  234. os_memset(apos, 0, padlen);
  235. apos += padlen;
  236. /* Zero-padded C */
  237. os_memcpy(apos, m, mlen);
  238. apos += mlen;
  239. padlen = (16 - mlen % 16) % 16;
  240. os_memset(apos, 0, padlen);
  241. apos += padlen;
  242. /* Length of AAD and C in bits */
  243. WPA_PUT_BE64(apos, aad_len * 8);
  244. apos += 8;
  245. WPA_PUT_BE64(apos, mlen * 8);
  246. apos += 8;
  247. wpa_hexdump(MSG_EXCESSIVE, "GCMP GHASH_H input", auth, apos - auth);
  248. ghash(H, auth, apos - auth, S);
  249. wpa_hexdump(MSG_EXCESSIVE, "GCMP S = GHASH_H(...)", S, 16);
  250. os_free(auth);
  251. /* 7. T' = MSB_t(GCTR_K(J_0, S)) */
  252. J0[AES_BLOCK_SIZE - 1] = 0x01;
  253. aes_gctr(aes, J0, S, sizeof(S), T);
  254. aes_encrypt_deinit(aes);
  255. if (os_memcmp(data + data_len - 16, T, 16) != 0) {
  256. u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
  257. wpa_printf(MSG_INFO, "Invalid GCMP MIC in frame: A1=" MACSTR
  258. " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
  259. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  260. MAC2STR(hdr->addr3),
  261. WLAN_GET_SEQ_SEQ(seq_ctrl),
  262. WLAN_GET_SEQ_FRAG(seq_ctrl));
  263. wpa_hexdump(MSG_DEBUG, "GCMP decrypted", plain, data_len - 16);
  264. os_free(plain);
  265. return NULL;
  266. }
  267. *decrypted_len = data_len - 8 - 16;
  268. return plain;
  269. }
  270. u8 * gcmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
  271. u8 *pn, int keyid, size_t *encrypted_len)
  272. {
  273. u8 aad[2 + 30], nonce[12], *crypt, *pos, *auth, *apos;
  274. u8 H[AES_BLOCK_SIZE];
  275. u8 J0[AES_BLOCK_SIZE];
  276. u8 S[16];
  277. size_t aad_len, plen, padlen;
  278. struct ieee80211_hdr *hdr;
  279. void *aes;
  280. if (len < hdrlen || hdrlen < 24)
  281. return NULL;
  282. plen = len - hdrlen;
  283. crypt = os_malloc(hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE);
  284. if (crypt == NULL)
  285. return NULL;
  286. os_memcpy(crypt, frame, hdrlen);
  287. hdr = (struct ieee80211_hdr *) crypt;
  288. hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
  289. pos = crypt + hdrlen;
  290. *pos++ = pn[5]; /* PN0 */
  291. *pos++ = pn[4]; /* PN1 */
  292. *pos++ = 0x00; /* Rsvd */
  293. *pos++ = 0x20 | (keyid << 6);
  294. *pos++ = pn[3]; /* PN2 */
  295. *pos++ = pn[2]; /* PN3 */
  296. *pos++ = pn[1]; /* PN4 */
  297. *pos++ = pn[0]; /* PN5 */
  298. aes = aes_encrypt_init(tk, 16);
  299. if (aes == NULL) {
  300. os_free(crypt);
  301. return NULL;
  302. }
  303. os_memset(aad, 0, sizeof(aad));
  304. gcmp_aad_nonce(hdr, crypt + hdrlen, &aad[2], &aad_len, nonce);
  305. WPA_PUT_BE16(aad, aad_len);
  306. wpa_hexdump(MSG_EXCESSIVE, "GCMP AAD", &aad[2], aad_len);
  307. wpa_hexdump(MSG_EXCESSIVE, "GCMP nonce", nonce, sizeof(nonce));
  308. /* GCM-AE_K(IV, P, A)
  309. *
  310. * IV = GCMP nonce
  311. * A = AAD
  312. */
  313. /* 1. Generate hash subkey H = AES_K(0^128) */
  314. os_memset(H, 0, sizeof(H));
  315. aes_encrypt(aes, H, H);
  316. wpa_hexdump(MSG_EXCESSIVE, "Hash subkey H for GHASH", H, sizeof(H));
  317. /* 2. Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */
  318. os_memcpy(J0, nonce, sizeof(nonce));
  319. os_memset(J0 + sizeof(nonce), 0, AES_BLOCK_SIZE - sizeof(nonce));
  320. J0[AES_BLOCK_SIZE - 1] = 0x01;
  321. /* 3. C = GCTR_K(inc_32(J_0), P) */
  322. inc32(J0);
  323. aes_gctr(aes, J0, frame + hdrlen, len - hdrlen, pos);
  324. pos += len - hdrlen;
  325. /*
  326. * 4. u = 128 * ceil[len(C)/128] - len(C)
  327. * v = 128 * ceil[len(A)/128] - len(A)
  328. * 5. S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64)
  329. * (i.e., zero padded to block size A || C and lengths of each in bits)
  330. */
  331. auth = os_malloc(32 + 16 + len - hdrlen + 8 + 8);
  332. if (auth == NULL) {
  333. os_free(crypt);
  334. return NULL;
  335. }
  336. apos = auth;
  337. /* Zero-padded AAD */
  338. os_memcpy(apos, &aad[2], aad_len);
  339. apos += aad_len;
  340. padlen = (16 - aad_len % 16) % 16;
  341. os_memset(apos, 0, padlen);
  342. apos += padlen;
  343. /* Zero-padded C */
  344. os_memcpy(apos, crypt + hdrlen + 8, plen);
  345. apos += plen;
  346. padlen = (16 - plen % 16) % 16;
  347. os_memset(apos, 0, padlen);
  348. apos += padlen;
  349. /* Length of AAD and C in bits */
  350. WPA_PUT_BE64(apos, aad_len * 8);
  351. apos += 8;
  352. WPA_PUT_BE64(apos, plen * 8);
  353. apos += 8;
  354. wpa_hexdump(MSG_EXCESSIVE, "GCMP GHASH_H input", auth, apos - auth);
  355. ghash(H, auth, apos - auth, S);
  356. wpa_hexdump(MSG_EXCESSIVE, "GCMP S = GHASH_H(...)", S, 16);
  357. os_free(auth);
  358. /* 6. T = MSB_t(GCTR_K(J_0, S)) */
  359. J0[AES_BLOCK_SIZE - 1] = 0x01;
  360. aes_gctr(aes, J0, S, sizeof(S), pos);
  361. wpa_hexdump(MSG_EXCESSIVE, "GCMP MIC", pos, 16);
  362. /* 7. Return (C, T) */
  363. wpa_hexdump(MSG_EXCESSIVE, "GCMP encrypted", crypt + hdrlen + 8, plen);
  364. aes_encrypt_deinit(aes);
  365. *encrypted_len = hdrlen + 8 + plen + 16;
  366. return crypt;
  367. }