@@ -790,6 +790,10 @@ static int gcmAesAead_loaded = 0;
790790 (defined(LINUXKM_LKCAPI_REGISTER_ALL ) || \
791791 defined(LINUXKM_LKCAPI_REGISTER_AESXTS ))
792792
793+ #ifndef WOLFSSL_AESGCM_STREAM
794+ #error LKCAPI registration of AES-XTS requires WOLFSSL_AESXTS_STREAM (--enable-aesxts-stream).
795+ #endif
796+
793797struct km_AesXtsCtx {
794798 XtsAes * aesXts ; /* allocated in km_AesXtsInitCommon() to assure alignment
795799 * for AESNI.
@@ -835,6 +839,16 @@ static int km_AesXtsSetKey(struct crypto_skcipher *tfm, const u8 *in_key,
835839 int err ;
836840 struct km_AesXtsCtx * ctx = crypto_skcipher_ctx (tfm );
837841
842+ /* filter bad keysizes here, to avoid console noise from
843+ * CONFIG_CRYPTO_MANAGER_EXTRA_TESTS.
844+ */
845+ if ((key_len != (AES_128_KEY_SIZE * 2 )) &&
846+ (key_len != (AES_192_KEY_SIZE * 2 )) &&
847+ (key_len != (AES_256_KEY_SIZE * 2 )))
848+ {
849+ return - EINVAL ;
850+ }
851+
838852 err = wc_AesXtsSetKeyNoInit (ctx -> aesXts , in_key , key_len ,
839853 AES_ENCRYPTION_AND_DECRYPTION );
840854
@@ -852,7 +866,6 @@ static int km_AesXtsSetKey(struct crypto_skcipher *tfm, const u8 *in_key,
852866static int km_AesXtsEncrypt (struct skcipher_request * req )
853867{
854868 int err = 0 ;
855-
856869 struct crypto_skcipher * tfm = NULL ;
857870 struct km_AesXtsCtx * ctx = NULL ;
858871 struct skcipher_walk walk ;
@@ -861,6 +874,9 @@ static int km_AesXtsEncrypt(struct skcipher_request *req)
861874 tfm = crypto_skcipher_reqtfm (req );
862875 ctx = crypto_skcipher_ctx (tfm );
863876
877+ if (req -> cryptlen < AES_BLOCK_SIZE )
878+ return - EINVAL ;
879+
864880 err = skcipher_walk_virt (& walk , req , false);
865881
866882 if (unlikely (err )) {
@@ -869,23 +885,101 @@ static int km_AesXtsEncrypt(struct skcipher_request *req)
869885 return err ;
870886 }
871887
872- while (( nbytes = walk .nbytes ) != 0 ) {
888+ if ( walk .nbytes == walk . total ) {
873889 err = wc_AesXtsEncrypt (ctx -> aesXts , walk .dst .virt .addr ,
874- walk .src .virt .addr , nbytes ,
875- walk .iv , walk .ivsize );
890+ walk .src .virt .addr , walk .nbytes , walk .iv , walk .ivsize );
876891
877892 if (unlikely (err )) {
878893 pr_err ("%s: wc_AesXtsEncrypt failed: %d\n" ,
879894 crypto_tfm_alg_driver_name (crypto_skcipher_tfm (tfm )), err );
880895 return - EINVAL ;
881896 }
882897
883- err = skcipher_walk_done (& walk , walk .nbytes - nbytes );
898+ err = skcipher_walk_done (& walk , 0 );
899+
900+ } else {
901+ int tail = req -> cryptlen % AES_BLOCK_SIZE ;
902+ struct skcipher_request subreq ;
903+ byte tweak_block [AES_BLOCK_SIZE ];
904+
905+ if (tail > 0 ) {
906+ int blocks = DIV_ROUND_UP (req -> cryptlen , AES_BLOCK_SIZE ) - 2 ;
907+
908+ skcipher_walk_abort (& walk );
909+
910+ skcipher_request_set_tfm (& subreq , tfm );
911+ skcipher_request_set_callback (& subreq ,
912+ skcipher_request_flags (req ),
913+ NULL , NULL );
914+ skcipher_request_set_crypt (& subreq , req -> src , req -> dst ,
915+ blocks * AES_BLOCK_SIZE , req -> iv );
916+ req = & subreq ;
917+
918+ err = skcipher_walk_virt (& walk , req , false);
919+ if (!walk .nbytes )
920+ return err ;
921+ } else {
922+ tail = 0 ;
923+ }
924+
925+ err = wc_AesXtsEncryptStart (ctx -> aesXts , walk .iv , walk .ivsize ,
926+ tweak_block );
884927
885928 if (unlikely (err )) {
886- pr_err ("%s: skcipher_walk_done failed: %d\n" ,
929+ pr_err ("%s: wc_AesXtsEncryptStart failed: %d\n" ,
887930 crypto_tfm_alg_driver_name (crypto_skcipher_tfm (tfm )), err );
888- return err ;
931+ return - EINVAL ;
932+ }
933+
934+ while ((nbytes = walk .nbytes ) != 0 ) {
935+ if (nbytes < walk .total )
936+ nbytes &= ~(AES_BLOCK_SIZE - 1 );
937+
938+ err = wc_AesXtsEncryptUpdate (ctx -> aesXts , walk .dst .virt .addr ,
939+ walk .src .virt .addr , nbytes ,
940+ tweak_block );
941+
942+ if (unlikely (err )) {
943+ pr_err ("%s: wc_AesXtsEncryptUpdate failed: %d\n" ,
944+ crypto_tfm_alg_driver_name (crypto_skcipher_tfm (tfm )), err );
945+ return - EINVAL ;
946+ }
947+
948+ err = skcipher_walk_done (& walk , walk .nbytes - nbytes );
949+
950+ if (unlikely (err )) {
951+ pr_err ("%s: skcipher_walk_done failed: %d\n" ,
952+ crypto_tfm_alg_driver_name (crypto_skcipher_tfm (tfm )), err );
953+ return err ;
954+ }
955+ }
956+
957+ if (unlikely (tail > 0 && !err )) {
958+ struct scatterlist sg_src [2 ], sg_dst [2 ];
959+ struct scatterlist * src , * dst ;
960+
961+ dst = src = scatterwalk_ffwd (sg_src , req -> src , req -> cryptlen );
962+ if (req -> dst != req -> src )
963+ dst = scatterwalk_ffwd (sg_dst , req -> dst , req -> cryptlen );
964+
965+ skcipher_request_set_crypt (req , src , dst , AES_BLOCK_SIZE + tail ,
966+ req -> iv );
967+
968+ err = skcipher_walk_virt (& walk , & subreq , false);
969+ if (err )
970+ return err ;
971+
972+ err = wc_AesXtsEncryptUpdate (ctx -> aesXts , walk .dst .virt .addr ,
973+ walk .src .virt .addr , walk .nbytes ,
974+ tweak_block );
975+
976+ if (unlikely (err )) {
977+ pr_err ("%s: wc_AesXtsEncryptUpdate failed: %d\n" ,
978+ crypto_tfm_alg_driver_name (crypto_skcipher_tfm (tfm )), err );
979+ return - EINVAL ;
980+ }
981+
982+ err = skcipher_walk_done (& walk , 0 );
889983 }
890984 }
891985
@@ -903,6 +997,9 @@ static int km_AesXtsDecrypt(struct skcipher_request *req)
903997 tfm = crypto_skcipher_reqtfm (req );
904998 ctx = crypto_skcipher_ctx (tfm );
905999
1000+ if (req -> cryptlen < AES_BLOCK_SIZE )
1001+ return - EINVAL ;
1002+
9061003 err = skcipher_walk_virt (& walk , req , false);
9071004
9081005 if (unlikely (err )) {
@@ -911,26 +1008,106 @@ static int km_AesXtsDecrypt(struct skcipher_request *req)
9111008 return err ;
9121009 }
9131010
914- while ((nbytes = walk .nbytes ) != 0 ) {
915- err = wc_AesXtsDecrypt (ctx -> aesXts , walk .dst .virt .addr ,
916- walk .src .virt .addr , nbytes ,
917- walk .iv , walk .ivsize );
1011+ if (walk .nbytes == walk .total ) {
1012+
1013+ err = wc_AesXtsDecrypt (ctx -> aesXts ,
1014+ walk .dst .virt .addr , walk .src .virt .addr ,
1015+ walk .nbytes , walk .iv , walk .ivsize );
9181016
9191017 if (unlikely (err )) {
920- pr_err ("%s: wc_AesCbcDecrypt failed: %d\n" ,
1018+ pr_err ("%s: wc_AesXtsDecrypt failed: %d\n" ,
9211019 crypto_tfm_alg_driver_name (crypto_skcipher_tfm (tfm )), err );
9221020 return - EINVAL ;
9231021 }
9241022
925- err = skcipher_walk_done (& walk , walk .nbytes - nbytes );
1023+ err = skcipher_walk_done (& walk , 0 );
1024+
1025+ } else {
1026+ int tail = req -> cryptlen % AES_BLOCK_SIZE ;
1027+ struct skcipher_request subreq ;
1028+ byte tweak_block [AES_BLOCK_SIZE ];
1029+
1030+ if (unlikely (tail > 0 )) {
1031+ int blocks = DIV_ROUND_UP (req -> cryptlen , AES_BLOCK_SIZE ) - 2 ;
1032+
1033+ skcipher_walk_abort (& walk );
1034+
1035+ skcipher_request_set_tfm (& subreq , tfm );
1036+ skcipher_request_set_callback (& subreq ,
1037+ skcipher_request_flags (req ),
1038+ NULL , NULL );
1039+ skcipher_request_set_crypt (& subreq , req -> src , req -> dst ,
1040+ blocks * AES_BLOCK_SIZE , req -> iv );
1041+ req = & subreq ;
1042+
1043+ err = skcipher_walk_virt (& walk , req , false);
1044+ if (!walk .nbytes )
1045+ return err ;
1046+ } else {
1047+ tail = 0 ;
1048+ }
1049+
1050+ err = wc_AesXtsDecryptStart (ctx -> aesXts , walk .iv , walk .ivsize ,
1051+ tweak_block );
9261052
9271053 if (unlikely (err )) {
928- pr_err ("%s: skcipher_walk_done failed: %d\n" ,
1054+ pr_err ("%s: wc_AesXtsDecryptStart failed: %d\n" ,
9291055 crypto_tfm_alg_driver_name (crypto_skcipher_tfm (tfm )), err );
930- return err ;
1056+ return - EINVAL ;
9311057 }
932- }
9331058
1059+ while ((nbytes = walk .nbytes ) != 0 ) {
1060+ if (nbytes < walk .total )
1061+ nbytes &= ~(AES_BLOCK_SIZE - 1 );
1062+
1063+ err = wc_AesXtsDecryptUpdate (ctx -> aesXts , walk .dst .virt .addr ,
1064+ walk .src .virt .addr , nbytes ,
1065+ tweak_block );
1066+
1067+ if (unlikely (err )) {
1068+ pr_err ("%s: wc_AesXtsDecryptUpdate failed: %d\n" ,
1069+ crypto_tfm_alg_driver_name (crypto_skcipher_tfm (tfm )), err );
1070+ return - EINVAL ;
1071+ }
1072+
1073+ err = skcipher_walk_done (& walk , walk .nbytes - nbytes );
1074+
1075+ if (unlikely (err )) {
1076+ pr_err ("%s: skcipher_walk_done failed: %d\n" ,
1077+ crypto_tfm_alg_driver_name (crypto_skcipher_tfm (tfm )), err );
1078+ return err ;
1079+ }
1080+ }
1081+
1082+ if (unlikely (tail > 0 && !err )) {
1083+ struct scatterlist sg_src [2 ], sg_dst [2 ];
1084+ struct scatterlist * src , * dst ;
1085+
1086+ dst = src = scatterwalk_ffwd (sg_src , req -> src , req -> cryptlen );
1087+ if (req -> dst != req -> src )
1088+ dst = scatterwalk_ffwd (sg_dst , req -> dst , req -> cryptlen );
1089+
1090+ skcipher_request_set_crypt (req , src , dst , AES_BLOCK_SIZE + tail ,
1091+ req -> iv );
1092+
1093+ err = skcipher_walk_virt (& walk , & subreq , false);
1094+ if (err )
1095+ return err ;
1096+
1097+ err = wc_AesXtsDecryptUpdate (ctx -> aesXts , walk .dst .virt .addr ,
1098+ walk .src .virt .addr , walk .nbytes ,
1099+ tweak_block );
1100+
1101+ if (unlikely (err )) {
1102+ pr_err ("%s: wc_AesXtsDecryptUpdate failed: %d\n" ,
1103+ crypto_tfm_alg_driver_name (crypto_skcipher_tfm (tfm )), err );
1104+ return - EINVAL ;
1105+ }
1106+
1107+ err = skcipher_walk_done (& walk , 0 );
1108+ }
1109+
1110+ }
9341111 return err ;
9351112}
9361113
0 commit comments