2
0

100-remove-cryptoapi-dependencies.patch 18 KB

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