2007-05-05 22:45:53 +04:00
/*
* Copyright 2003 - 2004 , Instant802 Networks , Inc .
* Copyright 2005 - 2006 , Devicescape Software , Inc .
*
2013-10-10 11:55:20 +04:00
* Rewrite : Copyright ( C ) 2013 Linaro Ltd < ard . biesheuvel @ linaro . org >
*
2007-05-05 22:45:53 +04:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
2007-08-29 02:50:33 +04:00
# include <linux/kernel.h>
2007-05-05 22:45:53 +04:00
# include <linux/types.h>
# include <linux/crypto.h>
# include <linux/err.h>
2011-07-07 00:02:14 +04:00
# include <crypto/aes.h>
2007-05-05 22:45:53 +04:00
# include <net/mac80211.h>
2008-04-08 23:14:40 +04:00
# include "key.h"
2007-05-05 22:45:53 +04:00
# include "aes_ccm.h"
2013-10-10 11:55:20 +04:00
void ieee80211_aes_ccm_encrypt ( struct crypto_aead * tfm , u8 * b_0 , u8 * aad ,
u8 * data , size_t data_len , u8 * mic )
2007-05-05 22:45:53 +04:00
{
2013-10-10 11:55:20 +04:00
struct scatterlist assoc , pt , ct [ 2 ] ;
2007-05-05 22:45:53 +04:00
2014-03-21 10:39:32 +04:00
char aead_req_data [ sizeof ( struct aead_request ) +
crypto_aead_reqsize ( tfm ) ]
__aligned ( __alignof__ ( struct aead_request ) ) ;
struct aead_request * aead_req = ( void * ) aead_req_data ;
memset ( aead_req , 0 , sizeof ( aead_req_data ) ) ;
2007-05-05 22:45:53 +04:00
2013-10-10 11:55:20 +04:00
sg_init_one ( & pt , data , data_len ) ;
sg_init_one ( & assoc , & aad [ 2 ] , be16_to_cpup ( ( __be16 * ) aad ) ) ;
sg_init_table ( ct , 2 ) ;
sg_set_buf ( & ct [ 0 ] , data , data_len ) ;
sg_set_buf ( & ct [ 1 ] , mic , IEEE80211_CCMP_MIC_LEN ) ;
2007-05-05 22:45:53 +04:00
2014-03-21 10:39:32 +04:00
aead_request_set_tfm ( aead_req , tfm ) ;
aead_request_set_assoc ( aead_req , & assoc , assoc . length ) ;
aead_request_set_crypt ( aead_req , & pt , ct , data_len , b_0 ) ;
2007-05-05 22:45:53 +04:00
2014-03-21 10:39:32 +04:00
crypto_aead_encrypt ( aead_req ) ;
2007-05-05 22:45:53 +04:00
}
2013-10-10 11:55:20 +04:00
int ieee80211_aes_ccm_decrypt ( struct crypto_aead * tfm , u8 * b_0 , u8 * aad ,
u8 * data , size_t data_len , u8 * mic )
2007-05-05 22:45:53 +04:00
{
2013-10-10 11:55:20 +04:00
struct scatterlist assoc , pt , ct [ 2 ] ;
2014-03-21 10:39:32 +04:00
char aead_req_data [ sizeof ( struct aead_request ) +
crypto_aead_reqsize ( tfm ) ]
__aligned ( __alignof__ ( struct aead_request ) ) ;
struct aead_request * aead_req = ( void * ) aead_req_data ;
2013-10-10 11:55:20 +04:00
2014-03-21 10:39:32 +04:00
memset ( aead_req , 0 , sizeof ( aead_req_data ) ) ;
2013-10-10 11:55:20 +04:00
sg_init_one ( & pt , data , data_len ) ;
sg_init_one ( & assoc , & aad [ 2 ] , be16_to_cpup ( ( __be16 * ) aad ) ) ;
sg_init_table ( ct , 2 ) ;
sg_set_buf ( & ct [ 0 ] , data , data_len ) ;
sg_set_buf ( & ct [ 1 ] , mic , IEEE80211_CCMP_MIC_LEN ) ;
2014-03-21 10:39:32 +04:00
aead_request_set_tfm ( aead_req , tfm ) ;
aead_request_set_assoc ( aead_req , & assoc , assoc . length ) ;
aead_request_set_crypt ( aead_req , ct , & pt ,
2013-10-10 11:55:20 +04:00
data_len + IEEE80211_CCMP_MIC_LEN , b_0 ) ;
2014-03-21 10:39:32 +04:00
return crypto_aead_decrypt ( aead_req ) ;
2007-05-05 22:45:53 +04:00
}
2013-10-10 11:55:20 +04:00
struct crypto_aead * ieee80211_aes_key_setup_encrypt ( const u8 key [ ] )
2007-05-05 22:45:53 +04:00
{
2013-10-10 11:55:20 +04:00
struct crypto_aead * tfm ;
int err ;
2007-05-05 22:45:53 +04:00
2013-10-10 11:55:20 +04:00
tfm = crypto_alloc_aead ( " ccm(aes) " , 0 , CRYPTO_ALG_ASYNC ) ;
if ( IS_ERR ( tfm ) )
return tfm ;
2007-05-05 22:45:53 +04:00
2013-10-10 11:55:20 +04:00
err = crypto_aead_setkey ( tfm , key , WLAN_KEY_LEN_CCMP ) ;
if ( ! err )
err = crypto_aead_setauthsize ( tfm , IEEE80211_CCMP_MIC_LEN ) ;
if ( ! err )
return tfm ;
2007-05-05 22:45:53 +04:00
2013-10-10 11:55:20 +04:00
crypto_free_aead ( tfm ) ;
return ERR_PTR ( err ) ;
2007-05-05 22:45:53 +04:00
}
2013-10-10 11:55:20 +04:00
void ieee80211_aes_key_free ( struct crypto_aead * tfm )
2007-05-05 22:45:53 +04:00
{
2013-10-10 11:55:20 +04:00
crypto_free_aead ( tfm ) ;
2007-05-05 22:45:53 +04:00
}