Commit d47cc4de authored by Eric Biggers's avatar Eric Biggers Committed by Andrii Nakryiko
Browse files

bpf: Use sha1() instead of sha1_transform() in bpf_prog_calc_tag()



Now that there's a proper SHA-1 library API, just use that instead of
the low-level SHA-1 compression function.  This eliminates the need for
bpf_prog_calc_tag() to implement the SHA-1 padding itself.  No
functional change; the computed tags remain the same.

Signed-off-by: default avatarEric Biggers <ebiggers@kernel.org>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20250811201615.564461-1-ebiggers@kernel.org
parent 0780f54a
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -997,12 +997,6 @@ static inline u32 bpf_prog_insn_size(const struct bpf_prog *prog)
	return prog->len * sizeof(struct bpf_insn);
}

static inline u32 bpf_prog_tag_scratch_size(const struct bpf_prog *prog)
{
	return round_up(bpf_prog_insn_size(prog) +
			sizeof(__be64) + 1, SHA1_BLOCK_SIZE);
}

static inline unsigned int bpf_prog_size(unsigned int proglen)
{
	return max(sizeof(struct bpf_prog),
+9 −41
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
 */

#include <uapi/linux/btf.h>
#include <crypto/sha1.h>
#include <linux/filter.h>
#include <linux/skbuff.h>
#include <linux/vmalloc.h>
@@ -293,28 +294,19 @@ void __bpf_prog_free(struct bpf_prog *fp)

int bpf_prog_calc_tag(struct bpf_prog *fp)
{
	const u32 bits_offset = SHA1_BLOCK_SIZE - sizeof(__be64);
	u32 raw_size = bpf_prog_tag_scratch_size(fp);
	u32 digest[SHA1_DIGEST_WORDS];
	u32 ws[SHA1_WORKSPACE_WORDS];
	u32 i, bsize, psize, blocks;
	size_t size = bpf_prog_insn_size(fp);
	u8 digest[SHA1_DIGEST_SIZE];
	struct bpf_insn *dst;
	bool was_ld_map;
	u8 *raw, *todo;
	__be32 *result;
	__be64 *bits;
	u32 i;

	raw = vmalloc(raw_size);
	if (!raw)
	dst = vmalloc(size);
	if (!dst)
		return -ENOMEM;

	sha1_init_raw(digest);
	memset(ws, 0, sizeof(ws));

	/* We need to take out the map fd for the digest calculation
	 * since they are unstable from user space side.
	 */
	dst = (void *)raw;
	for (i = 0, was_ld_map = false; i < fp->len; i++) {
		dst[i] = fp->insnsi[i];
		if (!was_ld_map &&
@@ -334,33 +326,9 @@ int bpf_prog_calc_tag(struct bpf_prog *fp)
			was_ld_map = false;
		}
	}

	psize = bpf_prog_insn_size(fp);
	memset(&raw[psize], 0, raw_size - psize);
	raw[psize++] = 0x80;

	bsize  = round_up(psize, SHA1_BLOCK_SIZE);
	blocks = bsize / SHA1_BLOCK_SIZE;
	todo   = raw;
	if (bsize - psize >= sizeof(__be64)) {
		bits = (__be64 *)(todo + bsize - sizeof(__be64));
	} else {
		bits = (__be64 *)(todo + bsize + bits_offset);
		blocks++;
	}
	*bits = cpu_to_be64((psize - 1) << 3);

	while (blocks--) {
		sha1_transform(digest, todo, ws);
		todo += SHA1_BLOCK_SIZE;
	}

	result = (__force __be32 *)digest;
	for (i = 0; i < SHA1_DIGEST_WORDS; i++)
		result[i] = cpu_to_be32(digest[i]);
	memcpy(fp->tag, result, sizeof(fp->tag));

	vfree(raw);
	sha1((const u8 *)dst, size, digest);
	memcpy(fp->tag, digest, sizeof(fp->tag));
	vfree(dst);
	return 0;
}