2 * Copyright 2003-2004, Instant802 Networks, Inc.
3 * Copyright 2005, Devicescape Software, Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 #include <linux/types.h>
11 #include <linux/netdevice.h>
13 #include <net/ieee80211.h>
14 #include "ieee80211_key.h"
19 static inline void aes_ccm_prepare(u32
*rk
, u8
*b_0
, u8
*aad
, u8
*b
,
24 ieee80211_aes_encrypt(rk
, b_0
, b
);
26 /* Extra Authenticate-only data (always two AES blocks) */
27 for (i
= 0; i
< AES_BLOCK_LEN
; i
++)
29 ieee80211_aes_encrypt(rk
, aad
, b
);
33 for (i
= 0; i
< AES_BLOCK_LEN
; i
++)
35 ieee80211_aes_encrypt(rk
, aad
, a
);
37 /* Mask out bits from auth-only-b_0 */
40 /* S_0 is used to encrypt T (= MIC) */
43 ieee80211_aes_encrypt(rk
, b_0
, s_0
);
47 void ieee80211_aes_ccm_encrypt(u32
*rk
, u8
*b_0
, u8
*aad
, u8
*data
,
48 size_t data_len
, u8
*cdata
, u8
*mic
)
50 int i
, j
, last_len
, num_blocks
;
52 u8 b
[AES_BLOCK_LEN
], s_0
[AES_BLOCK_LEN
], e
[AES_BLOCK_LEN
];
54 num_blocks
= (data_len
+ AES_BLOCK_LEN
- 1) / AES_BLOCK_LEN
;
55 last_len
= data_len
% AES_BLOCK_LEN
;
56 aes_ccm_prepare(rk
, b_0
, aad
, b
, s_0
, b
);
58 /* Process payload blocks */
61 for (j
= 1; j
<= num_blocks
; j
++) {
62 int blen
= (j
== num_blocks
&& last_len
) ?
63 last_len
: AES_BLOCK_LEN
;
65 /* Authentication followed by encryption */
66 for (i
= 0; i
< blen
; i
++)
68 ieee80211_aes_encrypt(rk
, b
, b
);
70 b_0
[14] = (j
>> 8) & 0xff;
72 ieee80211_aes_encrypt(rk
, b_0
, e
);
73 for (i
= 0; i
< blen
; i
++)
74 *cpos
++ = *pos
++ ^ e
[i
];
77 for (i
= 0; i
< CCMP_MIC_LEN
; i
++)
78 mic
[i
] = b
[i
] ^ s_0
[i
];
82 int ieee80211_aes_ccm_decrypt(u32
*rk
, u8
*b_0
, u8
*aad
, u8
*cdata
,
83 size_t data_len
, u8
*mic
, u8
*data
)
85 int i
, j
, last_len
, num_blocks
;
87 u8 b
[AES_BLOCK_LEN
], s_0
[AES_BLOCK_LEN
], a
[AES_BLOCK_LEN
];
89 num_blocks
= (data_len
+ AES_BLOCK_LEN
- 1) / AES_BLOCK_LEN
;
90 last_len
= data_len
% AES_BLOCK_LEN
;
91 aes_ccm_prepare(rk
, b_0
, aad
, b
, s_0
, a
);
93 /* Process payload blocks */
96 for (j
= 1; j
<= num_blocks
; j
++) {
97 int blen
= (j
== num_blocks
&& last_len
) ?
98 last_len
: AES_BLOCK_LEN
;
100 /* Decryption followed by authentication */
101 b_0
[14] = (j
>> 8) & 0xff;
103 ieee80211_aes_encrypt(rk
, b_0
, b
);
104 for (i
= 0; i
< blen
; i
++) {
105 *pos
= *cpos
++ ^ b
[i
];
109 ieee80211_aes_encrypt(rk
, a
, a
);
112 for (i
= 0; i
< CCMP_MIC_LEN
; i
++) {
113 if ((mic
[i
] ^ s_0
[i
]) != a
[i
])
This page took 0.056667 seconds and 5 git commands to generate.