]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
libbpf: Implement SHA256 internal helper
authorKP Singh <kpsingh@kernel.org>
Sun, 14 Sep 2025 21:51:32 +0000 (23:51 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 19 Sep 2025 02:11:42 +0000 (19:11 -0700)
Use AF_ALG sockets to not have libbpf depend on OpenSSL. The helper is
used for the loader generation code to embed the metadata hash in the
loader program and also by the bpf_map__make_exclusive API to calculate
the hash of the program the map is exclusive to.

Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: KP Singh <kpsingh@kernel.org>
Link: https://lore.kernel.org/r/20250914215141.15144-4-kpsingh@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/lib/bpf/libbpf.c
tools/lib/bpf/libbpf_internal.h

index fe4fc5438678c51d3df036b1d54120ce7acd127b..a39640bd544812fc5710d2b025217ac5129f4a0c 100644 (file)
@@ -43,6 +43,9 @@
 #include <sys/vfs.h>
 #include <sys/utsname.h>
 #include <sys/resource.h>
+#include <sys/socket.h>
+#include <linux/if_alg.h>
+#include <linux/socket.h>
 #include <libelf.h>
 #include <gelf.h>
 #include <zlib.h>
@@ -14217,3 +14220,59 @@ void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s)
        free(s->progs);
        free(s);
 }
+
+int libbpf_sha256(const void *data, size_t data_sz, void *sha_out, size_t sha_out_sz)
+{
+       struct sockaddr_alg sa = {
+               .salg_family = AF_ALG,
+               .salg_type   = "hash",
+               .salg_name   = "sha256"
+       };
+       int sock_fd = -1;
+       int op_fd = -1;
+       int err = 0;
+
+       if (sha_out_sz != SHA256_DIGEST_LENGTH) {
+               pr_warn("sha_out_sz should be exactly 32 bytes for a SHA256 digest");
+               return -EINVAL;
+       }
+
+       sock_fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
+       if (sock_fd < 0) {
+               err = -errno;
+               pr_warn("failed to create AF_ALG socket for SHA256: %s\n", errstr(err));
+               return err;
+       }
+
+       if (bind(sock_fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
+               err = -errno;
+               pr_warn("failed to bind to AF_ALG socket for SHA256: %s\n", errstr(err));
+               goto out;
+       }
+
+       op_fd = accept(sock_fd, NULL, 0);
+       if (op_fd < 0) {
+               err = -errno;
+               pr_warn("failed to accept from AF_ALG socket for SHA256: %s\n", errstr(err));
+               goto out;
+       }
+
+       if (write(op_fd, data, data_sz) != data_sz) {
+               err = -errno;
+               pr_warn("failed to write data to AF_ALG socket for SHA256: %s\n", errstr(err));
+               goto out;
+       }
+
+       if (read(op_fd, sha_out, SHA256_DIGEST_LENGTH) != SHA256_DIGEST_LENGTH) {
+               err = -errno;
+               pr_warn("failed to read SHA256 from AF_ALG socket: %s\n", errstr(err));
+               goto out;
+       }
+
+out:
+       if (op_fd >= 0)
+               close(op_fd);
+       if (sock_fd >= 0)
+               close(sock_fd);
+       return err;
+}
index 477a3b3389a0914c671cf642c90e00572ad53740..8a055de0d32483e2297ec6c17861b549c8be75a6 100644 (file)
@@ -736,4 +736,8 @@ int elf_resolve_pattern_offsets(const char *binary_path, const char *pattern,
 
 int probe_fd(int fd);
 
+#define SHA256_DIGEST_LENGTH 32
+#define SHA256_DWORD_SIZE SHA256_DIGEST_LENGTH / sizeof(__u64)
+
+int libbpf_sha256(const void *data, size_t data_sz, void *sha_out, size_t sha_out_sz);
 #endif /* __LIBBPF_LIBBPF_INTERNAL_H */