Re: [PATCH BlueZ v2 1/3] src: add HMAC-SHA256 to bt_crypto using kernel AF_ALG

Luiz Augusto von Dentz <[email protected]>
Newsgroups org.kernel.vger.linux-bluetooth
Message-ID <CABBYNZ+mrXB0jju86xd7VcxW=WU3vO=sK1vL-N5QRbXuQvEguQ@mail.gmail.com>
Hi Pakrohk,

On Tue, Jul 21, 2026 at 10:17 AM Pakrohk <[email protected]> wrote:
>
> From: Pakrohk <[email protected]>
>
> Add HMAC-SHA256 computation to the bt_crypto library using the Linux
> kernel AF_ALG interface. This follows the exact same pattern as the
> existing cmac(aes) implementation.
>
> The HMAC-SHA256 function is needed for verifying external quirk profile
> signatures. The previous implementation used popen("openssl dgst ...")
> which had command injection risks and an openssl CLI dependency.
>
> Using kernel AF_ALG:
>   - No external library dependencies
>   - Matches existing BlueZ crypto patterns
>   - No shell invocation or temp files
>   - Works in bluetoothd's process context

Well I guess kernel crypto doesn't want us to add new usage like this
since AF_ALG is to be considered deprecated, even though I have to
agree it is much simpler and probably safer than using an external
crypto library.

> The hmac(sha256) algorithm is available in all modern Linux kernels
> via the crypto API (/proc/crypto).
>
> Signed-off-by: Pakrohk <[email protected]>
> diff --git a/src/shared/crypto.c b/src/shared/crypto.c
> index cb99116..f5883bd 100644
> --- a/src/shared/crypto.c
> +++ b/src/shared/crypto.c
> @@ -69,6 +69,7 @@ struct bt_crypto {
>         int ecb_aes;
>         int urandom;
>         int cmac_aes;
> +       int hmac_sha256;
>  };
>
>  static int urandom_setup(void)
> @@ -126,6 +127,28 @@ static int cmac_aes_setup(void)
>         return fd;
>  }
>
> +static int hmac_sha256_setup(void)
> +{
> +       struct sockaddr_alg salg;
> +       int fd;
> +
> +       fd = socket(PF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
> +       if (fd < 0)
> +               return -1;
> +
> +       memset(&salg, 0, sizeof(salg));
> +       salg.salg_family = AF_ALG;
> +       strcpy((char *) salg.salg_type, "hash");
> +       strcpy((char *) salg.salg_name, "hmac(sha256)");
> +
> +       if (bind(fd, (struct sockaddr *) &salg, sizeof(salg)) < 0) {
> +               close(fd);
> +               return -1;
> +       }
> +
> +       return fd;
> +}
> +
>  static struct bt_crypto *singleton;
>
>  struct bt_crypto *bt_crypto_new(void)
> @@ -159,6 +182,16 @@ struct bt_crypto *bt_crypto_new(void)
>                 return NULL;
>         }
>
> +       singleton->hmac_sha256 = hmac_sha256_setup();
> +       if (singleton->hmac_sha256 < 0) {
> +               close(singleton->cmac_aes);
> +               close(singleton->urandom);
> +               close(singleton->ecb_aes);
> +               free(singleton);
> +               singleton = NULL;
> +               return NULL;
> +       }
> +
>         return bt_crypto_ref(singleton);
>  }
>
> @@ -183,6 +216,7 @@ void bt_crypto_unref(struct bt_crypto *crypto)
>         close(crypto->urandom);
>         close(crypto->ecb_aes);
>         close(crypto->cmac_aes);
> +       close(crypto->hmac_sha256);
>
>         free(crypto);
>         singleton = NULL;
> @@ -1005,3 +1039,35 @@ bool bt_crypto_sirk(struct bt_crypto *crypto, const char *str, uint16_t vendor,
>         /* Encrypt sirk using k as LTK with sef function */
>         return bt_crypto_sef(crypto, k, sirk_plaintext, sirk);
>  }
> +
> +bool bt_crypto_hmac_sha256(struct bt_crypto *crypto,
> +                               const uint8_t *key, size_t key_len,
> +                               const uint8_t *msg, size_t msg_len,
> +                               uint8_t res[32])
> +{
> +       ssize_t len;
> +       int fd;
> +
> +       if (!crypto)
> +               return false;
> +
> +       fd = alg_new(crypto->hmac_sha256, key, key_len);
> +       if (fd < 0)
> +               return false;
> +
> +       len = send(fd, msg, msg_len, 0);
> +       if (len < 0) {
> +               close(fd);
> +               return false;
> +       }
> +
> +       len = read(fd, res, 32);
> +       if (len < 0) {
> +               close(fd);
> +               return false;
> +       }
> +
> +       close(fd);
> +
> +       return true;
> +}
> diff --git a/src/shared/crypto.h b/src/shared/crypto.h
> index d85f807..6b234bc 100644
> --- a/src/shared/crypto.h
> +++ b/src/shared/crypto.h
> @@ -62,3 +62,8 @@ bool bt_crypto_sirk(struct bt_crypto *crypto, const char *str, uint16_t vendor,
>                         uint8_t sirk[16]);
>  bool bt_crypto_rsi(struct bt_crypto *crypto, const uint8_t sirk[16],
>                                         uint8_t rsi[6]);
> +
> +bool bt_crypto_hmac_sha256(struct bt_crypto *crypto,
> +                               const uint8_t *key, size_t key_len,
> +                               const uint8_t *msg, size_t msg_len,
> +                               uint8_t res[32]);
>


-- 
Luiz Augusto von Dentz
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.