2019-05-29 07:18:13 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2021-03-21 18:00:07 +05:30
/*
2012-05-14 11:05:30 +00:00
* AES CTR 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/ctr.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:18 -07:00
static int ctr_aes_nx_set_key ( struct crypto_skcipher * tfm ,
const u8 * in_key ,
unsigned int key_len )
2012-05-14 11:05:30 +00:00
{
2019-10-12 21:39:18 -07:00
struct nx_crypto_ctx * nx_ctx = crypto_skcipher_ctx ( tfm ) ;
2012-05-14 11:05:30 +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_CTR ;
memcpy ( csbcpb - > cpb . aes_ctr . key , in_key , key_len ) ;
return 0 ;
}
2019-10-12 21:39:18 -07:00
static int ctr3686_aes_nx_set_key ( struct crypto_skcipher * tfm ,
const u8 * in_key ,
unsigned int key_len )
2012-05-14 11:05:30 +00:00
{
2019-10-12 21:39:18 -07:00
struct nx_crypto_ctx * nx_ctx = crypto_skcipher_ctx ( tfm ) ;
2012-05-14 11:05:30 +00:00
if ( key_len < CTR_RFC3686_NONCE_SIZE )
return - EINVAL ;
2015-07-07 17:30:25 +08:00
memcpy ( nx_ctx - > priv . ctr . nonce ,
2012-05-14 11:05:30 +00:00
in_key + key_len - CTR_RFC3686_NONCE_SIZE ,
CTR_RFC3686_NONCE_SIZE ) ;
key_len - = CTR_RFC3686_NONCE_SIZE ;
return ctr_aes_nx_set_key ( tfm , in_key , key_len ) ;
}
2019-10-12 21:39:18 -07:00
static int ctr_aes_nx_crypt ( struct skcipher_request * req , u8 * iv )
2012-05-14 11:05:30 +00:00
{
2019-10-12 21:39:18 -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:30 +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:34 -03:00
unsigned int processed = 0 , to_process ;
2012-05-14 11:05:30 +00:00
int rc ;
2013-08-12 18:49:37 -03:00
spin_lock_irqsave ( & nx_ctx - > lock , irq_flags ) ;
2013-08-29 11:36:34 -03:00
do {
2019-10-12 21:39:18 -07:00
to_process = req - > cryptlen - processed ;
2012-05-14 11:05:30 +00:00
2019-10-12 21:39:18 -07:00
rc = nx_build_sg_lists ( nx_ctx , iv , req - > dst , req - > src ,
2019-10-12 21:39:15 -07:00
& to_process , processed ,
csbcpb - > cpb . aes_ctr . iv ) ;
2013-08-29 11:36:34 -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:18 -07:00
req - > base . flags & CRYPTO_TFM_REQ_MAY_SLEEP ) ;
2013-08-29 11:36:34 -03:00
if ( rc )
goto out ;
2019-10-12 21:39:18 -07:00
memcpy ( iv , csbcpb - > cpb . aes_cbc . cv , AES_BLOCK_SIZE ) ;
2012-05-14 11:05:30 +00:00
2013-08-29 11:36:34 -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:34 -03:00
& ( nx_ctx - > stats - > aes_bytes ) ) ;
2012-05-14 11:05:30 +00:00
2013-08-29 11:36:34 -03:00
processed + = to_process ;
2019-10-12 21:39:18 -07:00
} while ( processed < req - > cryptlen ) ;
2012-05-14 11:05:30 +00:00
out :
2013-08-12 18:49:37 -03:00
spin_unlock_irqrestore ( & nx_ctx - > lock , irq_flags ) ;
2012-05-14 11:05:30 +00:00
return rc ;
}
2019-10-12 21:39:18 -07:00
static int ctr3686_aes_nx_crypt ( struct skcipher_request * req )
2012-05-14 11:05:30 +00:00
{
2019-10-12 21:39:18 -07:00
struct crypto_skcipher * tfm = crypto_skcipher_reqtfm ( req ) ;
struct nx_crypto_ctx * nx_ctx = crypto_skcipher_ctx ( tfm ) ;
2015-07-07 17:30:25 +08:00
u8 iv [ 16 ] ;
2012-05-14 11:05:30 +00:00
2021-06-16 13:34:59 -07:00
memcpy ( iv , nx_ctx - > priv . ctr . nonce , CTR_RFC3686_NONCE_SIZE ) ;
2019-10-12 21:39:18 -07:00
memcpy ( iv + CTR_RFC3686_NONCE_SIZE , req - > iv , CTR_RFC3686_IV_SIZE ) ;
2014-10-28 15:45:49 -02:00
iv [ 12 ] = iv [ 13 ] = iv [ 14 ] = 0 ;
2012-05-14 11:05:30 +00:00
iv [ 15 ] = 1 ;
2019-10-12 21:39:18 -07:00
return ctr_aes_nx_crypt ( req , iv ) ;
2012-05-14 11:05:30 +00:00
}
2019-10-12 21:39:18 -07:00
struct skcipher_alg nx_ctr3686_aes_alg = {
. base . cra_name = " rfc3686(ctr(aes)) " ,
. base . cra_driver_name = " rfc3686-ctr-aes-nx " ,
. base . cra_priority = 300 ,
. base . cra_blocksize = 1 ,
. base . cra_ctxsize = sizeof ( struct nx_crypto_ctx ) ,
. base . cra_module = THIS_MODULE ,
. init = nx_crypto_ctx_aes_ctr_init ,
. exit = nx_crypto_ctx_skcipher_exit ,
. min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE ,
. max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE ,
. ivsize = CTR_RFC3686_IV_SIZE ,
. setkey = ctr3686_aes_nx_set_key ,
. encrypt = ctr3686_aes_nx_crypt ,
. decrypt = ctr3686_aes_nx_crypt ,
. chunksize = AES_BLOCK_SIZE ,
2012-05-14 11:05:30 +00:00
} ;