[PATCH 04/12] libbpf: Implement SHA256 internal helper

Andrii Nakryiko andrii.nakryiko at gmail.com
Thu Jun 12 22:55:49 UTC 2025


On Fri, Jun 6, 2025 at 4:29 PM KP Singh <kpsingh at kernel.org> wrote:
>
> 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.
>
> Signed-off-by: KP Singh <kpsingh at kernel.org>
> ---
>  tools/lib/bpf/libbpf.c          | 57 +++++++++++++++++++++++++++++++++
>  tools/lib/bpf/libbpf_internal.h |  9 ++++++
>  2 files changed, 66 insertions(+)
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index e9c641a2fb20..475038d04cb4 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -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>
> @@ -14161,3 +14164,57 @@ void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s)
>         free(s->progs);
>         free(s);
>  }
> +
> +int libbpf_sha256(const void *data, size_t data_size, void *sha_out)

naming convention nit: in libbpf sources we usually use _sz suffix for size

> +{
> +       int sock_fd = -1;
> +       int op_fd = -1;
> +       int err = 0;
> +

nit: unnecessary empty line, please keep all variable decls in one
contiguous block

> +       struct sockaddr_alg sa = {
> +               .salg_family = AF_ALG,
> +               .salg_type   = "hash",
> +               .salg_name   = "sha256"
> +       };
> +
> +       if (!data || !sha_out)
> +               return -EINVAL;

this is internal API, no need for this (and we don't really check for
NULL for mandatory arguments even in public APIs), so let's just drop
this check

if anything, I'd probably require passing sha_out_sz and validate that
it's equal to SHA256_DIGEST_LENGTH to prevent silent corruptions

> +
> +       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 libbpf_err(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_sock;
> +       }
> +
> +       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_sock;
> +       }
> +
> +       if (write(op_fd, data, data_size) != data_size) {
> +               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:
> +       close(op_fd);
> +out_sock:
> +       close(sock_fd);

nit: given you init fds to -1, you can simplify out* jumping to just
single out: clause with if (fd >= 0) close(fd); sequence

> +       return libbpf_err(err);
> +}
> diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
> index 477a3b3389a0..79c6c0dac878 100644
> --- a/tools/lib/bpf/libbpf_internal.h
> +++ b/tools/lib/bpf/libbpf_internal.h
> @@ -736,4 +736,13 @@ int elf_resolve_pattern_offsets(const char *binary_path, const char *pattern,
>
>  int probe_fd(int fd);
>
> +#ifndef SHA256_DIGEST_LENGTH
> +#define SHA256_DIGEST_LENGTH 32
> +#endif
> +
> +#ifndef SHA256_DWORD_SIZE
> +#define SHA256_DWORD_SIZE SHA256_DIGEST_LENGTH / sizeof(__u64)
> +#endif

do we really need ifndef guarding these?...


> +
> +int libbpf_sha256(const void *data, size_t data_size, void *sha_out);
>  #endif /* __LIBBPF_LIBBPF_INTERNAL_H */
> --
> 2.43.0
>



More information about the Linux-security-module-archive mailing list