100-remove-cryptoapi-dependencies.patch 18 KB

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