Skip to content
Permalink
Browse files
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>
  • Loading branch information
Satya Tangirala committed May 11, 2020
1 parent c34be1d commit eb54e7323628bf827eab028d14d8171f8dd6777e
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 0 deletions.
@@ -80,3 +80,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.
@@ -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
@@ -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"
@@ -1304,6 +1305,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;

@@ -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);
@@ -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 */
@@ -27,6 +27,7 @@
#include <linux/mmc/slot-gpio.h>

#include "core.h"
#include "crypto.h"
#include "host.h"
#include "slot-gpio.h"
#include "pwrseq.h"
@@ -480,6 +481,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);
}
@@ -21,6 +21,7 @@
#include "queue.h"
#include "block.h"
#include "core.h"
#include "crypto.h"
#include "card.h"
#include "host.h"

@@ -448,6 +449,8 @@ static int mmc_mq_init(struct mmc_queue *mq, struct mmc_card *card,

mmc_setup_queue(mq, card);

mmc_crypto_setup_queue(host, mq->queue);

return 0;
}

@@ -168,8 +168,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);
@@ -368,6 +368,7 @@ struct mmc_host {
#define MMC_CAP2_CQE (1 << 23) /* Has eMMC command queue engine */
#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_CRYPTO (1 << 27) /* Host supports inline encryption */

int fixed_drv_type; /* fixed driver type for non-removable media */

@@ -459,6 +460,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 */

unsigned long private[0] ____cacheline_aligned;
};

0 comments on commit eb54e73

Please sign in to comment.