From f146c7bc85a51f95c05e0f8173d484eb301ece78 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Thu, 13 Aug 2026 18:52:04 +0200 Subject: PCI: Add pci_irq_type() to query the allocated interrupt type Add a helper that returns PCI_IRQ_MSIX, PCI_IRQ_MSI, or PCI_IRQ_INTX based on the interrupt type the PCI core selected after pci_alloc_irq_vectors(). Several drivers already open-code this check against pdev->msix_enabled and pdev->msi_enabled, or even open code this helper [1]. A common helper avoids the duplication and keeps drivers from accessing the bitfield directly (see also [2]). Acked-by: Bjorn Helgaas Tested-by: John Hubbard Link: https://elixir.bootlin.com/linux/v7.1/source/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c#L196 [1] Inspired-by: John Hubbard Link: https://lore.kernel.org/all/DKKG2QM3YJYB.Z2H2B2UXJ75N@kernel.org/ [2] Reviewed-by: Gary Guo Link: https://patch.msgid.link/20260813165234.620555-5-dakr@kernel.org [ Add missing pci_irq_type() stub for CONFIG_PCI=n. ] Signed-off-by: Danilo Krummrich --- crypto/cipher.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 crypto/cipher.c (limited to 'crypto/cipher.c') diff --git a/crypto/cipher.c b/crypto/cipher.c new file mode 100644 index 000000000..c9dab656a --- /dev/null +++ b/crypto/cipher.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Cryptographic API. + * + * Single-block cipher operations. + * + * Copyright (c) 2002 James Morris + * Copyright (c) 2005 Herbert Xu + */ + +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" + +static int setkey_unaligned(struct crypto_cipher *tfm, const u8 *key, + unsigned int keylen) +{ + struct cipher_alg *cia = crypto_cipher_alg(tfm); + unsigned long alignmask = crypto_cipher_alignmask(tfm); + int ret; + u8 *buffer, *alignbuffer; + unsigned long absize; + + absize = keylen + alignmask; + buffer = kmalloc(absize, GFP_ATOMIC); + if (!buffer) + return -ENOMEM; + + alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + memcpy(alignbuffer, key, keylen); + ret = cia->cia_setkey(crypto_cipher_tfm(tfm), alignbuffer, keylen); + kfree_sensitive(buffer); + return ret; + +} + +int crypto_cipher_setkey(struct crypto_cipher *tfm, + const u8 *key, unsigned int keylen) +{ + struct cipher_alg *cia = crypto_cipher_alg(tfm); + unsigned long alignmask = crypto_cipher_alignmask(tfm); + + if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) + return -EINVAL; + + if ((unsigned long)key & alignmask) + return setkey_unaligned(tfm, key, keylen); + + return cia->cia_setkey(crypto_cipher_tfm(tfm), key, keylen); +} +EXPORT_SYMBOL_NS_GPL(crypto_cipher_setkey, "CRYPTO_INTERNAL"); + +static inline void cipher_crypt_one(struct crypto_cipher *tfm, + u8 *dst, const u8 *src, bool enc) +{ + unsigned long alignmask = crypto_cipher_alignmask(tfm); + struct cipher_alg *cia = crypto_cipher_alg(tfm); + void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = + enc ? cia->cia_encrypt : cia->cia_decrypt; + + if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) { + unsigned int bs = crypto_cipher_blocksize(tfm); + u8 buffer[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK]; + u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + + memcpy(tmp, src, bs); + fn(crypto_cipher_tfm(tfm), tmp, tmp); + memcpy(dst, tmp, bs); + } else { + fn(crypto_cipher_tfm(tfm), dst, src); + } +} + +void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, + u8 *dst, const u8 *src) +{ + cipher_crypt_one(tfm, dst, src, true); +} +EXPORT_SYMBOL_NS_GPL(crypto_cipher_encrypt_one, "CRYPTO_INTERNAL"); + +void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, + u8 *dst, const u8 *src) +{ + cipher_crypt_one(tfm, dst, src, false); +} +EXPORT_SYMBOL_NS_GPL(crypto_cipher_decrypt_one, "CRYPTO_INTERNAL"); -- cgit v1.3.1