Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crypto/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ obj-$(CONFIG_CRYPTO_ECHAINIV) += echainiv.o
crypto_hash-y += ahash.o
crypto_hash-y += shash.o
obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
ifeq ($(CONFIG_BPF_SYSCALL),y)
obj-$(CONFIG_CRYPTO_HASH2) += bpf_crypto_shash.o
endif

obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
obj-$(CONFIG_CRYPTO_SIG2) += sig.o
Expand Down
95 changes: 95 additions & 0 deletions crypto/bpf_crypto_shash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
#include <linux/types.h>
#include <linux/module.h>
#include <linux/bpf_crypto.h>
#include <crypto/hash.h>

struct bpf_shash_ctx {
struct crypto_shash *tfm;
struct shash_desc desc;
};

static void *bpf_crypto_shash_alloc_tfm(const char *algo)
{
struct bpf_shash_ctx *ctx;
struct crypto_shash *tfm;

tfm = crypto_alloc_shash(algo, 0, 0);
if (IS_ERR(tfm))
return tfm;

ctx = kzalloc(sizeof(*ctx) + crypto_shash_descsize(tfm), GFP_KERNEL);
if (!ctx) {
crypto_free_shash(tfm);
return ERR_PTR(-ENOMEM);
}

ctx->tfm = tfm;
ctx->desc.tfm = tfm;

return ctx;
}

static void bpf_crypto_shash_free_tfm(void *tfm)
{
struct bpf_shash_ctx *ctx = tfm;

crypto_free_shash(ctx->tfm);
kfree(ctx);
}

static int bpf_crypto_shash_has_algo(const char *algo)
{
return crypto_has_shash(algo, 0, 0);
}

static int bpf_crypto_shash_hash(void *tfm, const u8 *data, u8 *out,
unsigned int len)
{
struct bpf_shash_ctx *ctx = tfm;

return crypto_shash_digest(&ctx->desc, data, len, out);
}

static unsigned int bpf_crypto_shash_digestsize(void *tfm)
{
struct bpf_shash_ctx *ctx = tfm;

return crypto_shash_digestsize(ctx->tfm);
}

static u32 bpf_crypto_shash_get_flags(void *tfm)
{
struct bpf_shash_ctx *ctx = tfm;

return crypto_shash_get_flags(ctx->tfm);
}

static const struct bpf_crypto_type bpf_crypto_shash_type = {
.alloc_tfm = bpf_crypto_shash_alloc_tfm,
.free_tfm = bpf_crypto_shash_free_tfm,
.has_algo = bpf_crypto_shash_has_algo,
.hash = bpf_crypto_shash_hash,
.digestsize = bpf_crypto_shash_digestsize,
.get_flags = bpf_crypto_shash_get_flags,
.owner = THIS_MODULE,
.name = "hash",
};

static int __init bpf_crypto_shash_init(void)
{
return bpf_crypto_register_type(&bpf_crypto_shash_type);
}

static void __exit bpf_crypto_shash_exit(void)
{
int err = bpf_crypto_unregister_type(&bpf_crypto_shash_type);

WARN_ON_ONCE(err);
}

module_init(bpf_crypto_shash_init);
module_exit(bpf_crypto_shash_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Hash algorithm support for BPF");
2 changes: 2 additions & 0 deletions include/linux/bpf_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ struct bpf_crypto_type {
int (*setauthsize)(void *tfm, unsigned int authsize);
int (*encrypt)(void *tfm, const u8 *src, u8 *dst, unsigned int len, u8 *iv);
int (*decrypt)(void *tfm, const u8 *src, u8 *dst, unsigned int len, u8 *iv);
int (*hash)(void *tfm, const u8 *data, u8 *out, unsigned int len);
unsigned int (*ivsize)(void *tfm);
unsigned int (*statesize)(void *tfm);
unsigned int (*digestsize)(void *tfm);
u32 (*get_flags)(void *tfm);
struct module *owner;
char name[14];
Expand Down
Loading
Loading