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