31
31
* funneled through AES are...16 bytes in size!
32
32
*/
33
33
34
+ #include <crypto/aes.h>
35
+ #include <crypto/algapi.h>
36
+ #include <crypto/hash.h>
34
37
#include <crypto/skcipher.h>
35
38
#include <linux/crypto.h>
36
39
#include <linux/module.h>
@@ -109,16 +112,6 @@ struct aes_ccm_a {
109
112
__be16 counter ; /* Value of x */
110
113
} __attribute__((packed ));
111
114
112
- static void bytewise_xor (void * _bo , const void * _bi1 , const void * _bi2 ,
113
- size_t size )
114
- {
115
- u8 * bo = _bo ;
116
- const u8 * bi1 = _bi1 , * bi2 = _bi2 ;
117
- size_t itr ;
118
- for (itr = 0 ; itr < size ; itr ++ )
119
- bo [itr ] = bi1 [itr ] ^ bi2 [itr ];
120
- }
121
-
122
115
/* Scratch space for MAC calculations. */
123
116
struct wusb_mac_scratch {
124
117
struct aes_ccm_b0 b0 ;
@@ -150,8 +143,7 @@ struct wusb_mac_scratch {
150
143
* @a: ASCII string, 14 bytes long (I guess zero padded if needed;
151
144
* we use exactly 14 bytes).
152
145
*
153
- * @b: data stream to be processed; cannot be a global or const local
154
- * (will confuse the scatterlists)
146
+ * @b: data stream to be processed
155
147
*
156
148
* @blen: size of b...
157
149
*
@@ -160,16 +152,10 @@ struct wusb_mac_scratch {
160
152
* @key. We bytewise xor B0 with B1 (1) and AES-crypt that. Then we
161
153
* take the payload and divide it in blocks (16 bytes), xor them with
162
154
* the previous crypto result (16 bytes) and crypt it, repeat the next
163
- * block with the output of the previous one, rinse wash (I guess this
164
- * is what AES CBC mode means...but I truly have no idea). So we use
165
- * the CBC(AES) blkcipher, that does precisely that. The IV (Initial
155
+ * block with the output of the previous one, rinse wash. So we use
156
+ * the CBC-MAC(AES) shash, that does precisely that. The IV (Initial
166
157
* Vector) is 16 bytes and is set to zero, so
167
158
*
168
- * See rfc3610. Linux crypto has a CBC implementation, but the
169
- * documentation is scarce, to say the least, and the example code is
170
- * so intricated that is difficult to understand how things work. Most
171
- * of this is guess work -- bite me.
172
- *
173
159
* (1) Created as 6.5 says, again, using as l(a) 'Blen + 14', and
174
160
* using the 14 bytes of @a to fill up
175
161
* b1.{mac_header,e0,security_reserved,padding}.
@@ -189,44 +175,24 @@ struct wusb_mac_scratch {
189
175
* NOTE: blen is not aligned to a block size, we'll pad zeros, that's
190
176
* what sg[4] is for. Maybe there is a smarter way to do this.
191
177
*/
192
- static int wusb_ccm_mac (struct crypto_sync_skcipher * tfm_cbc ,
193
- struct crypto_cipher * tfm_aes ,
178
+ static int wusb_ccm_mac (struct crypto_shash * tfm_cbcmac ,
194
179
struct wusb_mac_scratch * scratch ,
195
180
void * mic ,
196
181
const struct aes_ccm_nonce * n ,
197
182
const struct aes_ccm_label * a , const void * b ,
198
183
size_t blen )
199
184
{
200
- int result = 0 ;
201
- SYNC_SKCIPHER_REQUEST_ON_STACK (req , tfm_cbc );
202
- struct scatterlist sg [4 ], sg_dst ;
203
- void * dst_buf ;
204
- size_t dst_size ;
205
- u8 * iv ;
206
- size_t zero_padding ;
185
+ SHASH_DESC_ON_STACK (desc , tfm_cbcmac );
186
+ u8 iv [AES_BLOCK_SIZE ];
207
187
208
188
/*
209
189
* These checks should be compile time optimized out
210
190
* ensure @a fills b1's mac_header and following fields
211
191
*/
212
- WARN_ON (sizeof (* a ) != sizeof (scratch -> b1 ) - sizeof (scratch -> b1 .la ));
213
- WARN_ON (sizeof (scratch -> b0 ) != sizeof (struct aes_ccm_block ));
214
- WARN_ON (sizeof (scratch -> b1 ) != sizeof (struct aes_ccm_block ));
215
- WARN_ON (sizeof (scratch -> ax ) != sizeof (struct aes_ccm_block ));
216
-
217
- result = - ENOMEM ;
218
- zero_padding = blen % sizeof (struct aes_ccm_block );
219
- if (zero_padding )
220
- zero_padding = sizeof (struct aes_ccm_block ) - zero_padding ;
221
- dst_size = blen + sizeof (scratch -> b0 ) + sizeof (scratch -> b1 ) +
222
- zero_padding ;
223
- dst_buf = kzalloc (dst_size , GFP_KERNEL );
224
- if (!dst_buf )
225
- goto error_dst_buf ;
226
-
227
- iv = kzalloc (crypto_sync_skcipher_ivsize (tfm_cbc ), GFP_KERNEL );
228
- if (!iv )
229
- goto error_iv ;
192
+ BUILD_BUG_ON (sizeof (* a ) != sizeof (scratch -> b1 ) - sizeof (scratch -> b1 .la ));
193
+ BUILD_BUG_ON (sizeof (scratch -> b0 ) != sizeof (struct aes_ccm_block ));
194
+ BUILD_BUG_ON (sizeof (scratch -> b1 ) != sizeof (struct aes_ccm_block ));
195
+ BUILD_BUG_ON (sizeof (scratch -> ax ) != sizeof (struct aes_ccm_block ));
230
196
231
197
/* Setup B0 */
232
198
scratch -> b0 .flags = 0x59 ; /* Format B0 */
@@ -243,46 +209,28 @@ static int wusb_ccm_mac(struct crypto_sync_skcipher *tfm_cbc,
243
209
scratch -> b1 .la = cpu_to_be16 (blen + 14 );
244
210
memcpy (& scratch -> b1 .mac_header , a , sizeof (* a ));
245
211
246
- sg_init_table (sg , ARRAY_SIZE (sg ));
247
- sg_set_buf (& sg [0 ], & scratch -> b0 , sizeof (scratch -> b0 ));
248
- sg_set_buf (& sg [1 ], & scratch -> b1 , sizeof (scratch -> b1 ));
249
- sg_set_buf (& sg [2 ], b , blen );
250
- /* 0 if well behaved :) */
251
- sg_set_page (& sg [3 ], ZERO_PAGE (0 ), zero_padding , 0 );
252
- sg_init_one (& sg_dst , dst_buf , dst_size );
253
-
254
- skcipher_request_set_sync_tfm (req , tfm_cbc );
255
- skcipher_request_set_callback (req , 0 , NULL , NULL );
256
- skcipher_request_set_crypt (req , sg , & sg_dst , dst_size , iv );
257
- result = crypto_skcipher_encrypt (req );
258
- skcipher_request_zero (req );
259
- if (result < 0 ) {
260
- printk (KERN_ERR "E: can't compute CBC-MAC tag (MIC): %d\n" ,
261
- result );
262
- goto error_cbc_crypt ;
263
- }
212
+ desc -> tfm = tfm_cbcmac ;
213
+ crypto_shash_init (desc );
214
+ crypto_shash_update (desc , (u8 * )& scratch -> b0 , sizeof (scratch -> b0 ) +
215
+ sizeof (scratch -> b1 ));
216
+ crypto_shash_finup (desc , b , blen , iv );
264
217
265
218
/* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5]
266
219
* The procedure is to AES crypt the A0 block and XOR the MIC
267
220
* Tag against it; we only do the first 8 bytes and place it
268
221
* directly in the destination buffer.
269
- *
270
- * POS Crypto API: size is assumed to be AES's block size.
271
- * Thanks for documenting it -- tip taken from airo.c
272
222
*/
273
223
scratch -> ax .flags = 0x01 ; /* as per WUSB 1.0 spec */
274
224
scratch -> ax .ccm_nonce = * n ;
275
225
scratch -> ax .counter = 0 ;
276
- crypto_cipher_encrypt_one (tfm_aes , (void * )& scratch -> ax ,
277
- (void * )& scratch -> ax );
278
- bytewise_xor (mic , & scratch -> ax , iv , 8 );
279
- result = 8 ;
280
- error_cbc_crypt :
281
- kfree (iv );
282
- error_iv :
283
- kfree (dst_buf );
284
- error_dst_buf :
285
- return result ;
226
+
227
+ /* reuse the CBC-MAC transform to perform the single block encryption */
228
+ crypto_shash_digest (desc , (u8 * )& scratch -> ax , sizeof (scratch -> ax ),
229
+ (u8 * )& scratch -> ax );
230
+
231
+ crypto_xor_cpy (mic , (u8 * )& scratch -> ax , iv , 8 );
232
+
233
+ return 8 ;
286
234
}
287
235
288
236
/*
@@ -298,61 +246,39 @@ ssize_t wusb_prf(void *out, size_t out_size,
298
246
{
299
247
ssize_t result , bytes = 0 , bitr ;
300
248
struct aes_ccm_nonce n = * _n ;
301
- struct crypto_sync_skcipher * tfm_cbc ;
302
- struct crypto_cipher * tfm_aes ;
303
- struct wusb_mac_scratch * scratch ;
249
+ struct crypto_shash * tfm_cbcmac ;
250
+ struct wusb_mac_scratch scratch ;
304
251
u64 sfn = 0 ;
305
252
__le64 sfn_le ;
306
253
307
- tfm_cbc = crypto_alloc_sync_skcipher ("cbc(aes)" , 0 , 0 );
308
- if (IS_ERR (tfm_cbc )) {
309
- result = PTR_ERR (tfm_cbc );
310
- printk (KERN_ERR "E: can't load CBC(AES): %d\n" , (int )result );
311
- goto error_alloc_cbc ;
312
- }
313
- result = crypto_sync_skcipher_setkey (tfm_cbc , key , 16 );
314
- if (result < 0 ) {
315
- printk (KERN_ERR "E: can't set CBC key: %d\n" , (int )result );
316
- goto error_setkey_cbc ;
254
+ tfm_cbcmac = crypto_alloc_shash ("cbcmac(aes)" , 0 , 0 );
255
+ if (IS_ERR (tfm_cbcmac )) {
256
+ result = PTR_ERR (tfm_cbcmac );
257
+ printk (KERN_ERR "E: can't load CBCMAC-AES: %d\n" , (int )result );
258
+ goto error_alloc_cbcmac ;
317
259
}
318
260
319
- tfm_aes = crypto_alloc_cipher ("aes" , 0 , 0 );
320
- if (IS_ERR (tfm_aes )) {
321
- result = PTR_ERR (tfm_aes );
322
- printk (KERN_ERR "E: can't load AES: %d\n" , (int )result );
323
- goto error_alloc_aes ;
324
- }
325
- result = crypto_cipher_setkey (tfm_aes , key , 16 );
261
+ result = crypto_shash_setkey (tfm_cbcmac , key , AES_BLOCK_SIZE );
326
262
if (result < 0 ) {
327
- printk (KERN_ERR "E: can't set AES key: %d\n" , (int )result );
328
- goto error_setkey_aes ;
329
- }
330
- scratch = kmalloc (sizeof (* scratch ), GFP_KERNEL );
331
- if (!scratch ) {
332
- result = - ENOMEM ;
333
- goto error_alloc_scratch ;
263
+ printk (KERN_ERR "E: can't set CBCMAC-AES key: %d\n" , (int )result );
264
+ goto error_setkey_cbcmac ;
334
265
}
335
266
336
267
for (bitr = 0 ; bitr < (len + 63 ) / 64 ; bitr ++ ) {
337
268
sfn_le = cpu_to_le64 (sfn ++ );
338
269
memcpy (& n .sfn , & sfn_le , sizeof (n .sfn )); /* n.sfn++... */
339
- result = wusb_ccm_mac (tfm_cbc , tfm_aes , scratch , out + bytes ,
270
+ result = wusb_ccm_mac (tfm_cbcmac , & scratch , out + bytes ,
340
271
& n , a , b , blen );
341
272
if (result < 0 )
342
273
goto error_ccm_mac ;
343
274
bytes += result ;
344
275
}
345
276
result = bytes ;
346
277
347
- kfree (scratch );
348
- error_alloc_scratch :
349
278
error_ccm_mac :
350
- error_setkey_aes :
351
- crypto_free_cipher (tfm_aes );
352
- error_alloc_aes :
353
- error_setkey_cbc :
354
- crypto_free_sync_skcipher (tfm_cbc );
355
- error_alloc_cbc :
279
+ error_setkey_cbcmac :
280
+ crypto_free_shash (tfm_cbcmac );
281
+ error_alloc_cbcmac :
356
282
return result ;
357
283
}
358
284
@@ -377,12 +303,8 @@ static int wusb_oob_mic_verify(void)
377
303
{
378
304
int result ;
379
305
u8 mic [8 ];
380
- /* WUSB1.0[A.2] test vectors
381
- *
382
- * Need to keep it in the local stack as GCC 4.1.3something
383
- * messes up and generates noise.
384
- */
385
- struct usb_handshake stv_hsmic_hs = {
306
+ /* WUSB1.0[A.2] test vectors */
307
+ static const struct usb_handshake stv_hsmic_hs = {
386
308
.bMessageNumber = 2 ,
387
309
.bStatus = 00 ,
388
310
.tTKID = { 0x76 , 0x98 , 0x01 },
@@ -457,11 +379,8 @@ static int wusb_key_derive_verify(void)
457
379
{
458
380
int result = 0 ;
459
381
struct wusb_keydvt_out keydvt_out ;
460
- /* These come from WUSB1.0[A.1] + 2006/12 errata
461
- * NOTE: can't make this const or global -- somehow it seems
462
- * the scatterlists for crypto get confused and we get
463
- * bad data. There is no doc on this... */
464
- struct wusb_keydvt_in stv_keydvt_in_a1 = {
382
+ /* These come from WUSB1.0[A.1] + 2006/12 errata */
383
+ static const struct wusb_keydvt_in stv_keydvt_in_a1 = {
465
384
.hnonce = {
466
385
0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 ,
467
386
0x18 , 0x19 , 0x1a , 0x1b , 0x1c , 0x1d , 0x1e , 0x1f
0 commit comments