ANDROID: mmc: MMC crypto API

Make mmc core able to use the blk-crypto framework for inline
encryption. This patch introduces a pointer to struct keyslot_manager
to struct mmc_host, and handles setting up the request_queue for
devices using that keyslot_manager appropriately. It also inits struct
mmc_request's inline encryption fields before it's passed to
mmc_host::ops->request.

Users of the core code in host/ (e.g. cqhci.c) should initialize the
keyslot_manager in struct mmc_host appropriately, if they want to
support inline encryption. They should also handle any inline
encryption related work necessary when mmc_host::ops->request is
called.

This patch is only compile tested, as I don't have a device to
actually test these patches. Enable CONFIG_MMC_CRYPTO to test

Bug: 153512828
Bug: 144046242
Change-Id: I6f98ffadfa6e39d7fdc3752b069210ad97babd8b
Co-developed-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Satya Tangirala <satyat@google.com>
This commit is contained in:
Satya Tangirala 2020-04-14 09:22:40 -07:00
parent 5f5805ee7b
commit 555cf12eb6
9 changed files with 110 additions and 0 deletions

View File

@ -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.

View File

@ -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

View File

@ -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"
@ -1302,6 +1303,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;

40
drivers/mmc/core/crypto.c Normal file
View File

@ -0,0 +1,40 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2020 Google LLC
*/
#include <linux/blk-crypto.h>
#include <linux/blkdev.h>
#include <linux/keyslot-manager.h>
#include <linux/mmc/host.h>
#include "core.h"
#include "queue.h"
void mmc_crypto_setup_queue(struct mmc_host *host, struct request_queue *q)
{
if (host->caps2 & MMC_CAP2_CRYPTO)
q->ksm = host->ksm;
}
EXPORT_SYMBOL_GPL(mmc_crypto_setup_queue);
void mmc_crypto_free_host(struct mmc_host *host)
{
keyslot_manager_destroy(host->ksm);
}
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;
const struct bio_crypt_ctx *bc;
if (!bio_crypt_should_process(req))
return;
bc = req->bio->bi_crypt_context;
mrq->crypto_key_slot = bc->bc_keyslot;
mrq->data_unit_num = bc->bc_dun[0];
mrq->crypto_key = bc->bc_key;
}
EXPORT_SYMBOL_GPL(mmc_crypto_prepare_req);

33
drivers/mmc/core/crypto.h Normal file
View File

@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2020 Google LLC
*/
#ifndef _MMC_CORE_CRYPTO_H
#define _MMC_CORE_CRYPTO_H
struct mmc_host;
struct mmc_queue_req;
struct request;
struct request_queue;
#ifdef CONFIG_MMC_CRYPTO
void mmc_crypto_setup_queue(struct mmc_host *host, struct request_queue *q);
void mmc_crypto_free_host(struct mmc_host *host);
void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq);
#else /* CONFIG_MMC_CRYPTO */
static inline void mmc_crypto_setup_queue(struct mmc_host *host,
struct request_queue *q) { }
static inline void mmc_crypto_free_host(struct mmc_host *host) { }
static inline void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq) { }
#endif /* CONFIG_MMC_CRYPTO */
#endif /* _MMC_CORE_CRYPTO_H */

View File

@ -24,6 +24,7 @@
#include <linux/mmc/slot-gpio.h>
#include "core.h"
#include "crypto.h"
#include "host.h"
#include "slot-gpio.h"
#include "pwrseq.h"
@ -518,6 +519,7 @@ EXPORT_SYMBOL(mmc_remove_host);
*/
void mmc_free_host(struct mmc_host *host)
{
mmc_crypto_free_host(host);
mmc_pwrseq_free(host);
put_device(&host->class_dev);
}

View File

@ -18,6 +18,7 @@
#include "queue.h"
#include "block.h"
#include "core.h"
#include "crypto.h"
#include "card.h"
#include "host.h"
@ -485,6 +486,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card)
blk_queue_rq_timeout(mq->queue, 60 * HZ);
mmc_setup_queue(mq, card);
mmc_crypto_setup_queue(host, mq->queue);
return 0;
free_tag_set:

View File

@ -165,8 +165,25 @@ struct mmc_request {
bool cap_cmd_during_tfr;
int tag;
#ifdef CONFIG_MMC_CRYPTO
int crypto_key_slot;
u64 data_unit_num;
const struct blk_crypto_key *crypto_key;
#endif
};
#ifdef CONFIG_MMC_CRYPTO
static inline bool mmc_request_crypto_enabled(const struct mmc_request *mrq)
{
return mrq->crypto_key != NULL;
}
#else
static inline bool mmc_request_crypto_enabled(const struct mmc_request *mrq)
{
return false;
}
#endif
struct mmc_card;
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq);

View File

@ -370,6 +370,7 @@ struct mmc_host {
#define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */
#define MMC_CAP2_AVOID_3_3V (1 << 25) /* Host must negotiate down from 3.3V */
#define MMC_CAP2_MERGE_CAPABLE (1 << 26) /* Host can merge a segment over the segment size */
#define MMC_CAP2_CRYPTO (1 << 27) /* Host supports inline encryption */
int fixed_drv_type; /* fixed driver type for non-removable media */
@ -462,6 +463,9 @@ struct mmc_host {
int cqe_qdepth;
bool cqe_enabled;
bool cqe_on;
#ifdef CONFIG_MMC_CRYPTO
struct keyslot_manager *ksm;
#endif /* CONFIG_MMC_CRYPTO */
/* Host Software Queue support */
bool hsq_enabled;