mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 06:09:23 -04:00
Merge "soc: qcom: Added support for virtualized FBE"
This commit is contained in:
commit
894cba23d7
9 changed files with 584 additions and 4 deletions
|
|
@ -432,6 +432,15 @@ config VIRTIO_BLK
|
|||
This is the virtual block driver for virtio. It can be used with
|
||||
QEMU based VMMs (like KVM or Xen). Say Y or M.
|
||||
|
||||
config VIRTIO_BLK_QTI_CRYPTO
|
||||
tristate "Vendor specific VIRTIO Crypto Engine Support"
|
||||
depends on VIRTIO_BLK
|
||||
help
|
||||
Enable storage inline crypto engine support for guest virtual machine.
|
||||
Enabling this allows kernel to use crypto operations defined
|
||||
and implemented by QTI.
|
||||
Say Y or M.
|
||||
|
||||
config VIRTIO_BLK_SCSI
|
||||
bool "SCSI passthrough request for the Virtio block driver"
|
||||
depends on VIRTIO_BLK
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ obj-$(CONFIG_BLK_DEV_SKD) += skd.o
|
|||
obj-$(CONFIG_BLK_DEV_UMEM) += umem.o
|
||||
obj-$(CONFIG_BLK_DEV_NBD) += nbd.o
|
||||
obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
|
||||
obj-$(CONFIG_VIRTIO_BLK_QTI_CRYPTO) += virtio_blk_qti_crypto.o
|
||||
obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
|
||||
|
||||
obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
|
||||
|
|
|
|||
|
|
@ -16,11 +16,22 @@
|
|||
#include <linux/blk-mq.h>
|
||||
#include <linux/blk-mq-virtio.h>
|
||||
#include <linux/numa.h>
|
||||
#ifdef CONFIG_QTI_CRYPTO_VIRTUALIZATION
|
||||
#include <linux/bio-crypt-ctx.h>
|
||||
#include "virtio_blk_qti_crypto.h"
|
||||
#endif
|
||||
|
||||
#define PART_BITS 4
|
||||
#define VQ_NAME_LEN 16
|
||||
#define MAX_DISCARD_SEGMENTS 256u
|
||||
|
||||
#ifdef CONFIG_QTI_CRYPTO_VIRTUALIZATION
|
||||
/* Temporaryly declaring ice supported feature bit.
|
||||
* Will discard this macro once uapi chages are mainlined
|
||||
*/
|
||||
#define VIRTIO_BLK_F_ICE 23 /* support ice virtualization */
|
||||
#endif
|
||||
|
||||
static int major;
|
||||
static DEFINE_IDA(vd_index_ida);
|
||||
|
||||
|
|
@ -71,6 +82,15 @@ struct virtio_blk {
|
|||
struct virtio_blk_vq *vqs;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_QTI_CRYPTO_VIRTUALIZATION
|
||||
struct virtio_blk_ice_info {
|
||||
/*the key slot to use for inline crypto*/
|
||||
u8 ice_slot;
|
||||
u8 activate;
|
||||
u16 reserved;
|
||||
} __packed;
|
||||
#endif
|
||||
|
||||
struct virtblk_req {
|
||||
#ifdef CONFIG_VIRTIO_BLK_SCSI
|
||||
struct scsi_request sreq; /* for SCSI passthrough, must be first */
|
||||
|
|
@ -78,6 +98,9 @@ struct virtblk_req {
|
|||
struct virtio_scsi_inhdr in_hdr;
|
||||
#endif
|
||||
struct virtio_blk_outhdr out_hdr;
|
||||
#ifdef CONFIG_QTI_CRYPTO_VIRTUALIZATION
|
||||
struct virtio_blk_ice_info ice_info;
|
||||
#endif
|
||||
u8 status;
|
||||
struct scatterlist sg[];
|
||||
};
|
||||
|
|
@ -173,8 +196,14 @@ static int virtblk_add_req(struct virtqueue *vq, struct virtblk_req *vbr,
|
|||
{
|
||||
struct scatterlist hdr, status, *sgs[3];
|
||||
unsigned int num_out = 0, num_in = 0;
|
||||
|
||||
#ifdef CONFIG_QTI_CRYPTO_VIRTUALIZATION
|
||||
size_t const hdr_size = virtio_has_feature(vq->vdev, VIRTIO_BLK_F_ICE) ?
|
||||
sizeof(vbr->out_hdr) + sizeof(vbr->ice_info) :
|
||||
sizeof(vbr->out_hdr);
|
||||
sg_init_one(&hdr, &vbr->out_hdr, hdr_size);
|
||||
#else
|
||||
sg_init_one(&hdr, &vbr->out_hdr, sizeof(vbr->out_hdr));
|
||||
#endif
|
||||
sgs[num_out++] = &hdr;
|
||||
|
||||
if (have_data) {
|
||||
|
|
@ -284,6 +313,25 @@ static void virtio_commit_rqs(struct blk_mq_hw_ctx *hctx)
|
|||
virtqueue_notify(vq->vq);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QTI_CRYPTO_VIRTUALIZATION
|
||||
static void virtblk_get_ice_info(struct virtio_blk *vblk, struct request *req)
|
||||
{
|
||||
/* whether or not the request needs inline crypto operations*/
|
||||
struct bio_crypt_ctx *bc;
|
||||
struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
|
||||
|
||||
if (!bio_crypt_should_process(req)) {
|
||||
/* ice is not activated */
|
||||
vbr->ice_info.activate = false;
|
||||
} else {
|
||||
bc = req->bio->bi_crypt_context;
|
||||
/* ice is activated - successful flow */
|
||||
vbr->ice_info.ice_slot = bc->bc_keyslot;
|
||||
vbr->ice_info.activate = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
const struct blk_mq_queue_data *bd)
|
||||
{
|
||||
|
|
@ -333,7 +381,10 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||
vbr->out_hdr.sector = type ?
|
||||
0 : cpu_to_virtio64(vblk->vdev, blk_rq_pos(req));
|
||||
vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(req));
|
||||
|
||||
#ifdef CONFIG_QTI_CRYPTO_VIRTUALIZATION
|
||||
if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_ICE))
|
||||
virtblk_get_ice_info(vblk, req);
|
||||
#endif
|
||||
blk_mq_start_request(req);
|
||||
|
||||
if (type == VIRTIO_BLK_T_DISCARD || type == VIRTIO_BLK_T_WRITE_ZEROES) {
|
||||
|
|
@ -981,8 +1032,17 @@ static int virtblk_probe(struct virtio_device *vdev)
|
|||
}
|
||||
|
||||
virtblk_update_capacity(vblk, false);
|
||||
virtio_device_ready(vdev);
|
||||
|
||||
#ifdef CONFIG_QTI_CRYPTO_VIRTUALIZATION
|
||||
if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_ICE)) {
|
||||
dev_notice(&vdev->dev, "%s\n", vblk->disk->disk_name);
|
||||
/* Initilaize supported crypto capabilities*/
|
||||
err = virtblk_init_crypto_qti_spec();
|
||||
if (!err)
|
||||
virtblk_crypto_qti_setup_rq_keyslot_manager(vblk->disk->queue);
|
||||
}
|
||||
#endif
|
||||
virtio_device_ready(vdev);
|
||||
device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups);
|
||||
return 0;
|
||||
|
||||
|
|
@ -1007,7 +1067,10 @@ static void virtblk_remove(struct virtio_device *vdev)
|
|||
|
||||
/* Make sure no work handler is accessing the device. */
|
||||
flush_work(&vblk->config_work);
|
||||
|
||||
#ifdef CONFIG_QTI_CRYPTO_VIRTUALIZATION
|
||||
if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_ICE))
|
||||
virtblk_crypto_qti_destroy_rq_keyslot_manager(vblk->disk->queue);
|
||||
#endif
|
||||
del_gendisk(vblk->disk);
|
||||
blk_cleanup_queue(vblk->disk->queue);
|
||||
|
||||
|
|
@ -1083,6 +1146,9 @@ static unsigned int features[] = {
|
|||
VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
|
||||
VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE,
|
||||
VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES,
|
||||
#ifdef CONFIG_QTI_CRYPTO_VIRTUALIZATION
|
||||
VIRTIO_BLK_F_ICE,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct virtio_driver virtio_blk = {
|
||||
|
|
|
|||
162
drivers/block/virtio_blk_qti_crypto.c
Normal file
162
drivers/block/virtio_blk_qti_crypto.c
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* virtio block crypto ops QTI implementation.
|
||||
*
|
||||
* Copyright (c) 2021, Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/crypto_qti_virt.h>
|
||||
#include <linux/keyslot-manager.h>
|
||||
|
||||
/*keyslot manager for vrtual IO*/
|
||||
static struct keyslot_manager *virtio_ksm;
|
||||
/*To get max ice slots for guest vm */
|
||||
static uint32_t num_ice_slots;
|
||||
|
||||
void virtblk_crypto_qti_setup_rq_keyslot_manager(struct request_queue *q)
|
||||
{
|
||||
q->ksm = virtio_ksm;
|
||||
}
|
||||
EXPORT_SYMBOL(virtblk_crypto_qti_setup_rq_keyslot_manager);
|
||||
|
||||
void virtblk_crypto_qti_destroy_rq_keyslot_manager(struct request_queue *q)
|
||||
{
|
||||
keyslot_manager_destroy(virtio_ksm);
|
||||
}
|
||||
EXPORT_SYMBOL(virtblk_crypto_qti_destroy_rq_keyslot_manager);
|
||||
|
||||
static inline bool virtblk_keyslot_valid(unsigned int slot)
|
||||
{
|
||||
/*
|
||||
* slot numbers range from 0 to max available
|
||||
* slots for vm.
|
||||
*/
|
||||
return slot < num_ice_slots;
|
||||
}
|
||||
|
||||
static int virtblk_crypto_qti_keyslot_program(struct keyslot_manager *ksm,
|
||||
const struct blk_crypto_key *key,
|
||||
unsigned int slot)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!virtblk_keyslot_valid(slot)) {
|
||||
pr_err("%s: key slot is not valid\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
err = crypto_qti_virt_program_key(key, slot);
|
||||
if (err) {
|
||||
pr_err("%s: program key failed with error %d\n",
|
||||
__func__, err);
|
||||
err = crypto_qti_virt_invalidate_key(slot);
|
||||
if (err) {
|
||||
pr_err("%s: invalidate key failed with error %d\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int virtblk_crypto_qti_keyslot_evict(struct keyslot_manager *ksm,
|
||||
const struct blk_crypto_key *key,
|
||||
unsigned int slot)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!virtblk_keyslot_valid(slot)) {
|
||||
pr_err("%s: key slot is not valid\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
err = crypto_qti_virt_invalidate_key(slot);
|
||||
if (err) {
|
||||
pr_err("%s: evict key failed with error %d\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int virtblk_crypto_qti_derive_raw_secret(struct keyslot_manager *ksm,
|
||||
const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size,
|
||||
u8 *secret,
|
||||
unsigned int secret_size)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (wrapped_key_size <= RAW_SECRET_SIZE) {
|
||||
pr_err("%s: Invalid wrapped_key_size: %u\n",
|
||||
__func__, wrapped_key_size);
|
||||
err = -EINVAL;
|
||||
return err;
|
||||
}
|
||||
if (secret_size != RAW_SECRET_SIZE) {
|
||||
pr_err("%s: Invalid secret size: %u\n",
|
||||
__func__, secret_size);
|
||||
err = -EINVAL;
|
||||
return err;
|
||||
}
|
||||
err = crypto_qti_virt_derive_raw_secret_platform(wrapped_key,
|
||||
wrapped_key_size,
|
||||
secret,
|
||||
secret_size);
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct keyslot_mgmt_ll_ops virtio_blk_crypto_qti_ksm_ops = {
|
||||
.keyslot_program = virtblk_crypto_qti_keyslot_program,
|
||||
.keyslot_evict = virtblk_crypto_qti_keyslot_evict,
|
||||
.derive_raw_secret = virtblk_crypto_qti_derive_raw_secret,
|
||||
};
|
||||
|
||||
int virtblk_init_crypto_qti_spec(void)
|
||||
{
|
||||
int err = 0;
|
||||
int cap_idx = 0;
|
||||
unsigned int crypto_modes_supported[BLK_ENCRYPTION_MODE_MAX];
|
||||
|
||||
/* Actual determination of capabilities for UFS/EMMC for different
|
||||
* encryption modes are done in the back end in case of virtualization
|
||||
* driver, so initializing this to 0xFFFFFFFF meaning it supports
|
||||
* all crypto capabilities to please the keyslot manager. feeding
|
||||
* as input parameter to the keyslot manager
|
||||
*/
|
||||
for (cap_idx = 0; cap_idx < BLK_ENCRYPTION_MODE_MAX; cap_idx++)
|
||||
crypto_modes_supported[cap_idx] = 0xFFFFFFFF;
|
||||
crypto_modes_supported[BLK_ENCRYPTION_MODE_INVALID] = 0;
|
||||
|
||||
/* Get max number of ice slots for guest vm */
|
||||
err = crypto_qti_virt_ice_get_info(&num_ice_slots);
|
||||
if (err) {
|
||||
pr_err("crypto_qti_virt_ice_get_info failed error = %d\n", err);
|
||||
return err;
|
||||
}
|
||||
/* Return from here inacse keyslot manger is already created */
|
||||
if (virtio_ksm)
|
||||
return 0;
|
||||
|
||||
/* create keyslot manager and which will manage the keyslots for all
|
||||
* virtual disks
|
||||
*/
|
||||
virtio_ksm = keyslot_manager_create(NULL,
|
||||
num_ice_slots,
|
||||
&virtio_blk_crypto_qti_ksm_ops,
|
||||
BLK_CRYPTO_FEATURE_STANDARD_KEYS |
|
||||
BLK_CRYPTO_FEATURE_WRAPPED_KEYS,
|
||||
crypto_modes_supported,
|
||||
NULL);
|
||||
|
||||
if (!virtio_ksm)
|
||||
return -ENOMEM;
|
||||
|
||||
pr_info("%s: keyslot manager created\n", __func__);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(virtblk_init_crypto_qti_spec);
|
||||
35
drivers/block/virtio_blk_qti_crypto.h
Normal file
35
drivers/block/virtio_blk_qti_crypto.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _VIRTIO_BLK_QTI_CRYPTO_H
|
||||
#define _VIRTIO_BLK_QTI_CRYPTO_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
/**
|
||||
* This function intializes the supported crypto capabilities
|
||||
* and create keyslot manager to manage keyslots for virtual
|
||||
* disks.
|
||||
*
|
||||
* Return: zero on success, else a -errno value
|
||||
*/
|
||||
int virtblk_init_crypto_qti_spec(void);
|
||||
|
||||
/**
|
||||
* set up a keyslot manager in the virtual disks request_queue
|
||||
*
|
||||
* @request_queue: virtual disk request queue
|
||||
*/
|
||||
void virtblk_crypto_qti_setup_rq_keyslot_manager(struct request_queue *q);
|
||||
/**
|
||||
* destroy keyslot manager
|
||||
*
|
||||
* @request_queue: virtual disk request queue
|
||||
*/
|
||||
void virtblk_crypto_qti_destroy_rq_keyslot_manager(struct request_queue *q);
|
||||
|
||||
#endif /* _VIRTIO_BLK_QTI_CRYPTO_H */
|
||||
|
||||
|
|
@ -1222,6 +1222,16 @@ config QTI_CRYPTO_FDE
|
|||
of KSM(Key Slot Manager) for the FDE. Making one less slot available for FBE
|
||||
(File based encryption) in case both encryption mechanism are enabled on device.
|
||||
|
||||
config QTI_CRYPTO_VIRTUALIZATION
|
||||
tristate "Enable hypervysor to be used for FBE"
|
||||
depends on FS_ENCRYPTION_INLINE_CRYPT
|
||||
depends on MSM_HAB
|
||||
help
|
||||
Say 'Y' to enable routing of crypto requests to different operating
|
||||
system in virtualized environment. Driver uses a hardware abstraction(hab)
|
||||
layer where the APIs exposed by that operationg systems are used to send
|
||||
requests to perform the hardware crypto operation.
|
||||
|
||||
config QTI_HW_KEY_MANAGER
|
||||
tristate "Enable QTI Hardware Key Manager for storage encryption"
|
||||
default n
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_HYP_CORE_CTL) += hyp_core_ctl.o
|
|||
obj-$(CONFIG_MSM_QBT_HANDLER) += qbt_handler.o
|
||||
obj-$(CONFIG_QTI_CRYPTO_COMMON) += crypto-qti-common.o
|
||||
obj-$(CONFIG_QTI_CRYPTO_TZ) += crypto-qti-tz.o
|
||||
obj-$(CONFIG_QTI_CRYPTO_VIRTUALIZATION) += crypto-qti-virt.o
|
||||
obj-$(CONFIG_QTI_HW_KEY_MANAGER) += hwkm.o crypto-qti-hwkm.o
|
||||
obj-$(CONFIG_QCOM_WDT_CORE) += qcom_wdt_core.o
|
||||
obj-$(CONFIG_QCOM_SOC_WATCHDOG) += qcom_soc_wdt.o
|
||||
|
|
|
|||
208
drivers/soc/qcom/crypto-qti-virt.c
Normal file
208
drivers/soc/qcom/crypto-qti-virt.c
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Crypto virtual library for storage encryption.
|
||||
*
|
||||
* Copyright (c) 2021, Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/habmm.h>
|
||||
#include <linux/crypto_qti_virt.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
/**********************************/
|
||||
/** global definitions **/
|
||||
/**********************************/
|
||||
|
||||
#define RESERVE_SIZE (36*sizeof(uint16_t))
|
||||
/* This macro is aligned to actual definition present
|
||||
* in bio crypt context header file.
|
||||
*/
|
||||
#define BLK_CRYPTO_MAX_WRAPPED_KEY_SIZE 128
|
||||
#define HAB_TIMEOUT_MS (3000)
|
||||
/* FBE request command ids */
|
||||
#define FBE_GET_MAX_SLOTS (7)
|
||||
#define FBE_SET_KEY_V2 (8)
|
||||
#define FBE_CLEAR_KEY_V2 (9)
|
||||
|
||||
struct fbe_request_v2_t {
|
||||
uint8_t reserve[RESERVE_SIZE];//for compatibility
|
||||
uint32_t cmd;
|
||||
uint8_t key[BLK_CRYPTO_MAX_WRAPPED_KEY_SIZE];
|
||||
uint32_t key_size;
|
||||
uint32_t virt_slot;
|
||||
};
|
||||
|
||||
struct fbe_req_args {
|
||||
struct fbe_request_v2_t req;
|
||||
int32_t status;
|
||||
int32_t ret;
|
||||
};
|
||||
|
||||
static struct completion send_fbe_req_done;
|
||||
|
||||
static int32_t send_fbe_req_hab(void *arg)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t status_size;
|
||||
uint32_t handle;
|
||||
struct fbe_req_args *req_args = (struct fbe_req_args *)arg;
|
||||
|
||||
do {
|
||||
if (!req_args) {
|
||||
pr_err("%s Null input\n", __func__);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = habmm_socket_open(&handle, MM_FDE_1, 0, 0);
|
||||
if (ret) {
|
||||
pr_err("habmm_socket_open failed with ret = %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = habmm_socket_send(handle, &req_args->req, sizeof(struct fbe_request_v2_t), 0);
|
||||
if (ret) {
|
||||
pr_err("habmm_socket_send failed, ret= 0x%x\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
status_size = sizeof(int32_t);
|
||||
ret = habmm_socket_recv(handle, &req_args->status, &status_size, 0,
|
||||
HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE);
|
||||
} while (-EINTR == ret);
|
||||
|
||||
if (ret) {
|
||||
pr_err("habmm_socket_recv failed, ret= 0x%x\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
if (status_size != sizeof(int32_t)) {
|
||||
pr_err("habmm_socket_recv expected size: %lu, actual=%u\n",
|
||||
sizeof(int32_t),
|
||||
status_size);
|
||||
ret = -E2BIG;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = habmm_socket_close(handle);
|
||||
if (ret) {
|
||||
pr_err("habmm_socket_close failed with ret = %d\n", ret);
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
req_args->ret = ret;
|
||||
|
||||
complete(&send_fbe_req_done);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_fbe_req(struct fbe_req_args *arg)
|
||||
{
|
||||
struct task_struct *thread;
|
||||
|
||||
init_completion(&send_fbe_req_done);
|
||||
arg->status = 0;
|
||||
|
||||
thread = kthread_run(send_fbe_req_hab, arg, "send_fbe_req");
|
||||
if (IS_ERR(thread)) {
|
||||
arg->ret = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (wait_for_completion_interruptible_timeout(
|
||||
&send_fbe_req_done, msecs_to_jiffies(HAB_TIMEOUT_MS)) <= 0) {
|
||||
pr_err("%s: timeout hit\n", __func__);
|
||||
kthread_stop(thread);
|
||||
arg->ret = -ETIME;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int crypto_qti_virt_ice_get_info(uint32_t *total_num_slots)
|
||||
{
|
||||
struct fbe_req_args arg;
|
||||
|
||||
if (!total_num_slots) {
|
||||
pr_err("%s Null input\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
arg.req.cmd = FBE_GET_MAX_SLOTS;
|
||||
send_fbe_req(&arg);
|
||||
|
||||
if (arg.ret || arg.status < 0) {
|
||||
pr_err("send_fbe_req_v2 failed with ret = %d, max_slots = %d\n",
|
||||
arg.ret, arg.status);
|
||||
return -ECOMM;
|
||||
}
|
||||
|
||||
*total_num_slots = (uint32_t) arg.status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_qti_virt_program_key(const struct blk_crypto_key *key,
|
||||
unsigned int slot)
|
||||
{
|
||||
struct fbe_req_args arg;
|
||||
|
||||
if (!key)
|
||||
return -EINVAL;
|
||||
|
||||
arg.req.cmd = FBE_SET_KEY_V2;
|
||||
arg.req.virt_slot = slot;
|
||||
arg.req.key_size = key->size;
|
||||
memcpy(&(arg.req.key[0]), key->raw, key->size);
|
||||
|
||||
send_fbe_req(&arg);
|
||||
|
||||
if (arg.ret || arg.status) {
|
||||
pr_err("send_fbe_req_v2 failed with ret = %d, status = %d\n",
|
||||
arg.ret, arg.status);
|
||||
return -ECOMM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(crypto_qti_virt_program_key);
|
||||
|
||||
int crypto_qti_virt_invalidate_key(unsigned int slot)
|
||||
{
|
||||
struct fbe_req_args arg;
|
||||
|
||||
arg.req.cmd = FBE_CLEAR_KEY_V2;
|
||||
arg.req.virt_slot = slot;
|
||||
|
||||
send_fbe_req(&arg);
|
||||
|
||||
if (arg.ret || arg.status) {
|
||||
pr_err("send_fbe_req_v2 failed with ret = %d, status = %d\n",
|
||||
arg.ret, arg.status);
|
||||
return -ECOMM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(crypto_qti_virt_invalidate_key);
|
||||
|
||||
int crypto_qti_virt_derive_raw_secret_platform(const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size,
|
||||
u8 *secret,
|
||||
unsigned int secret_size)
|
||||
{
|
||||
memcpy(secret, wrapped_key, secret_size);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(crypto_qti_virt_derive_raw_secret_platform);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("Crypto Virtual library for storage encryption");
|
||||
|
||||
88
include/linux/crypto_qti_virt.h
Normal file
88
include/linux/crypto_qti_virt.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_QTI_VIRT_H
|
||||
#define _CRYPTO_QTI_VIRT_H
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/bio-crypt-ctx.h>
|
||||
|
||||
#define RAW_SECRET_SIZE 32
|
||||
|
||||
#if IS_ENABLED(CONFIG_QTI_CRYPTO_VIRTUALIZATION)
|
||||
/**
|
||||
* crypto_qti_virt_program_key() - will send key and virtual slot
|
||||
* info to Back end (BE) and BE will program the key into specified
|
||||
* keyslot in the inline encryption hardware.
|
||||
*
|
||||
* @blk_crypto_key: Actual key or wrapped key
|
||||
* @slot: virtual slot
|
||||
*
|
||||
* Return: zero on success, else a -errno value
|
||||
*/
|
||||
int crypto_qti_virt_program_key(const struct blk_crypto_key *key,
|
||||
unsigned int slot);
|
||||
/**
|
||||
* crypto_qti_virt_invalidate_key() - will virtual slot
|
||||
* info to Back end (BE) and BE will Evict key from the
|
||||
* specified keyslot in the hardware
|
||||
*
|
||||
* @slot: virtual slot
|
||||
*
|
||||
* Return: zero on success, else a -errno value
|
||||
*/
|
||||
int crypto_qti_virt_invalidate_key(unsigned int slot);
|
||||
|
||||
/**
|
||||
* crypto_qti_virt_derive_raw_secret_platform() - Derive
|
||||
* software secret from wrapped key
|
||||
*
|
||||
* @wrapped_key: The wrapped key
|
||||
* @wrapped_key_size: Size of the wrapped key in bytes
|
||||
* @secret: (output) the software secret
|
||||
* @secret_size: (output) the number of secret bytes to derive
|
||||
*
|
||||
* Return: zero on success, else a -errno value
|
||||
*/
|
||||
int crypto_qti_virt_derive_raw_secret_platform(const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size, u8 *secret,
|
||||
unsigned int secret_size);
|
||||
|
||||
/**
|
||||
* crypto_qti_virt_ice_get_info() - Determines the
|
||||
* total number of available slot for virtual machine
|
||||
*
|
||||
* @total_num_slots: its an out param and this will update
|
||||
* with max number of slots.
|
||||
*
|
||||
* Return: zero on success, else a -errno value
|
||||
*/
|
||||
int crypto_qti_virt_ice_get_info(uint32_t *total_num_slots);
|
||||
#else
|
||||
static inline int crypto_qti_virt_program_key(const struct blk_crypto_key *key,
|
||||
unsigned int slot)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
static inline int crypto_qti_virt_invalidate_key(unsigned int slot)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
static inline int crypto_qti_virt_derive_raw_secret_platform(
|
||||
const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size, u8 *secret,
|
||||
unsigned int secret_size)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int crypto_qti_virt_ice_get_info(uint32_t *total_num_slots)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif /* CONFIG_QTI_CRYPTO_VIRTUALIZATION */
|
||||
#endif /*_CRYPTO_QTI_VIRT_H */
|
||||
|
||||
Loading…
Reference in a new issue