Skip to content

Commit 70d7b6e

Browse files
committed
add WOLFSSL_AESXTS_STREAM, --enable-aesxts-stream, wc_AesXtsEncryptStart(), wc_AesXtsDecryptStart(), wc_AesXtsEncryptUpdate(), wc_AesXtsDecryptUpdate(), and implement fixes in linuxkm/lkcapi_glue.c to use the streaming API when needed. also added support for 2*192 bit AES-XTS, needed for Linux kernel.
1 parent 28bd4eb commit 70d7b6e

5 files changed

Lines changed: 784 additions & 54 deletions

File tree

configure.ac

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,7 @@ then
939939

940940
if test "$ENABLED_FIPS" = "no" || test "$HAVE_FIPS_VERSION" -ge 6 || test "$FIPS_VERSION" = "v5-dev"; then
941941
test "$enable_aesxts" = "" && enable_aesxts=yes
942+
test "$enable_aesxts_stream" = "" && test "$enable_aesxts" = "yes" && enable_aesxts_stream=yes
942943
test "$enable_aessiv" = "" && enable_aessiv=yes
943944
fi
944945

@@ -1078,6 +1079,7 @@ then
10781079

10791080
if test "$ENABLED_FIPS" = "no" || test "$HAVE_FIPS_VERSION" -ge 6 || test "$FIPS_VERSION" = "v5-dev"; then
10801081
test "$enable_aesxts" = "" && enable_aesxts=yes
1082+
test "$enable_aesxts_stream" = "" && test "$enable_aesxts" = "yes" && enable_aesxts_stream=yes
10811083
test "$enable_aessiv" = "" && enable_aessiv=yes
10821084
fi
10831085

@@ -4847,6 +4849,11 @@ AC_ARG_ENABLE([aesxts],
48474849
[ ENABLED_AESXTS=$enableval ],
48484850
[ ENABLED_AESXTS=no ]
48494851
)
4852+
AC_ARG_ENABLE([aesxts-stream],
4853+
[AS_HELP_STRING([--enable-aesxts-stream],[Enable wolfSSL AES-XTS support with streaming APIs (default: disabled)])],
4854+
[ ENABLED_AESXTS_STREAM=$enableval ],
4855+
[ ENABLED_AESXTS_STREAM=$ENABLED_AESXTS ]
4856+
)
48504857

48514858
# legacy old option name, for compatibility:
48524859
AC_ARG_ENABLE([xts],
@@ -5070,6 +5077,11 @@ AS_CASE([$FIPS_VERSION],
50705077
AS_IF([test "x$ENABLED_AESXTS" = "xyes" && test "x$ENABLED_AESNI" = "xyes"],
50715078
[AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_AES_XTS"])
50725079
5080+
AS_IF([test "x$ENABLED_AESXTS_STREAM" = "xno"],
5081+
[ENABLED_AESXTS_STREAM="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AESXTS_STREAM"])
5082+
AS_IF([test "x$ENABLED_AESXTS_STREAM" = "xyes" && test "x$ENABLED_AESNI" = "xyes"],
5083+
[AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_AESXTS_STREAM"])
5084+
50735085
AS_IF([(test "$ENABLED_AESCCM" = "yes" && test "$HAVE_AESCCM_PORT" != "yes") ||
50745086
(test "$ENABLED_AESCTR" = "yes" && test "$HAVE_AESCTR_PORT" != "yes") ||
50755087
(test "$ENABLED_AESGCM" = "yes" && test "$HAVE_AESGCM_PORT" != "yes") ||
@@ -8360,6 +8372,7 @@ then
83608372
test "$ENABLED_AESGCM_STREAM" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: --enable-aesgcm-stream is required for LKCAPI.])
83618373
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESGCM" ;;
83628374
'xts(aes)') test "$ENABLED_AESXTS" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-XTS implementation not enabled.])
8375+
test "$ENABLED_AESXTS_STREAM" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: --enable-aesxts-stream is required for LKCAPI.])
83638376
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESXTS" ;;
83648377
*) AC_MSG_ERROR([Unsupported LKCAPI algorithm "$lkcapi_alg".]) ;;
83658378
esac
@@ -9009,6 +9022,17 @@ then
90099022
fi
90109023
fi
90119024
9025+
if test "$ENABLED_AESXTS_STREAM" != "no"
9026+
then
9027+
if test "$ENABLED_AESXTS" = "no"
9028+
then
9029+
AC_MSG_ERROR([AES-XTS streaming enabled but AES-XTS is disabled])
9030+
else
9031+
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AESXTS_STREAM"
9032+
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_AESXTS_STREAM"
9033+
fi
9034+
fi
9035+
90129036
if test "$ENABLED_IOTSAFE" != "no"
90139037
then
90149038
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_IOTSAFE"
@@ -9769,6 +9793,7 @@ echo " * AES-CTR: $ENABLED_AESCTR"
97699793
echo " * AES-CFB: $ENABLED_AESCFB"
97709794
echo " * AES-OFB: $ENABLED_AESOFB"
97719795
echo " * AES-XTS: $ENABLED_AESXTS"
9796+
echo " * AES-XTS streaming: $ENABLED_AESXTS_STREAM"
97729797
echo " * AES-SIV: $ENABLED_AESSIV"
97739798
echo " * AES-EAX: $ENABLED_AESEAX"
97749799
echo " * AES Bitspliced: $ENABLED_AESBS"

linuxkm/lkcapi_glue.c

Lines changed: 193 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
793797
struct 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,
852866
static 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

linuxkm/x86_vector_register_glue.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,7 @@ static struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc(int create_p)
189189
* dependency loop on intelasm builds, we allocate here.
190190
* this is not thread-safe and doesn't need to be.
191191
*/
192-
int ret = allocate_wolfcrypt_linuxkm_fpu_states();
193-
if (ret != 0)
192+
if ((! create_p) || (allocate_wolfcrypt_linuxkm_fpu_states() != 0))
194193
#endif
195194
{
196195
if (_warned_on_null == 0) {

0 commit comments

Comments
 (0)