2019-05-29 07:18:13 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2021-03-18 12:44:21 +00:00
/*
2012-05-14 11:05:12 +00:00
* AES CBC routines supporting the Power 7 + Nest Accelerators driver
*
* Copyright ( C ) 2011 - 2012 International Business Machines Inc .
*
* Author : Kent Yoder < yoder1 @ us . ibm . com >
*/
# include <crypto/aes.h>
# include <crypto/algapi.h>
# include <linux/module.h>
# include <linux/types.h>
# include <linux/crypto.h>
# include <asm/vio.h>
# include "nx_csbcpb.h"
# include "nx.h"
2019-10-12 21:39:17 -07:00
static int cbc_aes_nx_set_key ( struct crypto_skcipher * tfm ,
const u8 * in_key ,
unsigned int key_len )
2012-05-14 11:05:12 +00:00
{
2019-10-12 21:39:17 -07:00
struct nx_crypto_ctx * nx_ctx = crypto_skcipher_ctx ( tfm ) ;
2012-05-14 11:05:12 +00:00
struct nx_csbcpb * csbcpb = nx_ctx - > csbcpb ;
nx_ctx_init ( nx_ctx , HCOP_FC_AES ) ;
switch ( key_len ) {
case AES_KEYSIZE_128 :
NX_CPB_SET_KEY_SIZE ( csbcpb , NX_KS_AES_128 ) ;
nx_ctx - > ap = & nx_ctx - > props [ NX_PROPS_AES_128 ] ;
break ;
case AES_KEYSIZE_192 :
NX_CPB_SET_KEY_SIZE ( csbcpb , NX_KS_AES_192 ) ;
nx_ctx - > ap = & nx_ctx - > props [ NX_PROPS_AES_192 ] ;
break ;
case AES_KEYSIZE_256 :
NX_CPB_SET_KEY_SIZE ( csbcpb , NX_KS_AES_256 ) ;
nx_ctx - > ap = & nx_ctx - > props [ NX_PROPS_AES_256 ] ;
break ;
default :
return - EINVAL ;
}
csbcpb - > cpb . hdr . mode = NX_MODE_AES_CBC ;
memcpy ( csbcpb - > cpb . aes_cbc . key , in_key , key_len ) ;
return 0 ;
}
2019-10-12 21:39:17 -07:00
static int cbc_aes_nx_crypt ( struct skcipher_request * req ,
int enc )
2012-05-14 11:05:12 +00:00
{
2019-10-12 21:39:17 -07:00
struct crypto_skcipher * tfm = crypto_skcipher_reqtfm ( req ) ;
struct nx_crypto_ctx * nx_ctx = crypto_skcipher_ctx ( tfm ) ;
2012-05-14 11:05:12 +00:00
struct nx_csbcpb * csbcpb = nx_ctx - > csbcpb ;
2013-08-12 18:49:37 -03:00
unsigned long irq_flags ;
2013-08-29 11:36:33 -03:00
unsigned int processed = 0 , to_process ;
2012-05-14 11:05:12 +00:00
int rc ;
2013-08-12 18:49:37 -03:00
spin_lock_irqsave ( & nx_ctx - > lock , irq_flags ) ;
2012-05-14 11:05:12 +00:00
if ( enc )
NX_CPB_FDM ( csbcpb ) | = NX_FDM_ENDE_ENCRYPT ;
else
NX_CPB_FDM ( csbcpb ) & = ~ NX_FDM_ENDE_ENCRYPT ;
2013-08-29 11:36:33 -03:00
do {
2019-10-12 21:39:17 -07:00
to_process = req - > cryptlen - processed ;
2013-08-29 11:36:33 -03:00
2019-10-12 21:39:17 -07:00
rc = nx_build_sg_lists ( nx_ctx , req - > iv , req - > dst , req - > src ,
2019-10-12 21:39:15 -07:00
& to_process , processed ,
csbcpb - > cpb . aes_cbc . iv ) ;
2013-08-29 11:36:33 -03:00
if ( rc )
goto out ;
if ( ! nx_ctx - > op . inlen | | ! nx_ctx - > op . outlen ) {
rc = - EINVAL ;
goto out ;
}
rc = nx_hcall_sync ( nx_ctx , & nx_ctx - > op ,
2019-10-12 21:39:17 -07:00
req - > base . flags & CRYPTO_TFM_REQ_MAY_SLEEP ) ;
2013-08-29 11:36:33 -03:00
if ( rc )
goto out ;
2019-10-12 21:39:17 -07:00
memcpy ( req - > iv , csbcpb - > cpb . aes_cbc . cv , AES_BLOCK_SIZE ) ;
2013-08-29 11:36:33 -03:00
atomic_inc ( & ( nx_ctx - > stats - > aes_ops ) ) ;
2021-06-17 16:00:12 +08:00
atomic64_add ( be32_to_cpu ( csbcpb - > csb . processed_byte_count ) ,
2013-08-29 11:36:33 -03:00
& ( nx_ctx - > stats - > aes_bytes ) ) ;
processed + = to_process ;
2019-10-12 21:39:17 -07:00
} while ( processed < req - > cryptlen ) ;
2012-05-14 11:05:12 +00:00
out :
2013-08-12 18:49:37 -03:00
spin_unlock_irqrestore ( & nx_ctx - > lock , irq_flags ) ;
2012-05-14 11:05:12 +00:00
return rc ;
}
2019-10-12 21:39:17 -07:00
static int cbc_aes_nx_encrypt ( struct skcipher_request * req )
2012-05-14 11:05:12 +00:00
{
2019-10-12 21:39:17 -07:00
return cbc_aes_nx_crypt ( req , 1 ) ;
2012-05-14 11:05:12 +00:00
}
2019-10-12 21:39:17 -07:00
static int cbc_aes_nx_decrypt ( struct skcipher_request * req )
2012-05-14 11:05:12 +00:00
{
2019-10-12 21:39:17 -07:00
return cbc_aes_nx_crypt ( req , 0 ) ;
2012-05-14 11:05:12 +00:00
}
2019-10-12 21:39:17 -07:00
struct skcipher_alg nx_cbc_aes_alg = {
. base . cra_name = " cbc(aes) " ,
. base . cra_driver_name = " cbc-aes-nx " ,
. base . cra_priority = 300 ,
. base . cra_blocksize = AES_BLOCK_SIZE ,
. base . cra_ctxsize = sizeof ( struct nx_crypto_ctx ) ,
. base . cra_alignmask = 0xf ,
. base . cra_module = THIS_MODULE ,
. init = nx_crypto_ctx_aes_cbc_init ,
. exit = nx_crypto_ctx_skcipher_exit ,
. min_keysize = AES_MIN_KEY_SIZE ,
. max_keysize = AES_MAX_KEY_SIZE ,
. ivsize = AES_BLOCK_SIZE ,
. setkey = cbc_aes_nx_set_key ,
. encrypt = cbc_aes_nx_encrypt ,
. decrypt = cbc_aes_nx_decrypt ,
2012-05-14 11:05:12 +00:00
} ;