From 73a34808912e3cfea8d88f0a2c08fc0ed107a9d8 Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@secunet.com>
Date: Fri, 3 Apr 2026 15:06:53 +0200
Subject: [PATCH] fixes found by analysis with LLM

Signed-off-by: Markus Theil <markus.theil@secunet.com>
Signed-off-by: Stephan Mueller <smueller@chronox.de>
(cherry picked from commit e8396c28c2cd2b81f69fc68500fcb2ec7163b4fd)

CVE: CVE-2026-71226
Upstream-Status: Backport [https://github.com/smuellerDD/libkcapi/commit/e8396c28c2cd2b81f69fc68500fcb2ec7163b4fd]
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
 apps/app-internal.c   | 15 +++++++++---
 apps/kcapi-dgst.c     | 11 ++++++---
 apps/kcapi-enc.c      |  9 ++++---
 apps/kcapi-hasher.c   | 12 ++++++---
 apps/kcapi-rng.c      | 24 ++++++++++++------
 configure.ac          |  3 ++-
 lib/kcapi-aead.c      | 12 +++++++--
 lib/kcapi-kdf.c       |  6 +++--
 lib/kcapi-kernel-if.c | 57 +++++++++++++++++++++++++++++--------------
 lib/kcapi-kpp.c       |  4 +--
 lib/kcapi-md.c        |  2 +-
 lib/kcapi-sym.c       |  6 +++++
 lib/kcapi-utils.c     |  7 ++++--
 13 files changed, 118 insertions(+), 50 deletions(-)

diff --git a/apps/app-internal.c b/apps/app-internal.c
index 7e01dd7..724b0b1 100644
--- a/apps/app-internal.c
+++ b/apps/app-internal.c
@@ -173,18 +173,24 @@ static uint8_t bin_char(char hex)
 void hex2bin(const char *hex, uint32_t hexlen, uint8_t *bin, uint32_t binlen)
 {
 	uint32_t i;
-	uint32_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen;
+	uint32_t chars;
 
 	/*
 	 * handle odd-length of strings where the first digit is the least
 	 * significant nibble
 	 */
 	if (hexlen & 1) {
+		if (!binlen)
+			return;
 		bin[0] = bin_char(hex[0]);
 		bin++;
 		hex++;
+		hexlen--;
+		binlen--;
 	}
 
+	chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen;
+
 	for (i = 0; i < chars; i++) {
 		bin[i] = (uint8_t)(bin_char(hex[(i*2)]) << 4);
 		bin[i] |= bin_char(hex[((i*2)+1)]);
@@ -238,13 +244,14 @@ ssize_t read_complete(int fd, uint8_t *buf, size_t buflen)
 		if (0 < ret) {
 			buflen -= (size_t)ret;
 			buf += ret;
+			rc += ret;
 		}
-		rc += ret;
-		if (ret)
-			break;
 	} while ((0 < ret || EINTR == errno || ERESTART == errno)
 		 && buflen > 0);
 
+	if (ret < 0)
+		return -errno;
+
 	return rc;
 }
 
diff --git a/apps/kcapi-dgst.c b/apps/kcapi-dgst.c
index 591a7fb..42d099c 100644
--- a/apps/kcapi-dgst.c
+++ b/apps/kcapi-dgst.c
@@ -128,6 +128,11 @@ static int cipher_op(struct kcapi_handle *handle, struct opt_data *opts)
 	}
 
 	outlen = kcapi_md_digestsize(handle);
+	if (!outlen) {
+		dolog(KCAPI_LOG_ERR, "Cipher has zero digest size");
+		ret = -EINVAL;
+		goto out;
+	}
 
 	if (opts->hexout)
 		outlen *= 2;
