Commit 199afbc2 authored by Andrey Smirnov's avatar Andrey Smirnov Committed by Ezequiel Garcia
Browse files

HACK: Add Secure Memory support.

Port of secure memory code from vendor tree rel_imx_4.19.35_1.0.0
parent bc6fc8ef
......@@ -156,6 +156,11 @@
interrupt-parent = <&gpc>;
ranges;
caam_sm: caam-sm@100000 {
compatible = "fsl,imx6q-caam-sm";
reg = <0x00100000 0x4000>;
};
dma_apbh: dma-apbh@110000 {
compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
reg = <0x00110000 0x2000>;
......
......@@ -469,6 +469,11 @@
reg = <0x4006e000 0x1000>;
interrupts = <96 IRQ_TYPE_LEVEL_HIGH>;
};
caam_sm: caam-sm@4007c000 {
compatible = "fsl,imx6q-caam-sm";
reg = <0x4007C000 0x4000>;
};
};
aips1: aips-bus@40080000 {
......
......@@ -280,6 +280,11 @@
ranges = <0x0 0x0 0x0 0x3e000000>;
dma-ranges = <0x40000000 0x0 0x40000000 0xc0000000>;
caam_sm: caam-sm@100000 {
compatible = "fsl,imx6q-caam-sm";
reg = <0x00100000 0x8000>;
};
bus@30000000 { /* AIPS1 */
compatible = "fsl,imx8mq-aips-bus", "simple-bus";
#address-cells = <1>;
......
......@@ -147,6 +147,29 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API
Selecting this will register the SEC4 hardware rng to
the hw_random API for suppying the kernel entropy pool.
config CRYPTO_DEV_FSL_CAAM_SM
tristate "CAAM Secure Memory / Keystore API (EXPERIMENTAL)"
default n
help
Enables use of a prototype kernel-level Keystore API with CAAM
Secure Memory for insertion/extraction of bus-protected secrets.
config CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE
int "Size of each keystore slot in Secure Memory"
depends on CRYPTO_DEV_FSL_CAAM_SM
range 5 9
default 7
help
Select size of allocation units to divide Secure Memory pages into
(the size of a "slot" as referenced inside the API code).
Established as powers of two.
Examples:
5 => 32 bytes
6 => 64 bytes
7 => 128 bytes
8 => 256 bytes
9 => 512 bytes
endif # CRYPTO_DEV_FSL_CAAM_JR
endif # CRYPTO_DEV_FSL_CAAM
......
......@@ -13,6 +13,7 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC) += caamalg_desc.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o
caam-y := ctrl.o
caam_jr-y := jr.o key_gen.o
......
......@@ -405,6 +405,7 @@
#define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_JKEK (0x20 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_KEY_CCM_JKEK (0x14 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_E_TKEK (0x23 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_KEY_KEK (0x24 << FIFOST_TYPE_SHIFT)
......@@ -1136,6 +1137,23 @@
#define OP_PCL_PKPROT_ECC 0x0002
#define OP_PCL_PKPROT_F2M 0x0001
/* Blob protocol protinfo bits */
#define OP_PCL_BLOB_TK 0x0200
#define OP_PCL_BLOB_EKT 0x0100
#define OP_PCL_BLOB_K2KR_MEM 0x0000
#define OP_PCL_BLOB_K2KR_C1KR 0x0010
#define OP_PCL_BLOB_K2KR_C2KR 0x0030
#define OP_PCL_BLOB_K2KR_AFHAS 0x0050
#define OP_PCL_BLOB_K2KR_C2KR_SPLIT 0x0070
#define OP_PCL_BLOB_PTXT_SECMEM 0x0008
#define OP_PCL_BLOB_BLACK 0x0004
#define OP_PCL_BLOB_FMT_NORMAL 0x0000
#define OP_PCL_BLOB_FMT_MSTR 0x0002
#define OP_PCL_BLOB_FMT_TEST 0x0003
/* For non-protocol/alg-only op commands */
#define OP_ALG_TYPE_SHIFT 24
#define OP_ALG_TYPE_MASK (0x7 << OP_ALG_TYPE_SHIFT)
......
......@@ -75,6 +75,12 @@ struct caam_drv_private {
struct iommu_domain *domain;
struct device *smdev;
dma_addr_t __iomem *sm_base; /* Secure memory storage base */
phys_addr_t sm_phy; /* Secure memory storage physical */
u32 sm_size;
bool has_seco;
/*
* Detected geometry block. Filled in from device tree if powerpc,
* or from register-based version detection code
......
......@@ -407,17 +407,22 @@ struct caam_perfmon {
#define CTPR_MS_PG_SZ_SHIFT 4
u32 comp_parms_ms; /* CTPR - Compile Parameters Register */
u32 comp_parms_ls; /* CTPR - Compile Parameters Register */
u64 rsvd1[2];
/* Secure Memory State Visibility */
u32 rsvd1;
u32 smstatus; /* Secure memory status */
u32 rsvd2;
u32 smpartown; /* Secure memory partition owner */
/* CAAM Global Status fc0-fdf */
u64 faultaddr; /* FAR - Fault Address */
u32 faultliodn; /* FALR - Fault Address LIODN */
u32 faultdetail; /* FADR - Fault Addr Detail */
u32 rsvd2;
u32 rsvd3;
#define CSTA_PLEND BIT(10)
#define CSTA_ALT_PLEND BIT(18)
u32 status; /* CSTA - CAAM Status */
u64 rsvd3;
u32 smpart; /* Secure Memory Partition Parameters */
u32 smvid; /* Secure Memory Version ID */
/* Component Instantiation Parameters fe0-fff */
u32 rtic_id; /* RVID - RTIC Version ID */
......@@ -436,6 +441,62 @@ struct caam_perfmon {
u32 caam_id_ls; /* CAAMVID - CAAM Version ID LS */
};
#define SMSTATUS_PART_SHIFT 28
#define SMSTATUS_PART_MASK (0xf << SMSTATUS_PART_SHIFT)
#define SMSTATUS_PAGE_SHIFT 16
#define SMSTATUS_PAGE_MASK (0x7ff << SMSTATUS_PAGE_SHIFT)
#define SMSTATUS_MID_SHIFT 8
#define SMSTATUS_MID_MASK (0x3f << SMSTATUS_MID_SHIFT)
#define SMSTATUS_ACCERR_SHIFT 4
#define SMSTATUS_ACCERR_MASK (0xf << SMSTATUS_ACCERR_SHIFT)
#define SMSTATUS_ACCERR_NONE 0
#define SMSTATUS_ACCERR_ALLOC 1 /* Page not allocated */
#define SMSTATUS_ACCESS_ID 2 /* Not granted by ID */
#define SMSTATUS_ACCESS_WRITE 3 /* Writes not allowed */
#define SMSTATUS_ACCESS_READ 4 /* Reads not allowed */
#define SMSTATUS_ACCESS_NONKEY 6 /* Non-key reads not allowed */
#define SMSTATUS_ACCESS_BLOB 9 /* Blob access not allowed */
#define SMSTATUS_ACCESS_DESCB 10 /* Descriptor Blob access spans pages */
#define SMSTATUS_ACCESS_NON_SM 11 /* Outside Secure Memory range */
#define SMSTATUS_ACCESS_XPAGE 12 /* Access crosses pages */
#define SMSTATUS_ACCESS_INITPG 13 /* Page still initializing */
#define SMSTATUS_STATE_SHIFT 0
#define SMSTATUS_STATE_MASK (0xf << SMSTATUS_STATE_SHIFT)
#define SMSTATUS_STATE_RESET 0
#define SMSTATUS_STATE_INIT 1
#define SMSTATUS_STATE_NORMAL 2
#define SMSTATUS_STATE_FAIL 3
/* up to 15 rings, 2 bits shifted by ring number */
#define SMPARTOWN_RING_SHIFT 2
#define SMPARTOWN_RING_MASK 3
#define SMPARTOWN_AVAILABLE 0
#define SMPARTOWN_NOEXIST 1
#define SMPARTOWN_UNAVAILABLE 2
#define SMPARTOWN_OURS 3
/* Maximum number of pages possible */
#define SMPART_MAX_NUMPG_SHIFT 16
#define SMPART_MAX_NUMPG_MASK (0x3f << SMPART_MAX_NUMPG_SHIFT)
/* Maximum partition number */
#define SMPART_MAX_PNUM_SHIFT 12
#define SMPART_MAX_PNUM_MASK (0xf << SMPART_MAX_PNUM_SHIFT)
/* Highest possible page number */
#define SMPART_MAX_PG_SHIFT 0
#define SMPART_MAX_PG_MASK (0x3f << SMPART_MAX_PG_SHIFT)
/* Max size of a page */
#define SMVID_PG_SIZE_SHIFT 16
#define SMVID_PG_SIZE_MASK (0x7 << SMVID_PG_SIZE_SHIFT)
/* Major/Minor Version ID */
#define SMVID_MAJ_VERS_SHIFT 8
#define SMVID_MAJ_VERS (0xf << SMVID_MAJ_VERS_SHIFT)
#define SMVID_MIN_VERS_SHIFT 0
#define SMVID_MIN_VERS (0xf << SMVID_MIN_VERS_SHIFT)
/* LIODN programming for DMA configuration */
#define MSTRID_LOCK_LIODN 0x80000000
#define MSTRID_LOCK_MAKETRUSTED 0x00010000 /* only for JR masterid */
......@@ -642,6 +703,35 @@ struct caam_ctrl {
#define JRSTART_JR2_START 0x00000004 /* Start Job ring 2 */
#define JRSTART_JR3_START 0x00000008 /* Start Job ring 3 */
/* Secure Memory Configuration - if you have it */
/* Secure Memory Register Offset from JR Base Reg*/
#define SM_V1_OFFSET 0x0f4
#define SM_V2_OFFSET 0xa00
/* Minimum SM Version ID requiring v2 SM register mapping */
#define SMVID_V2 0x20105
struct caam_secure_mem_v1 {
u32 sm_cmd; /* SMCJRx - Secure memory command */
u32 rsvd1;
u32 sm_status; /* SMCSJRx - Secure memory status */
u32 rsvd2;
u32 sm_perm; /* SMAPJRx - Secure memory access perms */
u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */
u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */
};
struct caam_secure_mem_v2 {
u32 sm_perm; /* SMAPJRx - Secure memory access perms */
u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */
u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */
u32 rsvd1[118];
u32 sm_cmd; /* SMCJRx - Secure memory command */
u32 rsvd2;
u32 sm_status; /* SMCSJRx - Secure memory status */
};
/*
* caam_job_ring - direct job ring setup
* 1-4 possible per instantiation, base + 1000/2000/3000/4000
......@@ -812,6 +902,63 @@ struct caam_job_ring {
#define JRCR_RESET 0x01
/* secure memory command */
#define SMC_PAGE_SHIFT 16
#define SMC_PAGE_MASK (0xffff << SMC_PAGE_SHIFT)
#define SMC_PART_SHIFT 8
#define SMC_PART_MASK (0x0f << SMC_PART_SHIFT)
#define SMC_CMD_SHIFT 0
#define SMC_CMD_MASK (0x0f << SMC_CMD_SHIFT)
#define SMC_CMD_ALLOC_PAGE 0x01 /* allocate page to this partition */
#define SMC_CMD_DEALLOC_PAGE 0x02 /* deallocate page from partition */
#define SMC_CMD_DEALLOC_PART 0x03 /* deallocate partition */
#define SMC_CMD_PAGE_INQUIRY 0x05 /* find partition associate with page */
/* secure memory (command) status */
#define SMCS_PAGE_SHIFT 16
#define SMCS_PAGE_MASK (0x0fff << SMCS_PAGE_SHIFT)
#define SMCS_CMDERR_SHIFT 14
#define SMCS_CMDERR_MASK (3 << SMCS_CMDERR_SHIFT)
#define SMCS_ALCERR_SHIFT 12
#define SMCS_ALCERR_MASK (3 << SMCS_ALCERR_SHIFT)
#define SMCS_PGOWN_SHIFT 6
#define SMCS_PGWON_MASK (3 << SMCS_PGOWN_SHIFT)
#define SMCS_PART_SHIFT 0
#define SMCS_PART_MASK (0xf << SMCS_PART_SHIFT)
#define SMCS_CMDERR_NONE 0
#define SMCS_CMDERR_INCOMP 1 /* Command not yet complete */
#define SMCS_CMDERR_SECFAIL 2 /* Security failure occurred */
#define SMCS_CMDERR_OVERFLOW 3 /* Command overflow */
#define SMCS_ALCERR_NONE 0
#define SMCS_ALCERR_PSPERR 1 /* Partion marked PSP (dealloc only) */
#define SMCS_ALCERR_PAGEAVAIL 2 /* Page not available */
#define SMCS_ALCERR_PARTOWN 3 /* Partition ownership error */
#define SMCS_PGOWN_AVAIL 0 /* Page is available */
#define SMCS_PGOWN_NOEXIST 1 /* Page initializing or nonexistent */
#define SMCS_PGOWN_NOOWN 2 /* Page owned by another processor */
#define SMCS_PGOWN_OWNED 3 /* Page belongs to this processor */
/* secure memory access permissions */
#define SMCS_PERM_KEYMOD_SHIFT 16
#define SMCA_PERM_KEYMOD_MASK (0xff << SMCS_PERM_KEYMOD_SHIFT)
#define SMCA_PERM_CSP_ZERO 0x8000 /* Zero when deallocated or released */
#define SMCA_PERM_PSP_LOCK 0x4000 /* Part./pages can't be deallocated */
#define SMCA_PERM_PERM_LOCK 0x2000 /* Lock permissions */
#define SMCA_PERM_GRP_LOCK 0x1000 /* Lock access groups */
#define SMCA_PERM_RINGID_SHIFT 10
#define SMCA_PERM_RINGID_MASK (3 << SMCA_PERM_RINGID_SHIFT)
#define SMCA_PERM_G2_BLOB 0x0080 /* Group 2 blob import/export */
#define SMCA_PERM_G2_WRITE 0x0020 /* Group 2 write */
#define SMCA_PERM_G2_READ 0x0010 /* Group 2 read */
#define SMCA_PERM_G1_BLOB 0x0008 /* Group 1... */
#define SMCA_PERM_G1_WRITE 0x0002
#define SMCA_PERM_G1_READ 0x0001
/*
* caam_assurance - Assurance Controller View
* base + 0x6000 padded out to 0x1000
......
/*
* CAAM Secure Memory/Keywrap API Definitions
* Copyright (C) 2008-2015 Freescale Semiconductor, Inc.
*/
#ifndef SM_H
#define SM_H
/* Storage access permissions */
#define SM_PERM_READ 0x01
#define SM_PERM_WRITE 0x02
#define SM_PERM_BLOB 0x03
/* Define treatment of secure memory vs. general memory blobs */
#define SM_SECMEM 0
#define SM_GENMEM 1
/* Define treatment of red/black keys */
#define RED_KEY 0
#define BLACK_KEY 1
/* Define key encryption/covering options */
#define KEY_COVER_ECB 0 /* cover key in AES-ECB */
#define KEY_COVER_CCM 1 /* cover key with AES-CCM */
/*
* Round a key size up to an AES blocksize boundary so to allow for
* padding out to a full block
*/
#define AES_BLOCK_PAD(x) ((x % 16) ? ((x >> 4) + 1) << 4 : x)
/* Define space required for BKEK + MAC tag storage in any blob */
#define BLOB_OVERHEAD (32 + 16)
/* Keystore maintenance functions */
void sm_init_keystore(struct device *dev);
u32 sm_detect_keystore_units(struct device *dev);
int sm_establish_keystore(struct device *dev, u32 unit);
void sm_release_keystore(struct device *dev, u32 unit);
void caam_sm_shutdown(struct platform_device *pdev);
int caam_sm_example_init(struct platform_device *pdev);
/* Keystore accessor functions */
extern int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size,
u32 *slot);
extern int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot);
extern int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
const u8 *key_data, u32 key_length);
extern int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
u32 key_length, u8 *key_data);
extern int sm_keystore_cover_key(struct device *dev, u32 unit, u32 slot,
u16 key_length, u8 keyauth);
extern int sm_keystore_slot_export(struct device *dev, u32 unit, u32 slot,
u8 keycolor, u8 keyauth, u8 *outbuf,
u16 keylen, u8 *keymod);
extern int sm_keystore_slot_import(struct device *dev, u32 unit, u32 slot,
u8 keycolor, u8 keyauth, u8 *inbuf,
u16 keylen, u8 *keymod);
/* Prior functions from legacy API, deprecated */
extern int sm_keystore_slot_encapsulate(struct device *dev, u32 unit,
u32 inslot, u32 outslot, u16 secretlen,
u8 *keymod, u16 keymodlen);
extern int sm_keystore_slot_decapsulate(struct device *dev, u32 unit,
u32 inslot, u32 outslot, u16 secretlen,
u8 *keymod, u16 keymodlen);
/* Data structure to hold per-slot information */
struct keystore_data_slot_info {
u8 allocated; /* Track slot assignments */
u32 key_length; /* Size of the key */
};
/* Data structure to hold keystore information */
struct keystore_data {
void *base_address; /* Virtual base of secure memory pages */
void *phys_address; /* Physical base of secure memory pages */
u32 slot_count; /* Number of slots in the keystore */
struct keystore_data_slot_info *slot; /* Per-slot information */
};
/* store the detected attributes of a secure memory page */
struct sm_page_descriptor {
u16 phys_pagenum; /* may be discontiguous */
u16 own_part; /* Owning partition */
void *pg_base; /* Calculated virtual address */
void *pg_phys; /* Calculated physical address */
struct keystore_data *ksdata;
};
struct caam_drv_private_sm {
struct device *parentdev; /* this ends up as the controller */
struct device *smringdev; /* ring that owns this instance */
struct platform_device *sm_pdev; /* Secure Memory platform device */
spinlock_t kslock ____cacheline_aligned;
/* SM Register offset from JR base address */
u32 sm_reg_offset;
/* Default parameters for geometry */
u32 max_pages; /* maximum pages this instance can support */
u32 top_partition; /* highest partition number in this instance */
u32 top_page; /* highest page number in this instance */
u32 page_size; /* page size */
u32 slot_size; /* selected size of each storage block */
/* Partition/Page Allocation Map */
u32 localpages; /* Number of pages we can access */
struct sm_page_descriptor *pagedesc; /* Allocated per-page */
/* Installed handlers for keystore access */
int (*data_init)(struct device *dev, u32 unit);
void (*data_cleanup)(struct device *dev, u32 unit);
int (*slot_alloc)(struct device *dev, u32 unit, u32 size, u32 *slot);
int (*slot_dealloc)(struct device *dev, u32 unit, u32 slot);
void *(*slot_get_address)(struct device *dev, u32 unit, u32 handle);
void *(*slot_get_physical)(struct device *dev, u32 unit, u32 handle);
u32 (*slot_get_base)(struct device *dev, u32 unit, u32 handle);
u32 (*slot_get_offset)(struct device *dev, u32 unit, u32 handle);
u32 (*slot_get_slot_size)(struct device *dev, u32 unit, u32 handle);
};
#endif /* SM_H */
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment