Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: core: Add basic support for inline encryption

In preparation for adding CQHCI crypto engine (inline encryption)
support, add the code required to make mmc_core and mmc_block aware of
inline encryption. Specifically:

- Add a capability flag MMC_CAP2_CRYPTO to struct mmc_host. Drivers
will set this if the host and driver support inline encryption.

- Embed a blk_keyslot_manager in struct mmc_host. Drivers will
initialize this (as a device-managed resource) if the host and driver
support inline encryption. mmc_block registers this keyslot manager
with the request_queue of any MMC card attached to the host.

- Make mmc_block copy the crypto keyslot and crypto data unit number
from struct request to struct mmc_request, so that drivers will have
access to them.

- If the MMC host is reset, reprogram all the keyslots to ensure that
the software state stays in sync with the hardware state.

Co-developed-by: Satya Tangirala <satyat@google.com>
Signed-off-by: Satya Tangirala <satyat@google.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Satya Tangirala <satyat@google.com>
Reviewed-and-tested-by: Peng Zhou <peng.zhou@mediatek.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Link: https://lore.kernel.org/r/20210126001456.382989-2-ebiggers@kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Eric Biggers and committed by
Ulf Hansson
93f1c150 d76d9d7d

+124
+8
drivers/mmc/core/Kconfig
··· 81 81 This driver is only of interest to those developing or 82 82 testing a host driver. Most people should say N here. 83 83 84 + config MMC_CRYPTO 85 + bool "MMC Crypto Engine Support" 86 + depends on BLK_INLINE_ENCRYPTION 87 + help 88 + Enable Crypto Engine Support in MMC. 89 + Enabling this makes it possible for the kernel to use the crypto 90 + capabilities of the MMC device (if present) to perform crypto 91 + operations on data being transferred to/from the device.
+1
drivers/mmc/core/Makefile
··· 18 18 mmc_block-objs := block.o queue.o 19 19 obj-$(CONFIG_MMC_TEST) += mmc_test.o 20 20 obj-$(CONFIG_SDIO_UART) += sdio_uart.o 21 + mmc_core-$(CONFIG_MMC_CRYPTO) += crypto.o
+3
drivers/mmc/core/block.c
··· 51 51 #include "block.h" 52 52 #include "core.h" 53 53 #include "card.h" 54 + #include "crypto.h" 54 55 #include "host.h" 55 56 #include "bus.h" 56 57 #include "mmc_ops.h" ··· 1247 1246 (md->flags & MMC_BLK_REL_WR); 1248 1247 1249 1248 memset(brq, 0, sizeof(struct mmc_blk_request)); 1249 + 1250 + mmc_crypto_prepare_req(mqrq); 1250 1251 1251 1252 brq->mrq.data = &brq->data; 1252 1253 brq->mrq.tag = req->tag;
+3
drivers/mmc/core/core.c
··· 37 37 38 38 #include "core.h" 39 39 #include "card.h" 40 + #include "crypto.h" 40 41 #include "bus.h" 41 42 #include "host.h" 42 43 #include "sdio_bus.h" ··· 993 992 host->ops->hs400_enhanced_strobe(host, &host->ios); 994 993 995 994 mmc_set_ios(host); 995 + 996 + mmc_crypto_set_initial_state(host); 996 997 } 997 998 998 999 /**
+48
drivers/mmc/core/crypto.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * MMC crypto engine (inline encryption) support 4 + * 5 + * Copyright 2020 Google LLC 6 + */ 7 + 8 + #include <linux/blk-crypto.h> 9 + #include <linux/mmc/host.h> 10 + 11 + #include "core.h" 12 + #include "crypto.h" 13 + #include "queue.h" 14 + 15 + void mmc_crypto_set_initial_state(struct mmc_host *host) 16 + { 17 + /* Reset might clear all keys, so reprogram all the keys. */ 18 + if (host->caps2 & MMC_CAP2_CRYPTO) 19 + blk_ksm_reprogram_all_keys(&host->ksm); 20 + } 21 + 22 + void mmc_crypto_setup_queue(struct request_queue *q, struct mmc_host *host) 23 + { 24 + if (host->caps2 & MMC_CAP2_CRYPTO) 25 + blk_ksm_register(&host->ksm, q); 26 + } 27 + EXPORT_SYMBOL_GPL(mmc_crypto_setup_queue); 28 + 29 + void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq) 30 + { 31 + struct request *req = mmc_queue_req_to_req(mqrq); 32 + struct mmc_request *mrq = &mqrq->brq.mrq; 33 + 34 + if (!req->crypt_keyslot) 35 + return; 36 + 37 + mrq->crypto_enabled = true; 38 + mrq->crypto_key_slot = blk_ksm_get_slot_idx(req->crypt_keyslot); 39 + 40 + /* 41 + * For now we assume that all MMC drivers set max_dun_bytes_supported=4, 42 + * which is the limit for CQHCI crypto. So all DUNs should be 32-bit. 43 + */ 44 + WARN_ON_ONCE(req->crypt_ctx->bc_dun[0] > U32_MAX); 45 + 46 + mrq->data_unit_num = req->crypt_ctx->bc_dun[0]; 47 + } 48 + EXPORT_SYMBOL_GPL(mmc_crypto_prepare_req);
+40
drivers/mmc/core/crypto.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * MMC crypto engine (inline encryption) support 4 + * 5 + * Copyright 2020 Google LLC 6 + */ 7 + 8 + #ifndef _MMC_CORE_CRYPTO_H 9 + #define _MMC_CORE_CRYPTO_H 10 + 11 + struct mmc_host; 12 + struct mmc_queue_req; 13 + struct request_queue; 14 + 15 + #ifdef CONFIG_MMC_CRYPTO 16 + 17 + void mmc_crypto_set_initial_state(struct mmc_host *host); 18 + 19 + void mmc_crypto_setup_queue(struct request_queue *q, struct mmc_host *host); 20 + 21 + void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq); 22 + 23 + #else /* CONFIG_MMC_CRYPTO */ 24 + 25 + static inline void mmc_crypto_set_initial_state(struct mmc_host *host) 26 + { 27 + } 28 + 29 + static inline void mmc_crypto_setup_queue(struct request_queue *q, 30 + struct mmc_host *host) 31 + { 32 + } 33 + 34 + static inline void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq) 35 + { 36 + } 37 + 38 + #endif /* !CONFIG_MMC_CRYPTO */ 39 + 40 + #endif /* _MMC_CORE_CRYPTO_H */
+1
drivers/mmc/core/host.c
··· 25 25 #include <linux/mmc/slot-gpio.h> 26 26 27 27 #include "core.h" 28 + #include "crypto.h" 28 29 #include "host.h" 29 30 #include "slot-gpio.h" 30 31 #include "pwrseq.h"
+3
drivers/mmc/core/queue.c
··· 19 19 #include "block.h" 20 20 #include "core.h" 21 21 #include "card.h" 22 + #include "crypto.h" 22 23 #include "host.h" 23 24 24 25 #define MMC_DMA_MAP_MERGE_SEGMENTS 512 ··· 408 407 mutex_init(&mq->complete_lock); 409 408 410 409 init_waitqueue_head(&mq->wait); 410 + 411 + mmc_crypto_setup_queue(mq->queue, host); 411 412 } 412 413 413 414 static inline bool mmc_merge_capable(struct mmc_host *host)
+6
include/linux/mmc/core.h
··· 162 162 bool cap_cmd_during_tfr; 163 163 164 164 int tag; 165 + 166 + #ifdef CONFIG_MMC_CRYPTO 167 + bool crypto_enabled; 168 + int crypto_key_slot; 169 + u32 data_unit_num; 170 + #endif 165 171 }; 166 172 167 173 struct mmc_card;
+11
include/linux/mmc/host.h
··· 15 15 #include <linux/mmc/card.h> 16 16 #include <linux/mmc/pm.h> 17 17 #include <linux/dma-direction.h> 18 + #include <linux/keyslot-manager.h> 18 19 19 20 struct mmc_ios { 20 21 unsigned int clock; /* clock rate */ ··· 396 395 #define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */ 397 396 #define MMC_CAP2_AVOID_3_3V (1 << 25) /* Host must negotiate down from 3.3V */ 398 397 #define MMC_CAP2_MERGE_CAPABLE (1 << 26) /* Host can merge a segment over the segment size */ 398 + #ifdef CONFIG_MMC_CRYPTO 399 + #define MMC_CAP2_CRYPTO (1 << 27) /* Host supports inline encryption */ 400 + #else 401 + #define MMC_CAP2_CRYPTO 0 402 + #endif 399 403 400 404 int fixed_drv_type; /* fixed driver type for non-removable media */ 401 405 ··· 494 488 int cqe_qdepth; 495 489 bool cqe_enabled; 496 490 bool cqe_on; 491 + 492 + /* Inline encryption support */ 493 + #ifdef CONFIG_MMC_CRYPTO 494 + struct blk_keyslot_manager ksm; 495 + #endif 497 496 498 497 /* Host Software Queue support */ 499 498 bool hsq_enabled;