@@ -285,8 +290,8 @@ static int set_key(struct kcapi_handle *handle, struct opt_data *opts)
 			}
 
 			while (j < saltbuflen) {
-				ret = kcapi_rng_generate(rng, saltbuf,
-							 (size_t)saltbuflen);
+				ret = kcapi_rng_generate(rng, saltbuf + j,
+							 (size_t)(saltbuflen - j));
 				if (ret < 0) {
 					kcapi_rng_destroy(rng);
 					free(saltbuf);
@@ -320,7 +325,7 @@ static int set_key(struct kcapi_handle *handle, struct opt_data *opts)
 	if (opts->key_fd != -1) {
 		ret = read_complete(opts->key_fd, keybuf, sizeof(keybuf));
 		if (ret < 0)
-			return (int)ret;
+			goto out;
 
 		have_key = 1;
 		keybuflen = (uint32_t)ret;
diff --git a/apps/kcapi-enc.c b/apps/kcapi-enc.c
index 68cf2f7..e7aa9db 100644
--- a/apps/kcapi-enc.c
+++ b/apps/kcapi-enc.c
@@ -218,7 +218,7 @@ static ssize_t return_data_fd(struct kcapi_handle *handle,
 	}
 
 out:
-	munmap(outmem, outsize);
+	munmap(outmem, outsize + offset);
 	return (ret < 0) ? ret : generated_bytes;
 }
 
@@ -609,7 +609,7 @@ static int cipher_op(struct kcapi_handle *handle, struct opt_data *opts)
 		}
 
 	/* Get data from file. */
-	} else {
+	} else if (insb.st_size) {
 		uint32_t sent_data = 0;
 
 		inmem = mmap(NULL, (size_t)insb.st_size, PROT_READ, MAP_SHARED,
@@ -636,6 +636,7 @@ static int cipher_op(struct kcapi_handle *handle, struct opt_data *opts)
 			 * we will not apply padding.
 			 */
 			if (!opts->decrypt &&
+			    insb.st_size >= 2 &&
 			    !(insb.st_size % opts->func_blocksize(handle)) &&
 			    (uint32_t)padbyte < opts->func_blocksize(handle)) {
 				uint32_t i;
@@ -803,8 +804,8 @@ static int set_key(struct kcapi_handle *handle, struct opt_data *opts)
 			}
 
 			while (j < saltbuflen) {
-				ret = kcapi_rng_generate(rng, saltbuf,
-							 saltbuflen);
+				ret = kcapi_rng_generate(rng, saltbuf + j,
+							 saltbuflen - j);
 				if (ret < 0) {
 					kcapi_rng_destroy(rng);
 					free(saltbuf);
diff --git a/apps/kcapi-hasher.c b/apps/kcapi-hasher.c
index 217f59d..90dc34d 100644
--- a/apps/kcapi-hasher.c
+++ b/apps/kcapi-hasher.c
@@ -271,7 +271,7 @@ static int load_file(const char *filename, uint8_t **memory, off_t *size)
 				fprintf(stderr, "Key longer than UINT32_MAX\n");
 				ret = -ERANGE;
 				goto out;
-			} else if (buffer_size * 2 < buffer_size)
+			} else if (buffer_size > UINT32_MAX / 2)
 				buffer_size = UINT32_MAX;
 			else
 				buffer_size *= 2;
@@ -340,7 +340,7 @@ static int hasher(struct kcapi_handle *handle, const struct hash_params *params,
 			} while (left);
 			munmap(memblock, mapped);
 			offset = offset + (off_t)mapped;
-		} while (offset ^ size);
+		} while (offset != size);
 	} else {
 		uint8_t tmpbuf[TMPBUFLEN] __aligned(KCAPI_APP_ALIGN);
 		uint32_t bufsize;
@@ -647,11 +647,17 @@ static int process_checkfile(const struct hash_params *params,
 			hexhash = buf;
 
 		if (bsd_style) {
+			if (bsd_style > linelen) {
+				fprintf(stderr, "Invalid checkfile format\n");
+				ret = 1;
+				goto out;
+			}
+
 			/* Hash starts after separator */
 			hexhashlen = linelen - bsd_style + 1;
 
 			/* remove closing parenthesis behind filename */
-			if (buf[(bsd_style - 4)] == ')')
+			if (bsd_style >= 4 && buf[(bsd_style - 4)] == ')')
 				buf[(bsd_style - 4)] = '\0';
 		}
 
diff --git a/apps/kcapi-rng.c b/apps/kcapi-rng.c
index 9e025cd..46dab02 100644
--- a/apps/kcapi-rng.c
+++ b/apps/kcapi-rng.c
@@ -282,16 +282,18 @@ int main(int argc, char *argv[])
 	      seedsize);
 
 	if (!isatty(0) && (errno == EINVAL || errno == ENOTTY)) {
-		while (fgets((char *)seedbuf, (int)seedsize, stdin)) {
-			ret = kcapi_rng_seed(rng, seedbuf, seedsize);
+		ssize_t rret;
+
+		while ((rret = read(STDIN_FILENO, seedbuf, seedsize)) > 0) {
+			ret = kcapi_rng_seed(rng, seedbuf, (uint32_t)rret);
 			if (ret)
 				dolog(KCAPI_LOG_WARN,
-				      "User-provided seed of %lu bytes not accepted by DRNG (error: %ld)",
-				      (unsigned long)sizeof(buf), ret);
+				      "User-provided seed of %zd bytes not accepted by DRNG (error: %ld)",
+				      rret, ret);
 			else
 				dolog(KCAPI_LOG_DEBUG,
-				      "User-provided seed of %u bytes",
-				      seedsize);
+				      "User-provided seed of %zd bytes",
+				      rret);
 		}
 	}
 
@@ -312,9 +314,15 @@ int main(int argc, char *argv[])
 			char hexbuf[2 * KCAPI_RNG_BUFSIZE];
 
 			bin2hex(buf, (size_t)ret, hexbuf, sizeof(hexbuf), 0);
-			fwrite(hexbuf, 2 * (size_t)ret, 1, stdout);
+			if (fwrite(hexbuf, 2 * (size_t)ret, 1, stdout) != 1) {
+				ret = -EIO;
+				goto out;
+			}
 		} else {
-			fwrite(buf, (size_t)ret, 1, stdout);
+			if (fwrite(buf, (size_t)ret, 1, stdout) != 1) {
+				ret = -EIO;
+				goto out;
+			}
 		}
 
 		outlen -= (size_t)ret;
diff --git a/configure.ac b/configure.ac
index fbae4f9..446b8a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,16 +14,17 @@ m4_define([__KCAPI_MINVERSION], [5])
 m4_define([__KCAPI_PATCHLEVEL], [0])
 m4_define([KCAPI_VERSION], [__KCAPI_MAJVERSION.__KCAPI_MINVERSION.__KCAPI_PATCHLEVEL])
 
+AC_PREREQ([2.69])
 AC_INIT([libkcapi], [KCAPI_VERSION])
 AC_DEFINE([KCAPI_MAJVERSION], [__KCAPI_MAJVERSION])
 AC_DEFINE([KCAPI_MINVERSION], [__KCAPI_MINVERSION])
 AC_DEFINE([KCAPI_PATCHLEVEL], [__KCAPI_PATCHLEVEL])
+AC_CONFIG_MACRO_DIRS([m4])
 AM_INIT_AUTOMAKE([foreign])
 LT_INIT([pic-only])
 AC_SUBST([LIBTOOL_DEPS])
 AC_PROG_CC
 AC_CONFIG_FILES([Makefile])
-AC_CONFIG_MACRO_DIR([m4])
 AX_PROG_CC_FOR_BUILD
 AX_CHECK_PIE
 
