100-remove-cryptoapi-dependencies.patch 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. --- a/net/mac80211/Makefile
  2. +++ b/net/mac80211/Makefile
  3. @@ -7,7 +7,6 @@ mac80211-y := \
  4. driver-ops.o \
  5. sta_info.o \
  6. wep.o \
  7. - aead_api.o \
  8. wpa.o \
  9. scan.o offchannel.o \
  10. ht.o agg-tx.o agg-rx.o \
  11. @@ -19,8 +18,8 @@ mac80211-y := \
  12. rate.o \
  13. michael.o \
  14. tkip.o \
  15. + aes_ccm.o \
  16. aes_cmac.o \
  17. - aes_gmac.o \
  18. fils_aead.o \
  19. cfg.o \
  20. ethtool.o \
  21. --- a/net/mac80211/aead_api.c
  22. +++ /dev/null
  23. @@ -1,113 +0,0 @@
  24. -// SPDX-License-Identifier: GPL-2.0-only
  25. -/*
  26. - * Copyright 2003-2004, Instant802 Networks, Inc.
  27. - * Copyright 2005-2006, Devicescape Software, Inc.
  28. - * Copyright 2014-2015, Qualcomm Atheros, Inc.
  29. - *
  30. - * Rewrite: Copyright (C) 2013 Linaro Ltd <[email protected]>
  31. - */
  32. -
  33. -#include <linux/kernel.h>
  34. -#include <linux/types.h>
  35. -#include <linux/err.h>
  36. -#include <linux/scatterlist.h>
  37. -#include <crypto/aead.h>
  38. -
  39. -#include "aead_api.h"
  40. -
  41. -int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
  42. - u8 *data, size_t data_len, u8 *mic)
  43. -{
  44. - size_t mic_len = crypto_aead_authsize(tfm);
  45. - struct scatterlist sg[3];
  46. - struct aead_request *aead_req;
  47. - int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
  48. - u8 *__aad;
  49. - int ret;
  50. -
  51. - aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
  52. - if (!aead_req)
  53. - return -ENOMEM;
  54. -
  55. - __aad = (u8 *)aead_req + reqsize;
  56. - memcpy(__aad, aad, aad_len);
  57. -
  58. - sg_init_table(sg, 3);
  59. - sg_set_buf(&sg[0], __aad, aad_len);
  60. - sg_set_buf(&sg[1], data, data_len);
  61. - sg_set_buf(&sg[2], mic, mic_len);
  62. -
  63. - aead_request_set_tfm(aead_req, tfm);
  64. - aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
  65. - aead_request_set_ad(aead_req, sg[0].length);
  66. -
  67. - ret = crypto_aead_encrypt(aead_req);
  68. - kfree_sensitive(aead_req);
  69. -
  70. - return ret;
  71. -}
  72. -
  73. -int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
  74. - u8 *data, size_t data_len, u8 *mic)
  75. -{
  76. - size_t mic_len = crypto_aead_authsize(tfm);
  77. - struct scatterlist sg[3];
  78. - struct aead_request *aead_req;
  79. - int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
  80. - u8 *__aad;
  81. - int err;
  82. -
  83. - if (data_len == 0)
  84. - return -EINVAL;
  85. -
  86. - aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
  87. - if (!aead_req)
  88. - return -ENOMEM;
  89. -
  90. - __aad = (u8 *)aead_req + reqsize;
  91. - memcpy(__aad, aad, aad_len);
  92. -
  93. - sg_init_table(sg, 3);
  94. - sg_set_buf(&sg[0], __aad, aad_len);
  95. - sg_set_buf(&sg[1], data, data_len);
  96. - sg_set_buf(&sg[2], mic, mic_len);
  97. -
  98. - aead_request_set_tfm(aead_req, tfm);
  99. - aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
  100. - aead_request_set_ad(aead_req, sg[0].length);
  101. -
  102. - err = crypto_aead_decrypt(aead_req);
  103. - kfree_sensitive(aead_req);
  104. -
  105. - return err;
  106. -}
  107. -
  108. -struct crypto_aead *
  109. -aead_key_setup_encrypt(const char *alg, const u8 key[],
  110. - size_t key_len, size_t mic_len)
  111. -{
  112. - struct crypto_aead *tfm;
  113. - int err;
  114. -
  115. - tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC);
  116. - if (IS_ERR(tfm))
  117. - return tfm;
  118. -
  119. - err = crypto_aead_setkey(tfm, key, key_len);
  120. - if (err)
  121. - goto free_aead;
  122. - err = crypto_aead_setauthsize(tfm, mic_len);
  123. - if (err)
  124. - goto free_aead;
  125. -
  126. - return tfm;
  127. -
  128. -free_aead:
  129. - crypto_free_aead(tfm);
  130. - return ERR_PTR(err);
  131. -}
  132. -
  133. -void aead_key_free(struct crypto_aead *tfm)
  134. -{
  135. - crypto_free_aead(tfm);
  136. -}
  137. --- a/net/mac80211/aead_api.h
  138. +++ /dev/null
  139. @@ -1,23 +0,0 @@
  140. -/* SPDX-License-Identifier: GPL-2.0-only */
  141. -
  142. -#ifndef _AEAD_API_H
  143. -#define _AEAD_API_H
  144. -
  145. -#include <crypto/aead.h>
  146. -#include <linux/crypto.h>
  147. -
  148. -struct crypto_aead *
  149. -aead_key_setup_encrypt(const char *alg, const u8 key[],
  150. - size_t key_len, size_t mic_len);
  151. -
  152. -int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
  153. - size_t aad_len, u8 *data,
  154. - size_t data_len, u8 *mic);
  155. -
  156. -int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
  157. - size_t aad_len, u8 *data,
  158. - size_t data_len, u8 *mic);
  159. -
  160. -void aead_key_free(struct crypto_aead *tfm);
  161. -
  162. -#endif /* _AEAD_API_H */
  163. --- a/net/mac80211/aes_ccm.h
  164. +++ b/net/mac80211/aes_ccm.h
  165. @@ -7,39 +7,17 @@
  166. #ifndef AES_CCM_H
  167. #define AES_CCM_H
  168. -#include "aead_api.h"
  169. +#include <linux/crypto.h>
  170. -#define CCM_AAD_LEN 32
  171. -
  172. -static inline struct crypto_aead *
  173. -ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len)
  174. -{
  175. - return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len);
  176. -}
  177. -
  178. -static inline int
  179. -ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm,
  180. - u8 *b_0, u8 *aad, u8 *data,
  181. - size_t data_len, u8 *mic)
  182. -{
  183. - return aead_encrypt(tfm, b_0, aad + 2,
  184. - be16_to_cpup((__be16 *)aad),
  185. - data, data_len, mic);
  186. -}
  187. -
  188. -static inline int
  189. -ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm,
  190. - u8 *b_0, u8 *aad, u8 *data,
  191. - size_t data_len, u8 *mic)
  192. -{
  193. - return aead_decrypt(tfm, b_0, aad + 2,
  194. - be16_to_cpup((__be16 *)aad),
  195. - data, data_len, mic);
  196. -}
  197. -
  198. -static inline void ieee80211_aes_key_free(struct crypto_aead *tfm)
  199. -{
  200. - return aead_key_free(tfm);
  201. -}
  202. +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
  203. + size_t key_len,
  204. + size_t mic_len);
  205. +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
  206. + u8 *data, size_t data_len, u8 *mic,
  207. + size_t mic_len);
  208. +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
  209. + u8 *data, size_t data_len, u8 *mic,
  210. + size_t mic_len);
  211. +void ieee80211_aes_key_free(struct crypto_cipher *tfm);
  212. #endif /* AES_CCM_H */
  213. --- /dev/null
  214. +++ b/net/mac80211/aes_gcm.c
  215. @@ -0,0 +1,109 @@
  216. +/*
  217. + * Copyright 2014-2015, Qualcomm Atheros, Inc.
  218. + *
  219. + * This program is free software; you can redistribute it and/or modify
  220. + * it under the terms of the GNU General Public License version 2 as
  221. + * published by the Free Software Foundation.
  222. + */
  223. +
  224. +#include <linux/kernel.h>
  225. +#include <linux/types.h>
  226. +#include <linux/err.h>
  227. +#include <crypto/aead.h>
  228. +
  229. +#include <net/mac80211.h>
  230. +#include "key.h"
  231. +#include "aes_gcm.h"
  232. +
  233. +int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
  234. + u8 *data, size_t data_len, u8 *mic)
  235. +{
  236. + struct scatterlist sg[3];
  237. + struct aead_request *aead_req;
  238. + int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
  239. + u8 *__aad;
  240. +
  241. + aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
  242. + if (!aead_req)
  243. + return -ENOMEM;
  244. +
  245. + __aad = (u8 *)aead_req + reqsize;
  246. + memcpy(__aad, aad, GCM_AAD_LEN);
  247. +
  248. + sg_init_table(sg, 3);
  249. + sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
  250. + sg_set_buf(&sg[1], data, data_len);
  251. + sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
  252. +
  253. + aead_request_set_tfm(aead_req, tfm);
  254. + aead_request_set_crypt(aead_req, sg, sg, data_len, j_0);
  255. + aead_request_set_ad(aead_req, sg[0].length);
  256. +
  257. + crypto_aead_encrypt(aead_req);
  258. + kzfree(aead_req);
  259. + return 0;
  260. +}
  261. +
  262. +int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
  263. + u8 *data, size_t data_len, u8 *mic)
  264. +{
  265. + struct scatterlist sg[3];
  266. + struct aead_request *aead_req;
  267. + int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
  268. + u8 *__aad;
  269. + int err;
  270. +
  271. + if (data_len == 0)
  272. + return -EINVAL;
  273. +
  274. + aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
  275. + if (!aead_req)
  276. + return -ENOMEM;
  277. +
  278. + __aad = (u8 *)aead_req + reqsize;
  279. + memcpy(__aad, aad, GCM_AAD_LEN);
  280. +
  281. + sg_init_table(sg, 3);
  282. + sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
  283. + sg_set_buf(&sg[1], data, data_len);
  284. + sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
  285. +
  286. + aead_request_set_tfm(aead_req, tfm);
  287. + aead_request_set_crypt(aead_req, sg, sg,
  288. + data_len + IEEE80211_GCMP_MIC_LEN, j_0);
  289. + aead_request_set_ad(aead_req, sg[0].length);
  290. +
  291. + err = crypto_aead_decrypt(aead_req);
  292. + kzfree(aead_req);
  293. +
  294. + return err;
  295. +}
  296. +
  297. +struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
  298. + size_t key_len)
  299. +{
  300. + struct crypto_aead *tfm;
  301. + int err;
  302. +
  303. + tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
  304. + if (IS_ERR(tfm))
  305. + return tfm;
  306. +
  307. + err = crypto_aead_setkey(tfm, key, key_len);
  308. + if (err)
  309. + goto free_aead;
  310. + err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
  311. + if (err)
  312. + goto free_aead;
  313. +
  314. + return tfm;
  315. +
  316. +free_aead:
  317. + crypto_free_aead(tfm);
  318. + return ERR_PTR(err);
  319. +}
  320. +
  321. +void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
  322. +{
  323. + crypto_free_aead(tfm);
  324. +}
  325. --- a/net/mac80211/aes_gcm.h
  326. +++ b/net/mac80211/aes_gcm.h
  327. @@ -6,38 +6,30 @@
  328. #ifndef AES_GCM_H
  329. #define AES_GCM_H
  330. -#include "aead_api.h"
  331. +#include <linux/crypto.h>
  332. -#define GCM_AAD_LEN 32
  333. -
  334. -static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm,
  335. - u8 *j_0, u8 *aad, u8 *data,
  336. - size_t data_len, u8 *mic)
  337. +static inline void
  338. +ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
  339. + u8 *data, size_t data_len, u8 *mic)
  340. {
  341. - return aead_encrypt(tfm, j_0, aad + 2,
  342. - be16_to_cpup((__be16 *)aad),
  343. - data, data_len, mic);
  344. }
  345. -static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm,
  346. - u8 *j_0, u8 *aad, u8 *data,
  347. - size_t data_len, u8 *mic)
  348. +static inline int
  349. +ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
  350. + u8 *data, size_t data_len, u8 *mic)
  351. {
  352. - return aead_decrypt(tfm, j_0, aad + 2,
  353. - be16_to_cpup((__be16 *)aad),
  354. - data, data_len, mic);
  355. + return -EOPNOTSUPP;
  356. }
  357. static inline struct crypto_aead *
  358. ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
  359. {
  360. - return aead_key_setup_encrypt("gcm(aes)", key,
  361. - key_len, IEEE80211_GCMP_MIC_LEN);
  362. + return NULL;
  363. }
  364. -static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
  365. +static inline void
  366. +ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
  367. {
  368. - return aead_key_free(tfm);
  369. }
  370. #endif /* AES_GCM_H */
  371. --- a/net/mac80211/wpa.c
  372. +++ b/net/mac80211/wpa.c
  373. @@ -311,7 +311,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
  374. }
  375. -static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
  376. +static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
  377. + u16 data_len)
  378. {
  379. __le16 mask_fc;
  380. int a4_included, mgmt;
  381. @@ -341,14 +342,8 @@ static void ccmp_special_blocks(struct s
  382. else
  383. qos_tid = 0;
  384. - /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
  385. - * mode authentication are not allowed to collide, yet both are derived
  386. - * from this vector b_0. We only set L := 1 here to indicate that the
  387. - * data size can be represented in (L+1) bytes. The CCM layer will take
  388. - * care of storing the data length in the top (L+1) bytes and setting
  389. - * and clearing the other bits as is required to derive the two IVs.
  390. - */
  391. - b_0[0] = 0x1;
  392. + /* First block, b_0 */
  393. + b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
  394. /* Nonce: Nonce Flags | A2 | PN
  395. * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
  396. @@ -356,6 +351,8 @@ static void ccmp_special_blocks(struct s
  397. b_0[1] = qos_tid | (mgmt << 4);
  398. memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
  399. memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
  400. + /* l(m) */
  401. + put_unaligned_be16(data_len, &b_0[14]);
  402. /* AAD (extra authenticate-only data) / masked 802.11 header
  403. * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
  404. @@ -412,7 +409,7 @@ static int ccmp_encrypt_skb(struct ieee8
  405. u8 *pos;
  406. u8 pn[6];
  407. u64 pn64;
  408. - u8 aad[CCM_AAD_LEN];
  409. + u8 aad[2 * AES_BLOCK_SIZE];
  410. u8 b_0[AES_BLOCK_SIZE];
  411. if (info->control.hw_key &&
  412. @@ -467,9 +464,11 @@ static int ccmp_encrypt_skb(struct ieee8
  413. return 0;
  414. pos += IEEE80211_CCMP_HDR_LEN;
  415. - ccmp_special_blocks(skb, pn, b_0, aad);
  416. - return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
  417. - skb_put(skb, mic_len));
  418. + ccmp_special_blocks(skb, pn, b_0, aad, len);
  419. + ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
  420. + skb_put(skb, mic_len), mic_len);
  421. +
  422. + return 0;
  423. }
  424. @@ -542,13 +541,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee
  425. u8 aad[2 * AES_BLOCK_SIZE];
  426. u8 b_0[AES_BLOCK_SIZE];
  427. /* hardware didn't decrypt/verify MIC */
  428. - ccmp_special_blocks(skb, pn, b_0, aad);
  429. + ccmp_special_blocks(skb, pn, b_0, aad, data_len);
  430. if (ieee80211_aes_ccm_decrypt(
  431. key->u.ccmp.tfm, b_0, aad,
  432. skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
  433. data_len,
  434. - skb->data + skb->len - mic_len))
  435. + skb->data + skb->len - mic_len, mic_len))
  436. return RX_DROP_UNUSABLE;
  437. }
  438. @@ -643,7 +642,7 @@ static int gcmp_encrypt_skb(struct ieee8
  439. u8 *pos;
  440. u8 pn[6];
  441. u64 pn64;
  442. - u8 aad[GCM_AAD_LEN];
  443. + u8 aad[2 * AES_BLOCK_SIZE];
  444. u8 j_0[AES_BLOCK_SIZE];
  445. if (info->control.hw_key &&
  446. @@ -700,8 +699,10 @@ static int gcmp_encrypt_skb(struct ieee8
  447. pos += IEEE80211_GCMP_HDR_LEN;
  448. gcmp_special_blocks(skb, pn, j_0, aad);
  449. - return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
  450. - skb_put(skb, IEEE80211_GCMP_MIC_LEN));
  451. + ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
  452. + skb_put(skb, IEEE80211_GCMP_MIC_LEN));
  453. +
  454. + return 0;
  455. }
  456. ieee80211_tx_result
  457. @@ -1128,9 +1129,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct
  458. struct ieee80211_key *key = tx->key;
  459. struct ieee80211_mmie_16 *mmie;
  460. struct ieee80211_hdr *hdr;
  461. - u8 aad[GMAC_AAD_LEN];
  462. + u8 aad[20];
  463. u64 pn64;
  464. - u8 nonce[GMAC_NONCE_LEN];
  465. + u8 nonce[12];
  466. if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
  467. return TX_DROP;
  468. @@ -1176,7 +1177,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct
  469. struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
  470. struct ieee80211_key *key = rx->key;
  471. struct ieee80211_mmie_16 *mmie;
  472. - u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN];
  473. + u8 aad[20], *mic, ipn[6], nonce[12];
  474. struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
  475. if (!ieee80211_is_mgmt(hdr->frame_control))
  476. --- /dev/null
  477. +++ b/net/mac80211/aes_ccm.c
  478. @@ -0,0 +1,144 @@
  479. +/*
  480. + * Copyright 2003-2004, Instant802 Networks, Inc.
  481. + * Copyright 2005-2006, Devicescape Software, Inc.
  482. + *
  483. + * Rewrite: Copyright (C) 2013 Linaro Ltd <[email protected]>
  484. + *
  485. + * This program is free software; you can redistribute it and/or modify
  486. + * it under the terms of the GNU General Public License version 2 as
  487. + * published by the Free Software Foundation.
  488. + */
  489. +
  490. +#include <linux/kernel.h>
  491. +#include <linux/types.h>
  492. +#include <linux/err.h>
  493. +#include <crypto/aead.h>
  494. +#include <crypto/aes.h>
  495. +
  496. +#include <net/mac80211.h>
  497. +#include "key.h"
  498. +#include "aes_ccm.h"
  499. +
  500. +static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0,
  501. + u8 *a, u8 *b)
  502. +{
  503. + int i;
  504. +
  505. + crypto_cipher_encrypt_one(tfm, b, b_0);
  506. +
  507. + /* Extra Authenticate-only data (always two AES blocks) */
  508. + for (i = 0; i < AES_BLOCK_SIZE; i++)
  509. + aad[i] ^= b[i];
  510. + crypto_cipher_encrypt_one(tfm, b, aad);
  511. +
  512. + aad += AES_BLOCK_SIZE;
  513. +
  514. + for (i = 0; i < AES_BLOCK_SIZE; i++)
  515. + aad[i] ^= b[i];
  516. + crypto_cipher_encrypt_one(tfm, a, aad);
  517. +
  518. + /* Mask out bits from auth-only-b_0 */
  519. + b_0[0] &= 0x07;
  520. +
  521. + /* S_0 is used to encrypt T (= MIC) */
  522. + b_0[14] = 0;
  523. + b_0[15] = 0;
  524. + crypto_cipher_encrypt_one(tfm, s_0, b_0);
  525. +}
  526. +
  527. +
  528. +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
  529. + u8 *data, size_t data_len, u8 *mic,
  530. + size_t mic_len)
  531. +{
  532. + int i, j, last_len, num_blocks;
  533. + u8 b[AES_BLOCK_SIZE];
  534. + u8 s_0[AES_BLOCK_SIZE];
  535. + u8 e[AES_BLOCK_SIZE];
  536. + u8 *pos, *cpos;
  537. +
  538. + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
  539. + last_len = data_len % AES_BLOCK_SIZE;
  540. + aes_ccm_prepare(tfm, b_0, aad, s_0, b, b);
  541. +
  542. + /* Process payload blocks */
  543. + pos = data;
  544. + cpos = data;
  545. + for (j = 1; j <= num_blocks; j++) {
  546. + int blen = (j == num_blocks && last_len) ?
  547. + last_len : AES_BLOCK_SIZE;
  548. +
  549. + /* Authentication followed by encryption */
  550. + for (i = 0; i < blen; i++)
  551. + b[i] ^= pos[i];
  552. + crypto_cipher_encrypt_one(tfm, b, b);
  553. +
  554. + b_0[14] = (j >> 8) & 0xff;
  555. + b_0[15] = j & 0xff;
  556. + crypto_cipher_encrypt_one(tfm, e, b_0);
  557. + for (i = 0; i < blen; i++)
  558. + *cpos++ = *pos++ ^ e[i];
  559. + }
  560. +
  561. + for (i = 0; i < mic_len; i++)
  562. + mic[i] = b[i] ^ s_0[i];
  563. +}
  564. +
  565. +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
  566. + u8 *data, size_t data_len, u8 *mic,
  567. + size_t mic_len)
  568. +{
  569. + int i, j, last_len, num_blocks;
  570. + u8 *pos, *cpos;
  571. + u8 a[AES_BLOCK_SIZE];
  572. + u8 b[AES_BLOCK_SIZE];
  573. + u8 s_0[AES_BLOCK_SIZE];
  574. +
  575. + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
  576. + last_len = data_len % AES_BLOCK_SIZE;
  577. + aes_ccm_prepare(tfm, b_0, aad, s_0, a, b);
  578. +
  579. + /* Process payload blocks */
  580. + cpos = data;
  581. + pos = data;
  582. + for (j = 1; j <= num_blocks; j++) {
  583. + int blen = (j == num_blocks && last_len) ?
  584. + last_len : AES_BLOCK_SIZE;
  585. +
  586. + /* Decryption followed by authentication */
  587. + b_0[14] = (j >> 8) & 0xff;
  588. + b_0[15] = j & 0xff;
  589. + crypto_cipher_encrypt_one(tfm, b, b_0);
  590. + for (i = 0; i < blen; i++) {
  591. + *pos = *cpos++ ^ b[i];
  592. + a[i] ^= *pos++;
  593. + }
  594. + crypto_cipher_encrypt_one(tfm, a, a);
  595. + }
  596. +
  597. + for (i = 0; i < mic_len; i++) {
  598. + if ((mic[i] ^ s_0[i]) != a[i])
  599. + return -1;
  600. + }
  601. +
  602. + return 0;
  603. +}
  604. +
  605. +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
  606. + size_t key_len,
  607. + size_t mic_len)
  608. +{
  609. + struct crypto_cipher *tfm;
  610. +
  611. + tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
  612. + if (!IS_ERR(tfm))
  613. + crypto_cipher_setkey(tfm, key, key_len);
  614. +
  615. + return tfm;
  616. +}
  617. +
  618. +
  619. +void ieee80211_aes_key_free(struct crypto_cipher *tfm)
  620. +{
  621. + crypto_free_cipher(tfm);
  622. +}
  623. --- a/net/mac80211/Kconfig
  624. +++ b/net/mac80211/Kconfig
  625. @@ -6,8 +6,6 @@ config MAC80211
  626. depends on CRYPTO
  627. select BPAUTO_CRYPTO_LIB_ARC4
  628. depends on CRYPTO_AES
  629. - depends on CRYPTO_CCM
  630. - depends on CRYPTO_GCM
  631. depends on CRYPTO_CMAC
  632. depends on CRC32
  633. help
  634. --- a/net/mac80211/aes_gmac.h
  635. +++ b/net/mac80211/aes_gmac.h
  636. @@ -12,10 +12,22 @@
  637. #define GMAC_MIC_LEN 16
  638. #define GMAC_NONCE_LEN 12
  639. -struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
  640. - size_t key_len);
  641. -int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
  642. - const u8 *data, size_t data_len, u8 *mic);
  643. -void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
  644. +static inline struct crypto_aead *
  645. +ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len)
  646. +{
  647. + return NULL;
  648. +}
  649. +
  650. +static inline int
  651. +ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
  652. + const u8 *data, size_t data_len, u8 *mic)
  653. +{
  654. + return -EOPNOTSUPP;
  655. +}
  656. +
  657. +static inline void
  658. +ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
  659. +{
  660. +}
  661. #endif /* AES_GMAC_H */
  662. --- a/net/mac80211/key.h
  663. +++ b/net/mac80211/key.h
  664. @@ -89,7 +89,7 @@ struct ieee80211_key {
  665. * Management frames.
  666. */
  667. u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
  668. - struct crypto_aead *tfm;
  669. + struct crypto_cipher *tfm;
  670. u32 replays; /* dot11RSNAStatsCCMPReplays */
  671. } ccmp;
  672. struct {