@ -225,6 +225,12 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
dma_addr_t dst_phys = dma_map_single ( sdcp - > dev , sdcp - > coh - > aes_out_buf ,
dma_addr_t dst_phys = dma_map_single ( sdcp - > dev , sdcp - > coh - > aes_out_buf ,
DCP_BUF_SZ , DMA_FROM_DEVICE ) ;
DCP_BUF_SZ , DMA_FROM_DEVICE ) ;
if ( actx - > fill % AES_BLOCK_SIZE ) {
dev_err ( sdcp - > dev , " Invalid block size! \n " ) ;
ret = - EINVAL ;
goto aes_done_run ;
}
/* Fill in the DMA descriptor. */
/* Fill in the DMA descriptor. */
desc - > control0 = MXS_DCP_CONTROL0_DECR_SEMAPHORE |
desc - > control0 = MXS_DCP_CONTROL0_DECR_SEMAPHORE |
MXS_DCP_CONTROL0_INTERRUPT |
MXS_DCP_CONTROL0_INTERRUPT |
@ -254,6 +260,7 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
ret = mxs_dcp_start_dma ( actx ) ;
ret = mxs_dcp_start_dma ( actx ) ;
aes_done_run :
dma_unmap_single ( sdcp - > dev , key_phys , 2 * AES_KEYSIZE_128 ,
dma_unmap_single ( sdcp - > dev , key_phys , 2 * AES_KEYSIZE_128 ,
DMA_TO_DEVICE ) ;
DMA_TO_DEVICE ) ;
dma_unmap_single ( sdcp - > dev , src_phys , DCP_BUF_SZ , DMA_TO_DEVICE ) ;
dma_unmap_single ( sdcp - > dev , src_phys , DCP_BUF_SZ , DMA_TO_DEVICE ) ;
@ -280,13 +287,15 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
uint8_t * out_tmp , * src_buf , * dst_buf = NULL ;
uint8_t * out_tmp , * src_buf , * dst_buf = NULL ;
uint32_t dst_off = 0 ;
uint32_t dst_off = 0 ;
uint32_t last_out_len = 0 ;
uint8_t * key = sdcp - > coh - > aes_key ;
uint8_t * key = sdcp - > coh - > aes_key ;
int ret = 0 ;
int ret = 0 ;
int split = 0 ;
int split = 0 ;
unsigned int i , len , clen , rem = 0 ;
unsigned int i , len , clen , rem = 0 , tlen = 0 ;
int init = 0 ;
int init = 0 ;
bool limit_hit = false ;
actx - > fill = 0 ;
actx - > fill = 0 ;
@ -305,6 +314,11 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
for_each_sg ( req - > src , src , nents , i ) {
for_each_sg ( req - > src , src , nents , i ) {
src_buf = sg_virt ( src ) ;
src_buf = sg_virt ( src ) ;
len = sg_dma_len ( src ) ;
len = sg_dma_len ( src ) ;
tlen + = len ;
limit_hit = tlen > req - > nbytes ;
if ( limit_hit )
len = req - > nbytes - ( tlen - len ) ;
do {
do {
if ( actx - > fill + len > out_off )
if ( actx - > fill + len > out_off )
@ -321,13 +335,15 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
* If we filled the buffer or this is the last SG ,
* If we filled the buffer or this is the last SG ,
* submit the buffer .
* submit the buffer .
*/
*/
if ( actx - > fill = = out_off | | sg_is_last ( src ) ) {
if ( actx - > fill = = out_off | | sg_is_last ( src ) | |
limit_hit ) {
ret = mxs_dcp_run_aes ( actx , req , init ) ;
ret = mxs_dcp_run_aes ( actx , req , init ) ;
if ( ret )
if ( ret )
return ret ;
return ret ;
init = 0 ;
init = 0 ;
out_tmp = out_buf ;
out_tmp = out_buf ;
last_out_len = actx - > fill ;
while ( dst & & actx - > fill ) {
while ( dst & & actx - > fill ) {
if ( ! split ) {
if ( ! split ) {
dst_buf = sg_virt ( dst ) ;
dst_buf = sg_virt ( dst ) ;
@ -350,6 +366,19 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
}
}
}
}
} while ( len ) ;
} while ( len ) ;
if ( limit_hit )
break ;
}
/* Copy the IV for CBC for chaining */
if ( ! rctx - > ecb ) {
if ( rctx - > enc )
memcpy ( req - > info , out_buf + ( last_out_len - AES_BLOCK_SIZE ) ,
AES_BLOCK_SIZE ) ;
else
memcpy ( req - > info , in_buf + ( last_out_len - AES_BLOCK_SIZE ) ,
AES_BLOCK_SIZE ) ;
}
}
return ret ;
return ret ;