diff --git a/lib/kcapi-aead.c b/lib/kcapi-aead.c
index b52dda0..3a7d711 100644
--- a/lib/kcapi-aead.c
+++ b/lib/kcapi-aead.c
@@ -566,7 +566,11 @@ size_t impl_aead_outbuflen_enc(struct kcapi_handle *handle,
 {
 	struct kcapi_handle_tfm *tfm = handle->tfm;
 	uint32_t bs = tfm->info.blocksize;
-	size_t outlen = (inlen + bs - 1) / bs * bs + taglen + assoclen;
+	size_t outlen;
+
+	if (!bs)
+		return 0;
+	outlen = (inlen + bs - 1) / bs * bs + taglen + assoclen;
 
 	/* the kernel does not like zero length output buffers */
 	if (!outlen)
@@ -591,7 +595,11 @@ size_t impl_aead_outbuflen_dec(struct kcapi_handle *handle,
 {
 	struct kcapi_handle_tfm *tfm = handle->tfm;
 	uint32_t bs = tfm->info.blocksize;
-	size_t outlen = (inlen + bs - 1) / bs * bs + assoclen;
+	size_t outlen;
+
+	if (!bs)
+		return 0;
+	outlen = (inlen + bs - 1) / bs * bs + assoclen;
 
 	if (!handle->flags.ge_v4_9 == true)
 		outlen += taglen;
diff --git a/lib/kcapi-kdf.c b/lib/kcapi-kdf.c
index 54dc1ec..5f389b6 100644
--- a/lib/kcapi-kdf.c
+++ b/lib/kcapi-kdf.c
@@ -54,6 +54,8 @@
 #include "kcapi.h"
 #include "internal.h"
 
+#define MAX_DIGESTSIZE 64
+
 #ifndef __has_builtin
 # define __has_builtin(x) 0
 #endif
@@ -101,7 +103,7 @@ ssize_t impl_kdf_dpi(struct kcapi_handle *handle,
 	ssize_t err = 0;
 	uint8_t *dst_orig = dst;
 	size_t dlen_orig = dlen;
-	uint8_t Ai[h];
+	uint8_t Ai[MAX_DIGESTSIZE];
 	uint32_t i = 1;
 
 	if (dlen > INT_MAX)
@@ -448,7 +450,7 @@ static inline uint64_t kcapi_get_time(void)
 {
 	struct timespec time;
 
-	if (clock_gettime(CLOCK_REALTIME, &time) == 0)
+	if (clock_gettime(CLOCK_MONOTONIC, &time) == 0)
 		return (uint64_t)time.tv_nsec;
 
 	return 0;
diff --git a/lib/kcapi-kernel-if.c b/lib/kcapi-kernel-if.c
index 835e45a..b37f0dc 100644
--- a/lib/kcapi-kernel-if.c
+++ b/lib/kcapi-kernel-if.c
@@ -216,7 +216,7 @@ ssize_t _kcapi_common_send_meta(struct kcapi_handle *handle,
 		}
 		header->cmsg_level = SOL_ALG;
 		header->cmsg_type = ALG_SET_IV;
-		header->cmsg_len = kcapi_downcast_socklen_t(iv_msg_size);
+		header->cmsg_len = CMSG_LEN(iv_msg_size);
 		alg_iv = (void*)CMSG_DATA(header);
 		alg_iv->ivlen = tfm->info.ivsize;
 		memcpy(alg_iv->iv, handle->cipher.iv, tfm->info.ivsize);
@@ -409,8 +409,10 @@ ssize_t _kcapi_common_vmsplice_chunk(struct kcapi_handle *handle,
 				    "AF_ALG: splice syscall returned %zd", ret);
 		}
 
+		if (ret == 0)
+			return -EPIPE;
 		processed += ret;
-		inlen -= (uint32_t)ret;
+		inlen -= (size_t)ret;
 	}
 
 	return processed;
@@ -434,14 +436,17 @@ int _kcapi_aio_read_all(struct kcapi_handle *handle, size_t toread,
 
 		for (i = 0; i < rc; i++) {
 			struct iocb *cb;
+			unsigned int idx = (unsigned int)events[i].data;
+
+			if (idx >= KCAPI_AIO_CONCURRENT)
+				return -EOVERFLOW;
 
 			/*
 			 * If one cipher operation fails, so will the entire
 			 * AIO operation
 			 */
 			if (events[i].res < 0) {
-				handle->aio.iocb_ret[events[i].data] =
-							events[i].res;
+				handle->aio.iocb_ret[idx] = events[i].res;
 				return (int)events[i].res;
 			}
 
@@ -452,16 +457,15 @@ int _kcapi_aio_read_all(struct kcapi_handle *handle, size_t toread,
 			 * return code.
 			 */
 			if (events[i].res > 0) {
-				handle->aio.iocb_ret[events[i].data] =
-								events[i].res;
+				handle->aio.iocb_ret[idx] = events[i].res;
 			} else {
-				handle->aio.iocb_ret[events[i].data] =
+				handle->aio.iocb_ret[idx] =
 							(__s64)cb->aio_nbytes;
 			}
 
 			cb->aio_fildes = 0;
 		}
-		toread -= (uint32_t)rc;
+		toread -= (size_t)rc;
 	}
 
 	return 0;
@@ -613,7 +617,7 @@ ssize_t _kcapi_common_read_data(struct kcapi_handle *handle,
 			ret = read(*_kcapi_get_opfd(handle), out, outlen);
 			if (ret > 0) {
 				out += ret;
-				outlen -= (uint32_t)ret;
+				outlen -= (size_t)ret;
 				totallen += ret;
 			}
 			kcapi_dolog(KCAPI_LOG_DEBUG,
@@ -722,13 +726,13 @@ static int __kcapi_common_getinfo(struct kcapi_handle *handle,
 		goto out;
 	}
 	if (addr_len != sizeof(nl)) {
-		ret = -errno;
+		ret = -EPROTO;
 		kcapi_dolog(KCAPI_LOG_ERR,
 			    "Netlink error: wrong address length %d", addr_len);
 		goto out;
 	}
 	if (nl.nl_family != AF_NETLINK) {
-		ret = -errno;
+		ret = -EPROTO;
 		kcapi_dolog(KCAPI_LOG_ERR,
 			    "Netlink error: wrong address family %d",
 			    nl.nl_family);
@@ -764,12 +768,12 @@ static int __kcapi_common_getinfo(struct kcapi_handle *handle,
 			goto out;
 		}
 		if (rc == 0) {
-			ret = -errno;
+			ret = -ENODATA;
 			kcapi_dolog(KCAPI_LOG_ERR, "Netlink error: no data");
 			goto out;
 		}
 		if (rc > (ssize_t)sizeof(buf)) {
-			ret = -errno;
+			ret = -EOVERFLOW;
 			kcapi_dolog(KCAPI_LOG_ERR,
 				    "Netlink error: received too much data");
 			goto out;
@@ -779,6 +783,12 @@ static int __kcapi_common_getinfo(struct kcapi_handle *handle,
 
 	ret = -EFAULT;
 	res_len = res_n->nlmsg_len;
+	if (res_len > sizeof(buf)) {
+		kcapi_dolog(KCAPI_LOG_ERR,
+			    "Netlink error: nlmsg_len %lu exceeds buffer",
+			    res_len);
+		goto out;
+	}
 	if (res_n->nlmsg_type == NLMSG_ERROR) {
 		/*
 		 * return -EAGAIN -- this error will occur if we received a
@@ -819,6 +829,9 @@ static int __kcapi_common_getinfo(struct kcapi_handle *handle,
 
 	if (tb[CRYPTOCFGA_REPORT_HASH]) {
 		struct rtattr *rta = tb[CRYPTOCFGA_REPORT_HASH];
+
+		if (RTA_PAYLOAD(rta) < sizeof(struct crypto_report_hash))
+			goto out;
 		struct crypto_report_hash *rsh =
 			(struct crypto_report_hash *) RTA_DATA(rta);
 		tfm->info.hash_digestsize = rsh->digestsize;
@@ -831,6 +844,9 @@ static int __kcapi_common_getinfo(struct kcapi_handle *handle,
 	}
 	if (tb[CRYPTOCFGA_REPORT_BLKCIPHER]) {
 		struct rtattr *rta = tb[CRYPTOCFGA_REPORT_BLKCIPHER];
+
+		if (RTA_PAYLOAD(rta) < sizeof(struct crypto_report_blkcipher))
+			goto out;
 		struct crypto_report_blkcipher *rblk =
 			(struct crypto_report_blkcipher *) RTA_DATA(rta);
 		tfm->info.blocksize = rblk->blocksize;
@@ -845,6 +861,9 @@ static int __kcapi_common_getinfo(struct kcapi_handle *handle,
 	}
 	if (tb[CRYPTOCFGA_REPORT_AEAD]) {
 		struct rtattr *rta = tb[CRYPTOCFGA_REPORT_AEAD];
+
+		if (RTA_PAYLOAD(rta) < sizeof(struct crypto_report_aead))
+			goto out;
 		struct crypto_report_aead *raead =
 			(struct crypto_report_aead *) RTA_DATA(rta);
 		tfm->info.blocksize = raead->blocksize;
@@ -858,6 +877,9 @@ static int __kcapi_common_getinfo(struct kcapi_handle *handle,
 	}
 	if (tb[CRYPTOCFGA_REPORT_RNG]) {
 		struct rtattr *rta = tb[CRYPTOCFGA_REPORT_RNG];
+
+		if (RTA_PAYLOAD(rta) < sizeof(struct crypto_report_rng))
+			goto out;
 		struct crypto_report_rng *rrng =
 			(struct crypto_report_rng *) RTA_DATA(rta);
 		tfm->info.rng_seedsize = rrng->seedsize;
@@ -981,19 +1003,19 @@ static int _kcapi_get_kernver(struct kcapi_handle *handle)
 	/* 3.15.0 */
 	res = strtok_r(kernel.release, ".", &saveptr);
 	if (!res) {
-		printf("Could not parse kernel version");
+		kcapi_dolog(KCAPI_LOG_ERR, "Could not parse kernel version");
 		return -EFAULT;
 	}
 	tfm->sysinfo.kernel_maj = strtoul(res, NULL, 10);
 	res = strtok_r(NULL, ".", &saveptr);
 	if (!res) {
-		printf("Could not parse kernel version");
+		kcapi_dolog(KCAPI_LOG_ERR, "Could not parse kernel version");
 		return -EFAULT;
 	}
 	tfm->sysinfo.kernel_minor = strtoul(res, NULL, 10);
 	res = strtok_r(NULL, ".", &saveptr);
 	if (!res) {
-		printf("Could not parse kernel version");
+		kcapi_dolog(KCAPI_LOG_ERR, "Could not parse kernel version");
 		return -EFAULT;
 	}
 	tfm->sysinfo.kernel_patchlevel = strtoul(res, NULL, 10);
@@ -1217,7 +1239,6 @@ static int _kcapi_handle_init_tfm(struct kcapi_handle *handle, const char *type,
 
 	ret = _kcapi_common_getinfo(handle, ciphername);
 	if (ret) {
-		ret = -errno;
 		kcapi_dolog(KCAPI_LOG_ERR, "NETLINK_CRYPTO: cannot obtain cipher information for %s (is required crypto_user.c patch missing? see documentation)",
 			    ciphername);
 		return ret;
@@ -1368,7 +1389,7 @@ ssize_t _kcapi_cipher_crypt_chunk(struct kcapi_handle *handle,
 		in += inprocess;
 		inlen -= inprocess;
 		out += ret;
-		outlen -= (uint32_t)ret;
+		outlen -= (size_t)ret;
 	}
 
 	return totallen;
diff --git a/lib/kcapi-kpp.c b/lib/kcapi-kpp.c
index 814485a..d0383d6 100644
--- a/lib/kcapi-kpp.c
+++ b/lib/kcapi-kpp.c
@@ -52,12 +52,12 @@ int kcapi_kpp_ecdh_setcurve(struct kcapi_handle *handle,
 			    unsigned long curve_id)
 {
 	struct kcapi_handle_tfm *tfm = handle->tfm;
-	char curve_id_str[sizeof(unsigned long)];
+	char curve_id_str[24];
 	int ret = 0;
 
 	snprintf(curve_id_str, sizeof(curve_id_str), "%lu", curve_id);
 	ret = setsockopt(tfm->tfmfd, SOL_ALG, ALG_SET_ECDH_CURVE,
-			 curve_id_str, sizeof(curve_id_str));
+			 curve_id_str, (socklen_t)strlen(curve_id_str));
 	return (ret >= 0) ? ret : -errno;
 }
 
diff --git a/lib/kcapi-md.c b/lib/kcapi-md.c
index bddd76b..5f493eb 100644
--- a/lib/kcapi-md.c
+++ b/lib/kcapi-md.c
@@ -196,7 +196,7 @@ ssize_t impl_md_sha256(const uint8_t *in, size_t inlen,
 }
 
 ORIG_SYMVER(md_sha256, "1.0.0")
-ssize_t orig_md_sha256(const uint8_t *in, uint32_t inlen,
+int32_t orig_md_sha256(const uint8_t *in, uint32_t inlen,
 		       uint8_t *out, uint32_t outlen)
 {
 	return (int32_t)kcapi_md_conv_common("sha256", in, inlen, out, outlen);
diff --git a/lib/kcapi-sym.c b/lib/kcapi-sym.c
index 911ec1e..d500061 100644
--- a/lib/kcapi-sym.c
+++ b/lib/kcapi-sym.c
@@ -47,6 +47,9 @@ ssize_t impl_cipher_encrypt(struct kcapi_handle *handle,
 	struct kcapi_handle_tfm *tfm = handle->tfm;
 	uint32_t bs = tfm->info.blocksize;
 
+	if (!bs)
+		return -EINVAL;
+
 	/* require properly sized output data size */
 	if (outlen < ((inlen + bs - 1) / bs * bs))
 		kcapi_dolog(KCAPI_LOG_WARN,
@@ -120,6 +123,9 @@ ssize_t impl_cipher_decrypt(struct kcapi_handle *handle,
 {
 	struct kcapi_handle_tfm *tfm = handle->tfm;
 
+	if (!tfm->info.blocksize)
+		return -EINVAL;
+
 	/* require properly sized output data size */
 	if (inlen % tfm->info.blocksize)
 		kcapi_dolog(KCAPI_LOG_WARN,
diff --git a/lib/kcapi-utils.c b/lib/kcapi-utils.c
index 46fd330..e801d29 100644
--- a/lib/kcapi-utils.c
+++ b/lib/kcapi-utils.c
@@ -96,7 +96,7 @@ err:
 	} else {
 		kcapi_dolog(KCAPI_LOG_WARN,
 			    "AF_ALG: setting maximum splice pipe size to %u failed: %s",
-			    size, strerror(ret));
+			    size, strerror(-ret));
 	}
 	return ret;
 }
@@ -109,7 +109,10 @@ int kcapi_get_maxsplicesize(struct kcapi_handle *handle)
 		return -EINVAL;
 
 	/* Both pipe endpoints should have the same pipe size */
-	handle->pipesize = (unsigned int)fcntl(handle->pipes[0], F_GETPIPE_SZ);
+	int ret = fcntl(handle->pipes[0], F_GETPIPE_SZ);
+	if (ret < 0)
+		return -errno;
+	handle->pipesize = (unsigned int)ret;
 
 	/*
 	 * For vmsplice to allow the maximum number of 16 pages, we need to
