@@ -698,6 +698,64 @@ int crypto_skcipher_decrypt(struct skcipher_request *req)
698698}
699699EXPORT_SYMBOL_GPL (crypto_skcipher_decrypt );
700700
701+ static int crypto_lskcipher_export (struct skcipher_request * req , void * out )
702+ {
703+ struct crypto_skcipher * tfm = crypto_skcipher_reqtfm (req );
704+ u8 * ivs = skcipher_request_ctx (req );
705+
706+ ivs = PTR_ALIGN (ivs , crypto_skcipher_alignmask (tfm ) + 1 );
707+
708+ memcpy (out , ivs + crypto_skcipher_ivsize (tfm ),
709+ crypto_skcipher_statesize (tfm ));
710+
711+ return 0 ;
712+ }
713+
714+ static int crypto_lskcipher_import (struct skcipher_request * req , const void * in )
715+ {
716+ struct crypto_skcipher * tfm = crypto_skcipher_reqtfm (req );
717+ u8 * ivs = skcipher_request_ctx (req );
718+
719+ ivs = PTR_ALIGN (ivs , crypto_skcipher_alignmask (tfm ) + 1 );
720+
721+ memcpy (ivs + crypto_skcipher_ivsize (tfm ), in ,
722+ crypto_skcipher_statesize (tfm ));
723+
724+ return 0 ;
725+ }
726+
727+ static int skcipher_noexport (struct skcipher_request * req , void * out )
728+ {
729+ return 0 ;
730+ }
731+
732+ static int skcipher_noimport (struct skcipher_request * req , const void * in )
733+ {
734+ return 0 ;
735+ }
736+
737+ int crypto_skcipher_export (struct skcipher_request * req , void * out )
738+ {
739+ struct crypto_skcipher * tfm = crypto_skcipher_reqtfm (req );
740+ struct skcipher_alg * alg = crypto_skcipher_alg (tfm );
741+
742+ if (alg -> co .base .cra_type != & crypto_skcipher_type )
743+ return crypto_lskcipher_export (req , out );
744+ return alg -> export (req , out );
745+ }
746+ EXPORT_SYMBOL_GPL (crypto_skcipher_export );
747+
748+ int crypto_skcipher_import (struct skcipher_request * req , const void * in )
749+ {
750+ struct crypto_skcipher * tfm = crypto_skcipher_reqtfm (req );
751+ struct skcipher_alg * alg = crypto_skcipher_alg (tfm );
752+
753+ if (alg -> co .base .cra_type != & crypto_skcipher_type )
754+ return crypto_lskcipher_import (req , in );
755+ return alg -> import (req , in );
756+ }
757+ EXPORT_SYMBOL_GPL (crypto_skcipher_import );
758+
701759static void crypto_skcipher_exit_tfm (struct crypto_tfm * tfm )
702760{
703761 struct crypto_skcipher * skcipher = __crypto_skcipher_cast (tfm );
@@ -713,8 +771,17 @@ static int crypto_skcipher_init_tfm(struct crypto_tfm *tfm)
713771
714772 skcipher_set_needkey (skcipher );
715773
716- if (tfm -> __crt_alg -> cra_type != & crypto_skcipher_type )
774+ if (tfm -> __crt_alg -> cra_type != & crypto_skcipher_type ) {
775+ unsigned am = crypto_skcipher_alignmask (skcipher );
776+ unsigned reqsize ;
777+
778+ reqsize = am & ~(crypto_tfm_ctx_alignment () - 1 );
779+ reqsize += crypto_skcipher_ivsize (skcipher );
780+ reqsize += crypto_skcipher_statesize (skcipher );
781+ crypto_skcipher_set_reqsize (skcipher , reqsize );
782+
717783 return crypto_init_lskcipher_ops_sg (tfm );
784+ }
718785
719786 if (alg -> exit )
720787 skcipher -> base .exit = crypto_skcipher_exit_tfm ;
@@ -756,6 +823,7 @@ static void crypto_skcipher_show(struct seq_file *m, struct crypto_alg *alg)
756823 seq_printf (m , "ivsize : %u\n" , skcipher -> ivsize );
757824 seq_printf (m , "chunksize : %u\n" , skcipher -> chunksize );
758825 seq_printf (m , "walksize : %u\n" , skcipher -> walksize );
826+ seq_printf (m , "statesize : %u\n" , skcipher -> statesize );
759827}
760828
761829static int __maybe_unused crypto_skcipher_report (
@@ -870,7 +938,9 @@ int skcipher_prepare_alg_common(struct skcipher_alg_common *alg)
870938 struct crypto_istat_cipher * istat = skcipher_get_stat_common (alg );
871939 struct crypto_alg * base = & alg -> base ;
872940
873- if (alg -> ivsize > PAGE_SIZE / 8 || alg -> chunksize > PAGE_SIZE / 8 )
941+ if (alg -> ivsize > PAGE_SIZE / 8 || alg -> chunksize > PAGE_SIZE / 8 ||
942+ alg -> statesize > PAGE_SIZE / 2 ||
943+ (alg -> ivsize + alg -> statesize ) > PAGE_SIZE / 2 )
874944 return - EINVAL ;
875945
876946 if (!alg -> chunksize )
@@ -899,6 +969,12 @@ static int skcipher_prepare_alg(struct skcipher_alg *alg)
899969 if (!alg -> walksize )
900970 alg -> walksize = alg -> chunksize ;
901971
972+ if (!alg -> statesize ) {
973+ alg -> import = skcipher_noimport ;
974+ alg -> export = skcipher_noexport ;
975+ } else if (!(alg -> import && alg -> export ))
976+ return - EINVAL ;
977+
902978 base -> cra_type = & crypto_skcipher_type ;
903979 base -> cra_flags |= CRYPTO_ALG_TYPE_SKCIPHER ;
904980
0 commit comments