From b612c52c5ccf021d01e6c786db1a31a697f21d97 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Thu, 13 Aug 2020 21:58:07 +0200 Subject: [PATCH] Kern 5.8: fix MSG_MORE usage With kernel 5.8, a precise use of MSG_MORE is mandatory to support a stream cipher approach (init -> update -> update -> ... -> final). All but the last update operations must use MSG_MORE, the last update operation must not use MSG_MORE. Reported-by: Ondrej Mosnacek Signed-off-by: Stephan Mueller --- lib/kcapi-aead.c | 24 ++++++++++++++---------- lib/kcapi-kernel-if.c | 6 ++---- test/kcapi-main.c | 31 +++++++++++++++++-------------- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/lib/kcapi-aead.c b/lib/kcapi-aead.c index d241618..45a0bd7 100644 --- a/lib/kcapi-aead.c +++ b/lib/kcapi-aead.c @@ -210,13 +210,15 @@ _kcapi_aead_encrypt_aio_fallback(struct kcapi_handle *handle, uint32_t iovlen, const uint8_t *iv) { uint32_t i; - int32_t ret = kcapi_aead_stream_init_enc(handle, iv, NULL, 0); - - if (ret < 0) - return ret; + int32_t ret = 0; for (i = 0; i < iovlen; i++) { - int rc = kcapi_aead_stream_update_last(handle, iniov, 1); + int rc = kcapi_aead_stream_init_enc(handle, iv, NULL, 0); + + if (rc < 0) + return rc; + + rc = kcapi_aead_stream_update_last(handle, iniov, 1); if (rc < 0) return rc; @@ -271,13 +273,15 @@ _kcapi_aead_decrypt_aio_fallback(struct kcapi_handle *handle, uint32_t iovlen, const uint8_t *iv) { uint32_t i; - int32_t ret = kcapi_aead_stream_init_dec(handle, iv, NULL, 0); - - if (ret < 0) - return ret; + int32_t ret = 0; for (i = 0; i < iovlen; i++) { - int rc = kcapi_aead_stream_update_last(handle, iniov, 1); + int rc = kcapi_aead_stream_init_dec(handle, iv, NULL, 0); + + if (rc < 0) + return rc; + + rc = kcapi_aead_stream_update_last(handle, iniov, 1); if (rc < 0) return rc; diff --git a/lib/kcapi-kernel-if.c b/lib/kcapi-kernel-if.c index bea994f..42cf1ad 100644 --- a/lib/kcapi-kernel-if.c +++ b/lib/kcapi-kernel-if.c @@ -439,8 +439,7 @@ int _kcapi_aio_send_iov(struct kcapi_handle *handle, struct iovec *iov, if (0 > ret) return ret; } else { - ret = _kcapi_common_send_meta(handle, NULL, 0, enc, - len ? MSG_MORE : 0); + ret = _kcapi_common_send_meta(handle, NULL, 0, enc, MSG_MORE); if (0 > ret) return ret; ret = _kcapi_common_vmsplice_iov(handle, iov, iovlen, 0); @@ -1246,8 +1245,7 @@ int32_t _kcapi_cipher_crypt(struct kcapi_handle *handle, const uint8_t *in, if (0 > ret) return ret; } else { - ret = _kcapi_common_send_meta(handle, NULL, 0, enc, - inlen ? MSG_MORE : 0); + ret = _kcapi_common_send_meta(handle, NULL, 0, enc, MSG_MORE); if (0 > ret) return ret; ret = _kcapi_common_vmsplice_chunk(handle, in, inlen, 0); diff --git a/test/kcapi-main.c b/test/kcapi-main.c index 51f6ec7..64e466c 100644 --- a/test/kcapi-main.c +++ b/test/kcapi-main.c @@ -846,7 +846,7 @@ static int cavs_sym(struct kcapi_cavs *cavs_test, uint32_t loops, goto out; } - for(i = 0; i < loops; i++) { + for (i = 0; i < loops; i++) { _get_time(&begin); if (cavs_test->enc) { ret = kcapi_cipher_encrypt(handle, @@ -886,7 +886,7 @@ static int cavs_sym(struct kcapi_cavs *cavs_test, uint32_t loops, } static void mt_sym_writer(struct kcapi_handle *handle, struct iovec *iov, - int forking) + int forking, int last) { int ret; @@ -899,7 +899,10 @@ static void mt_sym_writer(struct kcapi_handle *handle, struct iovec *iov, return; } - ret = kcapi_cipher_stream_update_last(handle, iov, 1); + if (last) + ret = kcapi_cipher_stream_update_last(handle, iov, 1); + else + ret = kcapi_cipher_stream_update(handle, iov, 1); if (0 > ret) printf("Sending of data failed\n"); @@ -1004,7 +1007,7 @@ static int cavs_sym_stream(struct kcapi_cavs *cavs_test, uint32_t loops, iov.iov_len = cavs_test->ctlen; } - mt_sym_writer(handle_ptr, &iov, forking); + mt_sym_writer(handle_ptr, &iov, forking, i == (loops * 2 - 1)); outiov.iov_base = outbuf_ptr; outiov.iov_len = outbuflen; @@ -1636,21 +1639,21 @@ static int cavs_aead_stream(struct kcapi_cavs *cavs_test, uint32_t loops, if (ret) goto out; - if (cavs_test->enc) - ret = kcapi_aead_stream_init_enc(handle, newiv, NULL, 0); - - else - ret = kcapi_aead_stream_init_dec(handle, newiv, NULL, 0); - if (0 > ret) { - printf("Initialization of cipher buffer failed\n"); - goto out; - } - for (i = 0; i < loops; i++) { int errsv = 0; memset(outbuf, 0, outbuflen); + if (cavs_test->enc) + ret = kcapi_aead_stream_init_enc(handle, newiv, NULL, 0); + else + ret = kcapi_aead_stream_init_dec(handle, newiv, NULL, 0); + if (0 > ret) { + printf("Initialization of cipher buffer failed\n"); + goto out; + } + + iov.iov_base = cavs_test->assoc; iov.iov_len = cavs_test->assoclen; if (cavs_test->enc) {