Commit 93f1c150 authored by Eric Biggers's avatar Eric Biggers Committed by Ulf Hansson
Browse files

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: default avatarSatya Tangirala <satyat@google.com>
Signed-off-by: default avatarSatya Tangirala <satyat@google.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Reviewed-by: default avatarSatya Tangirala <satyat@google.com>
Reviewed-and-tested-by: default avatarPeng Zhou <peng.zhou@mediatek.com>
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
Link: https://lore.kernel.org/r/20210126001456.382989-2-ebiggers@kernel.org


Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent d76d9d7d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -81,3 +81,11 @@ config MMC_TEST
	  This driver is only of interest to those developing or
	  testing a host driver. Most people should say N here.

config MMC_CRYPTO
	bool "MMC Crypto Engine Support"
	depends on BLK_INLINE_ENCRYPTION
	help
	  Enable Crypto Engine Support in MMC.
	  Enabling this makes it possible for the kernel to use the crypto
	  capabilities of the MMC device (if present) to perform crypto
	  operations on data being transferred to/from the device.
+1 −0
Original line number Diff line number Diff line
@@ -18,3 +18,4 @@ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
mmc_block-objs			:= block.o queue.o
obj-$(CONFIG_MMC_TEST)		+= mmc_test.o
obj-$(CONFIG_SDIO_UART)		+= sdio_uart.o
mmc_core-$(CONFIG_MMC_CRYPTO)	+= crypto.o
+3 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@
#include "block.h"
#include "core.h"
#include "card.h"
#include "crypto.h"
#include "host.h"
#include "bus.h"
#include "mmc_ops.h"
@@ -1247,6 +1248,8 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,

	memset(brq, 0, sizeof(struct mmc_blk_request));

	mmc_crypto_prepare_req(mqrq);

	brq->mrq.data = &brq->data;
	brq->mrq.tag = req->tag;

+3 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@

#include "core.h"
#include "card.h"
#include "crypto.h"
#include "bus.h"
#include "host.h"
#include "sdio_bus.h"
@@ -992,6 +993,8 @@ void mmc_set_initial_state(struct mmc_host *host)
		host->ops->hs400_enhanced_strobe(host, &host->ios);

	mmc_set_ios(host);

	mmc_crypto_set_initial_state(host);
}

/**
+48 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * MMC crypto engine (inline encryption) support
 *
 * Copyright 2020 Google LLC
 */

#include <linux/blk-crypto.h>
#include <linux/mmc/host.h>

#include "core.h"
#include "crypto.h"
#include "queue.h"

void mmc_crypto_set_initial_state(struct mmc_host *host)
{
	/* Reset might clear all keys, so reprogram all the keys. */
	if (host->caps2 & MMC_CAP2_CRYPTO)
		blk_ksm_reprogram_all_keys(&host->ksm);
}

void mmc_crypto_setup_queue(struct request_queue *q, struct mmc_host *host)
{
	if (host->caps2 & MMC_CAP2_CRYPTO)
		blk_ksm_register(&host->ksm, q);
}
EXPORT_SYMBOL_GPL(mmc_crypto_setup_queue);

void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq)
{
	struct request *req = mmc_queue_req_to_req(mqrq);
	struct mmc_request *mrq = &mqrq->brq.mrq;

	if (!req->crypt_keyslot)
		return;

	mrq->crypto_enabled = true;
	mrq->crypto_key_slot = blk_ksm_get_slot_idx(req->crypt_keyslot);

	/*
	 * For now we assume that all MMC drivers set max_dun_bytes_supported=4,
	 * which is the limit for CQHCI crypto.  So all DUNs should be 32-bit.
	 */
	WARN_ON_ONCE(req->crypt_ctx->bc_dun[0] > U32_MAX);

	mrq->data_unit_num = req->crypt_ctx->bc_dun[0];
}
EXPORT_SYMBOL_GPL(mmc_crypto_prepare_req);
Loading