Re: [PATCH -next] crypto: ccp - Make function sev_get_firmware() static

2018-09-25 Thread Gary R Hook
On 09/25/2018 09:35 AM, Wei Yongjun wrote:
> Fixes the following sparse warning:
> 
> drivers/crypto/ccp/psp-dev.c:444:5: warning:
>   symbol 'sev_get_firmware' was not declared. Should it be static?
> 
> Signed-off-by: Wei Yongjun 

This appears to have been introduced by (cryptodev-2.6) commit 
e93720606efdbe914110e0ee94bd086f5514a6f1. Please update this commit 
message with all of the "fixes" magic (or whatever has to happen in the 
cryptodev repo), and CC: the author of the original patch.


> ---
>   drivers/crypto/ccp/psp-dev.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
> index 3b33863..d64a78c 100644
> --- a/drivers/crypto/ccp/psp-dev.c
> +++ b/drivers/crypto/ccp/psp-dev.c
> @@ -441,7 +441,8 @@ static int sev_get_api_version(void)
>   return 0;
>   }
>   
> -int sev_get_firmware(struct device *dev, const struct firmware **firmware)
> +static int sev_get_firmware(struct device *dev,
> + const struct firmware **firmware)
>   {
>   char fw_name_specific[SEV_FW_NAME_SIZE];
>   char fw_name_subset[SEV_FW_NAME_SIZE];
> 



Re: [PATCH] crypto: ccp: Check for NULL PSP pointer at module unload

2018-07-26 Thread Gary R Hook

On 07/26/2018 09:37 AM, Tom Lendacky wrote:

Should the PSP initialization fail, the PSP data structure will be
freed and the value contained in the sp_device struct set to NULL.
At module unload, psp_dev_destroy() does not check if the pointer
value is NULL and will end up dereferencing a NULL pointer.

Add a pointer check of the psp_data field in the sp_device struct
in psp_dev_destroy() and return immediately if it is NULL.

Cc:  # 4.16.x-
Fixes: 2a6170dfe755 ("crypto: ccp: Add Platform Security Processor (PSP) device 
support")
Signed-off-by: Tom Lendacky 


Acked-by: Gary R Hook 


---
  drivers/crypto/ccp/psp-dev.c |3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 9b59638..218739b 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -858,6 +858,9 @@ void psp_dev_destroy(struct sp_device *sp)
  {
struct psp_device *psp = sp->psp_data;
  
+	if (!psp)

+   return;
+
if (psp->sev_misc)
kref_put(_dev->refcount, sev_exit);
  





Re: [PATCH v1 5/5] crypto: ccp: Add support for new CCP/PSP device ID

2018-07-05 Thread Gary R Hook

On 07/03/2018 12:12 PM, Tom Lendacky wrote:

Add a new CCP/PSP PCI device ID and new PSP register offsets.

Signed-off-by: Tom Lendacky 


Acked-by: Gary R Hook 


---
  drivers/crypto/ccp/sp-pci.c |   29 -
  1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
index 78c1e9d..7da93e9 100644
--- a/drivers/crypto/ccp/sp-pci.c
+++ b/drivers/crypto/ccp/sp-pci.c
@@ -269,7 +269,7 @@ static int sp_pci_resume(struct pci_dev *pdev)
  #endif
  
  #ifdef CONFIG_CRYPTO_DEV_SP_PSP

-static const struct psp_vdata psp_entry = {
+static const struct psp_vdata pspv1 = {
.cmdresp_reg= 0x10580,
.cmdbuff_addr_lo_reg= 0x105e0,
.cmdbuff_addr_hi_reg= 0x105e4,
@@ -277,35 +277,54 @@ static int sp_pci_resume(struct pci_dev *pdev)
.inten_reg  = 0x10610,
.intsts_reg = 0x10614,
  };
+
+static const struct psp_vdata pspv2 = {
+   .cmdresp_reg= 0x10980,
+   .cmdbuff_addr_lo_reg= 0x109e0,
+   .cmdbuff_addr_hi_reg= 0x109e4,
+   .feature_reg= 0x109fc,
+   .inten_reg  = 0x10690,
+   .intsts_reg = 0x10694,
+};
  #endif
  
  static const struct sp_dev_vdata dev_vdata[] = {

-   {
+   {   /* 0 */
.bar = 2,
  #ifdef CONFIG_CRYPTO_DEV_SP_CCP
.ccp_vdata = ,
  #endif
},
-   {
+   {   /* 1 */
.bar = 2,
  #ifdef CONFIG_CRYPTO_DEV_SP_CCP
.ccp_vdata = ,
  #endif
  #ifdef CONFIG_CRYPTO_DEV_SP_PSP
-   .psp_vdata = _entry
+   .psp_vdata = ,
  #endif
},
-   {
+   {   /* 2 */
.bar = 2,
  #ifdef CONFIG_CRYPTO_DEV_SP_CCP
.ccp_vdata = ,
  #endif
},
+   {   /* 3 */
+   .bar = 2,
+#ifdef CONFIG_CRYPTO_DEV_SP_CCP
+   .ccp_vdata = ,
+#endif
+#ifdef CONFIG_CRYPTO_DEV_SP_PSP
+   .psp_vdata = ,
+#endif
+   },
  };
  static const struct pci_device_id sp_pci_table[] = {
{ PCI_VDEVICE(AMD, 0x1537), (kernel_ulong_t)_vdata[0] },
{ PCI_VDEVICE(AMD, 0x1456), (kernel_ulong_t)_vdata[1] },
{ PCI_VDEVICE(AMD, 0x1468), (kernel_ulong_t)_vdata[2] },
+   { PCI_VDEVICE(AMD, 0x1486), (kernel_ulong_t)_vdata[3] },
/* Last entry must be zero */
{ 0, }
  };





Re: [PATCH v1 1/5] crypto: ccp: Fix command completion detection race

2018-07-05 Thread Gary R Hook

On 07/05/2018 10:43 AM, Brijesh Singh wrote:



On 07/03/2018 12:11 PM, Tom Lendacky wrote:

The wait_event() function is used to detect command completion.  The
interrupt handler will set the wait condition variable when the interrupt
is triggered.  However, the variable used for wait_event() is initialized
after the command has been submitted, which can create a race condition
with the interrupt handler and result in the wait_event() never 
returning.

Move the initialization of the wait condition variable to just before
command submission.

Fixes: 200664d5237f ("crypto: ccp: Add Secure Encrypted Virtualization 
(SEV) command support")

Cc:  # 4.16.x-
Signed-off-by: Tom Lendacky 
---


Reviewed-by: Brijesh Singh 


Acked-by: Gary R Hook 





  drivers/crypto/ccp/psp-dev.c |    4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index ff478d8..973d683 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -84,8 +84,6 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
  static void sev_wait_cmd_ioc(struct psp_device *psp, unsigned int *reg)
  {
-    psp->sev_int_rcvd = 0;
-
  wait_event(psp->sev_int_queue, psp->sev_int_rcvd);
  *reg = ioread32(psp->io_regs + PSP_CMDRESP);
  }
@@ -148,6 +146,8 @@ static int __sev_do_cmd_locked(int cmd, void 
*data, int *psp_ret)

  iowrite32(phys_lsb, psp->io_regs + PSP_CMDBUFF_ADDR_LO);
  iowrite32(phys_msb, psp->io_regs + PSP_CMDBUFF_ADDR_HI);
+    psp->sev_int_rcvd = 0;
+
  reg = cmd;
  reg <<= PSP_CMDRESP_CMD_SHIFT;
  reg |= PSP_CMDRESP_IOC;





Re: [PATCH v1 4/5] crypto: ccp: Support register differences between PSP devices

2018-07-05 Thread Gary R Hook

On 07/03/2018 12:12 PM, Tom Lendacky wrote:

In preparation for adding a new PSP device ID that uses different register
offsets, add support to the PSP version data for register offset values.
And then update the code to use these new register offset values.

Signed-off-by: Tom Lendacky 


Acked-by: Gary R Hook 


---
  drivers/crypto/ccp/psp-dev.c |   24 
  drivers/crypto/ccp/psp-dev.h |9 -
  drivers/crypto/ccp/sp-dev.h  |7 ++-
  drivers/crypto/ccp/sp-pci.c  |7 ++-
  4 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 875756d..9b59638 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -62,14 +62,14 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
int reg;
  
  	/* Read the interrupt status: */

-   status = ioread32(psp->io_regs + PSP_P2CMSG_INTSTS);
+   status = ioread32(psp->io_regs + psp->vdata->intsts_reg);
  
  	/* Check if it is command completion: */

if (!(status & PSP_CMD_COMPLETE))
goto done;
  
  	/* Check if it is SEV command completion: */

-   reg = ioread32(psp->io_regs + PSP_CMDRESP);
+   reg = ioread32(psp->io_regs + psp->vdata->cmdresp_reg);
if (reg & PSP_CMDRESP_RESP) {
psp->sev_int_rcvd = 1;
wake_up(>sev_int_queue);
@@ -77,7 +77,7 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
  
  done:

/* Clear the interrupt status by writing the same value we read. */
-   iowrite32(status, psp->io_regs + PSP_P2CMSG_INTSTS);
+   iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
  
  	return IRQ_HANDLED;

  }
@@ -85,7 +85,7 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
  static void sev_wait_cmd_ioc(struct psp_device *psp, unsigned int *reg)
  {
wait_event(psp->sev_int_queue, psp->sev_int_rcvd);
-   *reg = ioread32(psp->io_regs + PSP_CMDRESP);
+   *reg = ioread32(psp->io_regs + psp->vdata->cmdresp_reg);
  }
  
  static int sev_cmd_buffer_len(int cmd)

@@ -143,15 +143,15 @@ static int __sev_do_cmd_locked(int cmd, void *data, int 
*psp_ret)
print_hex_dump_debug("(in):  ", DUMP_PREFIX_OFFSET, 16, 2, data,
 sev_cmd_buffer_len(cmd), false);
  
-	iowrite32(phys_lsb, psp->io_regs + PSP_CMDBUFF_ADDR_LO);

-   iowrite32(phys_msb, psp->io_regs + PSP_CMDBUFF_ADDR_HI);
+   iowrite32(phys_lsb, psp->io_regs + psp->vdata->cmdbuff_addr_lo_reg);
+   iowrite32(phys_msb, psp->io_regs + psp->vdata->cmdbuff_addr_hi_reg);
  
  	psp->sev_int_rcvd = 0;
  
  	reg = cmd;

reg <<= PSP_CMDRESP_CMD_SHIFT;
reg |= PSP_CMDRESP_IOC;
-   iowrite32(reg, psp->io_regs + PSP_CMDRESP);
+   iowrite32(reg, psp->io_regs + psp->vdata->cmdresp_reg);
  
  	/* wait for command completion */

sev_wait_cmd_ioc(psp, );
@@ -789,7 +789,7 @@ static int sev_misc_init(struct psp_device *psp)
  static int sev_init(struct psp_device *psp)
  {
/* Check if device supports SEV feature */
-   if (!(ioread32(psp->io_regs + PSP_FEATURE_REG) & 1)) {
+   if (!(ioread32(psp->io_regs + psp->vdata->feature_reg) & 1)) {
dev_dbg(psp->dev, "device does not support SEV\n");
return 1;
}
@@ -817,11 +817,11 @@ int psp_dev_init(struct sp_device *sp)
goto e_err;
}
  
-	psp->io_regs = sp->io_map + psp->vdata->offset;

+   psp->io_regs = sp->io_map;
  
  	/* Disable and clear interrupts until ready */

-   iowrite32(0, psp->io_regs + PSP_P2CMSG_INTEN);
-   iowrite32(-1, psp->io_regs + PSP_P2CMSG_INTSTS);
+   iowrite32(0, psp->io_regs + psp->vdata->inten_reg);
+   iowrite32(-1, psp->io_regs + psp->vdata->intsts_reg);
  
  	/* Request an irq */

ret = sp_request_psp_irq(psp->sp, psp_irq_handler, psp->name, psp);
@@ -838,7 +838,7 @@ int psp_dev_init(struct sp_device *sp)
sp->set_psp_master_device(sp);
  
  	/* Enable interrupt */

-   iowrite32(-1, psp->io_regs + PSP_P2CMSG_INTEN);
+   iowrite32(-1, psp->io_regs + psp->vdata->inten_reg);
  
  	dev_notice(dev, "psp enabled\n");
  
diff --git a/drivers/crypto/ccp/psp-dev.h b/drivers/crypto/ccp/psp-dev.h

index 5d46a2b..8b53a96 100644
--- a/drivers/crypto/ccp/psp-dev.h
+++ b/drivers/crypto/ccp/psp-dev.h
@@ -30,17 +30,8 @@
  
  #include "sp-dev.h"
  
-#define PSP_C2PMSG(_num)		((_num) << 2)

-#define PSP_CMDRESPPSP_C2PMSG(32)
-#define PSP_CMDBUFF_ADDR_LOPSP_C2PMSG(56)
-#define PSP_CMDBUFF_ADDR_HI PSP_C2PMSG(57)
-#define PSP_FEATURE_REGPSP_C2PMSG(63)
-
  #define PSP_CMD_COMPLETE  BIT(1

Re: [PATCH v1 3/5] crypto: ccp: Remove unused #defines

2018-07-05 Thread Gary R Hook

On 07/03/2018 12:11 PM, Tom Lendacky wrote:

Remove some unused #defines for register offsets that are not used. This
will lessen the changes required when register offsets change between
versions of the device.

Signed-off-by: Tom Lendacky 


Acked-by: Gary R Hook 


---
  drivers/crypto/ccp/psp-dev.c |2 +-
  drivers/crypto/ccp/psp-dev.h |   10 +-
  2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 91ef6ed..875756d 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -65,7 +65,7 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
status = ioread32(psp->io_regs + PSP_P2CMSG_INTSTS);
  
  	/* Check if it is command completion: */

-   if (!(status & BIT(PSP_CMD_COMPLETE_REG)))
+   if (!(status & PSP_CMD_COMPLETE))
goto done;
  
  	/* Check if it is SEV command completion: */

diff --git a/drivers/crypto/ccp/psp-dev.h b/drivers/crypto/ccp/psp-dev.h
index c7e9098a..5d46a2b 100644
--- a/drivers/crypto/ccp/psp-dev.h
+++ b/drivers/crypto/ccp/psp-dev.h
@@ -36,19 +36,11 @@
  #define PSP_CMDBUFF_ADDR_HI PSP_C2PMSG(57)
  #define PSP_FEATURE_REG   PSP_C2PMSG(63)
  
-#define PSP_P2CMSG(_num)		((_num) << 2)

-#define PSP_CMD_COMPLETE_REG   1
-#define PSP_CMD_COMPLETE   PSP_P2CMSG(PSP_CMD_COMPLETE_REG)
+#define PSP_CMD_COMPLETE   BIT(1)
  
  #define PSP_P2CMSG_INTEN		0x0110

  #define PSP_P2CMSG_INTSTS 0x0114
  
-#define PSP_C2PMSG_ATTR_0		0x0118

-#define PSP_C2PMSG_ATTR_1  0x011c
-#define PSP_C2PMSG_ATTR_2  0x0120
-#define PSP_C2PMSG_ATTR_3  0x0124
-#define PSP_P2CMSG_ATTR_0  0x0128
-
  #define PSP_CMDRESP_CMD_SHIFT 16
  #define PSP_CMDRESP_IOC   BIT(0)
  #define PSP_CMDRESP_RESP  BIT(31)





Re: [PATCH v1 2/5] crypto: ccp: Add psp enabled message when initialization succeeds

2018-07-05 Thread Gary R Hook

On 07/03/2018 12:11 PM, Tom Lendacky wrote:

Add a dev_notice() message to the PSP initialization to report when the
PSP initialization has succeeded and the PSP is enabled.

Signed-off-by: Tom Lendacky 


Acked-by: Gary R Hook 


---
  drivers/crypto/ccp/psp-dev.c |2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 973d683..91ef6ed 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -840,6 +840,8 @@ int psp_dev_init(struct sp_device *sp)
/* Enable interrupt */
iowrite32(-1, psp->io_regs + PSP_P2CMSG_INTEN);
  
+	dev_notice(dev, "psp enabled\n");

+
return 0;
  
  e_irq:






Re: [PATCH v1 1/5] crypto: ccp: Fix command completion detection race

2018-07-05 Thread Gary R Hook

On 07/03/2018 12:11 PM, Tom Lendacky wrote:

The wait_event() function is used to detect command completion.  The
interrupt handler will set the wait condition variable when the interrupt
is triggered.  However, the variable used for wait_event() is initialized
after the command has been submitted, which can create a race condition
with the interrupt handler and result in the wait_event() never returning.
Move the initialization of the wait condition variable to just before
command submission.

Fixes: 200664d5237f ("crypto: ccp: Add Secure Encrypted Virtualization (SEV) command 
support")
Cc:  # 4.16.x-
Signed-off-by: Tom Lendacky 


Acked-by: Gary R Hook 


---
  drivers/crypto/ccp/psp-dev.c |4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index ff478d8..973d683 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -84,8 +84,6 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
  
  static void sev_wait_cmd_ioc(struct psp_device *psp, unsigned int *reg)

  {
-   psp->sev_int_rcvd = 0;
-
wait_event(psp->sev_int_queue, psp->sev_int_rcvd);
*reg = ioread32(psp->io_regs + PSP_CMDRESP);
  }
@@ -148,6 +146,8 @@ static int __sev_do_cmd_locked(int cmd, void *data, int 
*psp_ret)
iowrite32(phys_lsb, psp->io_regs + PSP_CMDBUFF_ADDR_LO);
iowrite32(phys_msb, psp->io_regs + PSP_CMDBUFF_ADDR_HI);
  
+	psp->sev_int_rcvd = 0;

+
reg = cmd;
reg <<= PSP_CMDRESP_CMD_SHIFT;
reg |= PSP_CMDRESP_IOC;





[PATCH] crypto: doc - Document remaining members in struct crypto_alg

2018-03-14 Thread Gary R Hook
Add missing comments for union members ablkcipher, blkcipher,
cipher, and compress. This silences complaints when building
the htmldocs.

Fixes: 0d7f488f0305a (crypto: doc - cipher data structures)
Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 include/linux/crypto.h |8 
 1 file changed, 8 insertions(+)

diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 7e6e84cf6383..6eb06101089f 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -435,6 +435,14 @@ struct compress_alg {
  * @cra_exit: Deinitialize the cryptographic transformation object. This is a
  *   counterpart to @cra_init, used to remove various changes set in
  *   @cra_init.
+ * @cra_u.ablkcipher: Union member which contains an asynchronous block cipher
+ *   definition. See @struct @ablkcipher_alg.
+ * @cra_u.blkcipher: Union member which contains a synchronous block cipher
+ *  definition See @struct @blkcipher_alg.
+ * @cra_u.cipher: Union member which contains a single-block symmetric cipher
+ *   definition. See @struct @cipher_alg.
+ * @cra_u.compress: Union member which contains a (de)compression algorithm.
+ * See @struct @compress_alg.
  * @cra_module: Owner of this transformation implementation. Set to THIS_MODULE
  * @cra_list: internally used
  * @cra_users: internally used



[PATCH] crypto/ccp - Fill the result buffer only on digest, finup, and final ops

2018-03-07 Thread Gary R Hook
Any change to the result buffer should only happen on final, finup
and digest operations. Changes to the buffer for update, import, export,
etc, are not allowed.

Fixes: 66d7b9f6175e ("crypto: testmgr - test misuse of result in ahash")
Signed-off-by: Gary R Hook <gary.h...@amd.com>
Cc: <sta...@vger.kernel.org>
---
 0 files changed

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c 
b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
index 60fc0fa26fd3..26687f318de6 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
@@ -46,7 +46,7 @@ static int ccp_aes_cmac_complete(struct crypto_async_request 
*async_req,
}
 
/* Update result area if supplied */
-   if (req->result)
+   if (req->result && rctx->final)
memcpy(req->result, rctx->iv, digest_size);
 
 e_free:
diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c 
b/drivers/crypto/ccp/ccp-crypto-sha.c
index 8b9b16d433f7..871c9628a2ee 100644
--- a/drivers/crypto/ccp/ccp-crypto-sha.c
+++ b/drivers/crypto/ccp/ccp-crypto-sha.c
@@ -47,7 +47,7 @@ static int ccp_sha_complete(struct crypto_async_request 
*async_req, int ret)
}
 
/* Update result area if supplied */
-   if (req->result)
+   if (req->result && rctx->final)
memcpy(req->result, rctx->ctx, digest_size);
 
 e_free:



[PATCH] crypto/ccp: Validate buffer lengths for copy operations

2018-03-07 Thread Gary R Hook
The CCP driver copies data between scatter/gather lists and DMA buffers.
The length of the requested copy operation must be checked against
the available destination buffer length.

Reported-by: Maciej S. Szmigiero <m...@maciej.szmigiero.name>
Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 0 files changed

diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 406b95329b3d..0ea43cdeb05f 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -178,14 +178,18 @@ static int ccp_init_dm_workarea(struct ccp_dm_workarea 
*wa,
return 0;
 }
 
-static void ccp_set_dm_area(struct ccp_dm_workarea *wa, unsigned int wa_offset,
-   struct scatterlist *sg, unsigned int sg_offset,
-   unsigned int len)
+static int ccp_set_dm_area(struct ccp_dm_workarea *wa, unsigned int wa_offset,
+  struct scatterlist *sg, unsigned int sg_offset,
+  unsigned int len)
 {
WARN_ON(!wa->address);
 
+   if (len > (wa->length - wa_offset))
+   return -EINVAL;
+
scatterwalk_map_and_copy(wa->address + wa_offset, sg, sg_offset, len,
 0);
+   return 0;
 }
 
 static void ccp_get_dm_area(struct ccp_dm_workarea *wa, unsigned int wa_offset,
@@ -205,8 +209,11 @@ static int ccp_reverse_set_dm_area(struct ccp_dm_workarea 
*wa,
   unsigned int len)
 {
u8 *p, *q;
+   int rc;
 
-   ccp_set_dm_area(wa, wa_offset, sg, sg_offset, len);
+   rc = ccp_set_dm_area(wa, wa_offset, sg, sg_offset, len);
+   if (rc)
+   return rc;
 
p = wa->address + wa_offset;
q = p + len - 1;
@@ -509,7 +516,9 @@ static int ccp_run_aes_cmac_cmd(struct ccp_cmd_queue *cmd_q,
return ret;
 
dm_offset = CCP_SB_BYTES - aes->key_len;
-   ccp_set_dm_area(, dm_offset, aes->key, 0, aes->key_len);
+   ret = ccp_set_dm_area(, dm_offset, aes->key, 0, aes->key_len);
+   if (ret)
+   goto e_key;
ret = ccp_copy_to_sb(cmd_q, , op.jobid, op.sb_key,
 CCP_PASSTHRU_BYTESWAP_256BIT);
if (ret) {
@@ -528,7 +537,9 @@ static int ccp_run_aes_cmac_cmd(struct ccp_cmd_queue *cmd_q,
goto e_key;
 
dm_offset = CCP_SB_BYTES - AES_BLOCK_SIZE;
-   ccp_set_dm_area(, dm_offset, aes->iv, 0, aes->iv_len);
+   ret = ccp_set_dm_area(, dm_offset, aes->iv, 0, aes->iv_len);
+   if (ret)
+   goto e_ctx;
ret = ccp_copy_to_sb(cmd_q, , op.jobid, op.sb_ctx,
 CCP_PASSTHRU_BYTESWAP_256BIT);
if (ret) {
@@ -556,8 +567,10 @@ static int ccp_run_aes_cmac_cmd(struct ccp_cmd_queue 
*cmd_q,
goto e_src;
}
 
-   ccp_set_dm_area(, 0, aes->cmac_key, 0,
-   aes->cmac_key_len);
+   ret = ccp_set_dm_area(, 0, aes->cmac_key, 0,
+ aes->cmac_key_len);
+   if (ret)
+   goto e_src;
ret = ccp_copy_to_sb(cmd_q, , op.jobid, op.sb_ctx,
 CCP_PASSTHRU_BYTESWAP_256BIT);
if (ret) {
@@ -666,7 +679,9 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,
return ret;
 
dm_offset = CCP_SB_BYTES - aes->key_len;
-   ccp_set_dm_area(, dm_offset, aes->key, 0, aes->key_len);
+   ret = ccp_set_dm_area(, dm_offset, aes->key, 0, aes->key_len);
+   if (ret)
+   goto e_key;
ret = ccp_copy_to_sb(cmd_q, , op.jobid, op.sb_key,
 CCP_PASSTHRU_BYTESWAP_256BIT);
if (ret) {
@@ -685,7 +700,9 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,
goto e_key;
 
dm_offset = CCP_AES_CTX_SB_COUNT * CCP_SB_BYTES - aes->iv_len;
-   ccp_set_dm_area(, dm_offset, aes->iv, 0, aes->iv_len);
+   ret = ccp_set_dm_area(, dm_offset, aes->iv, 0, aes->iv_len);
+   if (ret)
+   goto e_ctx;
 
ret = ccp_copy_to_sb(cmd_q, , op.jobid, op.sb_ctx,
 CCP_PASSTHRU_BYTESWAP_256BIT);
@@ -777,7 +794,9 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,
goto e_dst;
}
 
-   ccp_set_dm_area(, dm_offset, aes->iv, 0, aes->iv_len);
+   ret = ccp_set_dm_area(, dm_offset, aes->iv, 0, aes->iv_len);
+   if (ret)
+   goto e_dst;
 
ret = ccp_copy_to_sb(cmd_q, , op.jobid, op.sb_ctx,
 CCP_PASSTHRU_BYTESWAP_256BIT);
@@ -820,7 +839,9 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,
   DMA_BIDI

Re: Why are we testing an intermediate result in ahash?

2018-03-05 Thread Gary R Hook

On 03/05/2018 12:31 PM, Kamil Konieczny wrote:



On 05.03.2018 18:47, Gary R Hook wrote:

On 03/05/2018 03:57 AM, Kamil Konieczny wrote:



On 02.03.2018 22:11, Gary R Hook wrote:

Commit 466d7b9f6 (cryptodev-2.6) added code to testmgr to populate, for async 
hash operations,
the result buffer with a known value and to test the buffer against that value 
at intermediate
steps. If the result buffer changes the operation is failed.

My question is: why?

What problem does this solve? Has this requirement existed all along, or is it 
new?

I'm now seeing complaints for AES/CMAC and SHA in my driver. I have no problem 
updating the driver,
of course, but I'd like to better understand the precipitating issue for the 
commit.

Mar  2 12:30:56 sosxen2 kernel: [   60.919198] alg: No test for cfb(aes) 
(cfb-aes-ccp)
Mar  2 12:30:56 sosxen2 kernel: [   60.924787] 367: alg: hash: update failed on 
test 3 for cmac-aes-ccp: used req->result
Mar  2 12:30:56 sosxen2 kernel: [   60.946571] 367: alg: hash: update failed on 
test 4 for sha1-ccp: used req->result
Mar  2 12:30:56 sosxen2 kernel: [   60.956461] 367: alg: hash: update failed on 
test 1 for hmac-sha1-ccp: used req->result
Mar  2 12:30:56 sosxen2 kernel: [   60.966117] 367: alg: hash: update failed on 
test 4 for sha224-ccp: used req->result


ahash req->result can be used in digit, final and finup hash operations.
It should not be used in init and update (nor in export and import).


Where is this documented, please? I'm not seeing it in Documentation/crypto. Of 
course, I could be looking for the wrong thing.


It was recent addition, and you are right, the doc needs update.


So a failure to communicate a newly-required behavior change, much less 
document it, is addressed by breaking drivers?  For some reason this 
seems wrong.


It's also wrong to change the documentation after the fact, and after 
surprising people. The documentation change should have gone in with the 
change to testmgr. And all that -after- doing as suggested below.



There were some bugs in past, when drivers try to use req->result
as theirs temporary storage.
The bug comes up in some scenarios when caller reused ahash request
and leaves in req->result undefined value, it can be NULL or container_of(NULL)
or whatever was on stack



As I mention in my other post, our driver vets the pointer before dereference.


Problem will not happen with NULL, but only because there is code like 
(pseudocode)
in ahash_update:

1: if (req->result == NULL)
2:   // use as temp memory ahash request context
3: else
4:  // use as temp memory req->result

The point is - if we need temporary storage for keeping some state between 
updates,
we should use ahash request context, and get rid of the code lines 1,3,4


We are not using the buffer for temporary storage, we are returning an 
intermediate result. Which, as far as we can tell, is in no way a problem.


IOW I still fail to see how this is an issue for our driver. All I see 
is a change that impacts us yet isn't relevant.



The line 4 can bite us when req->result will be neither NULL nor valid memory 
pointer.
The second argument is, why we bother to check with 1: when we can should 
already do 2: only


And I don't have a problem with a clear definition of what should and should 
not happen to
buffers offered by a caller. I simply want to know where this behavior is 
defined, and is it a change from the past?


This come up after some code review.


I'd like to suggest that if a change in the framework is required that 
the change is communicated to the maintainers, along with the expected 
impact of that change, and that a discussion takes place proactively. 
Not after getting surprised by driver breakage and a patch out of left 
field.


All IMO, of course.


Re: [PATCH] crypto: ccp: Use memdup_user() rather than duplicating its implementation

2018-03-05 Thread Gary R Hook

On 03/05/2018 07:10 AM, SF Markus Elfring wrote:

From: Markus Elfring <elfr...@users.sourceforge.net>
Date: Mon, 5 Mar 2018 13:50:13 +0100

Reuse existing functionality from memdup_user() instead of keeping
duplicate source code.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfr...@users.sourceforge.net>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
  drivers/crypto/ccp/psp-dev.c | 15 +--
  1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index fcfa5b1eae61..8255258cd040 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -367,8 +367,6 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp)
  
  void *psp_copy_user_blob(u64 __user uaddr, u32 len)

  {
-   void *data;
-
if (!uaddr || !len)
return ERR_PTR(-EINVAL);
  
@@ -376,18 +374,7 @@ void *psp_copy_user_blob(u64 __user uaddr, u32 len)

if (len > SEV_FW_BLOB_MAX_SIZE)
return ERR_PTR(-EINVAL);
  
-	data = kmalloc(len, GFP_KERNEL);

-   if (!data)
-   return ERR_PTR(-ENOMEM);
-
-   if (copy_from_user(data, (void __user *)(uintptr_t)uaddr, len))
-   goto e_free;
-
-   return data;
-
-e_free:
-   kfree(data);
-   return ERR_PTR(-EFAULT);
+   return memdup_user((void __user *)(uintptr_t)uaddr, len);
  }
  EXPORT_SYMBOL_GPL(psp_copy_user_blob);
  





Re: Why are we testing an intermediate result in ahash?

2018-03-05 Thread Gary R Hook

On 03/05/2018 03:57 AM, Kamil Konieczny wrote:



On 02.03.2018 22:11, Gary R Hook wrote:

Commit 466d7b9f6 (cryptodev-2.6) added code to testmgr to populate, for async 
hash operations,
the result buffer with a known value and to test the buffer against that value 
at intermediate
steps. If the result buffer changes the operation is failed.

My question is: why?

What problem does this solve? Has this requirement existed all along, or is it 
new?

I'm now seeing complaints for AES/CMAC and SHA in my driver. I have no problem 
updating the driver,
of course, but I'd like to better understand the precipitating issue for the 
commit.

Mar  2 12:30:56 sosxen2 kernel: [   60.919198] alg: No test for cfb(aes) 
(cfb-aes-ccp)
Mar  2 12:30:56 sosxen2 kernel: [   60.924787] 367: alg: hash: update failed on 
test 3 for cmac-aes-ccp: used req->result
Mar  2 12:30:56 sosxen2 kernel: [   60.946571] 367: alg: hash: update failed on 
test 4 for sha1-ccp: used req->result
Mar  2 12:30:56 sosxen2 kernel: [   60.956461] 367: alg: hash: update failed on 
test 1 for hmac-sha1-ccp: used req->result
Mar  2 12:30:56 sosxen2 kernel: [   60.966117] 367: alg: hash: update failed on 
test 4 for sha224-ccp: used req->result


ahash req->result can be used in digit, final and finup hash operations.
It should not be used in init and update (nor in export and import).


Where is this documented, please? I'm not seeing it in 
Documentation/crypto. Of course, I could be looking for the wrong thing.




There were some bugs in past, when drivers try to use req->result
as theirs temporary storage.
The bug comes up in some scenarios when caller reused ahash request
and leaves in req->result undefined value, it can be NULL or container_of(NULL)
or whatever was on stack



As I mention in my other post, our driver vets the pointer before 
dereference. And I don't have a problem with a clear definition of what 
should and should not happen to buffers offered by a caller. I simply 
want to know where this behavior is defined, and is it a change from the 
past?


Re: Why are we testing an intermediate result in ahash?

2018-03-05 Thread Gary R Hook

On 03/05/2018 03:50 AM, Herbert Xu wrote:

On Fri, Mar 02, 2018 at 03:11:52PM -0600, Gary R Hook wrote:

Commit 466d7b9f6 (cryptodev-2.6) added code to testmgr to populate, for
async hash operations, the result buffer with a known value and to test the
buffer against that value at intermediate steps. If the result buffer
changes the operation is failed.

My question is: why?


The problem is that you must not touch the result buffer unless
you're doing a finalisation.  Indeed, the caller may have provided
a NULL pointer for what it's worth.

Cheers,



Good thing I'm not afraid of appearing dense.

Where is this documented? Has this requirement always been thus, and 
only the recent patch is testing for it? -Why- mustn't we touch that buffer?


As for a NULL pointer, our driver checks for that, so that's not an 
issue. Although I get your point.





Re: [PATCH 2/3] crypto: ccp - return an actual key size from RSA max_size callback

2018-03-02 Thread Gary R Hook

On 03/02/2018 05:58 PM, Maciej S. Szmigiero wrote:

On 03.03.2018 00:49, Hook, Gary wrote:

On 3/2/2018 5:15 PM, Maciej S. Szmigiero wrote:


Thanks.

However, what about the first patch from this series?
Without it, while it no longer should cause a buffer overflow, in-kernel
X.509 certificate verification will still fail with CCP driver loaded
(since CCP RSA implementation has a higher priority than the software
RSA implementation).

Maciej




I commented on that one here:
https://marc.info/?l=linux-crypto-vger=151986452422791=2

Effectively a NACK. We are a reviewing a proposed patch right now.


Your earlier comment referred to the third patch from this series.
My message above was about the first one.


Apologies; my mistake.



Why are we testing an intermediate result in ahash?

2018-03-02 Thread Gary R Hook
Commit 466d7b9f6 (cryptodev-2.6) added code to testmgr to populate, for 
async hash operations, the result buffer with a known value and to test 
the buffer against that value at intermediate steps. If the result 
buffer changes the operation is failed.


My question is: why?

What problem does this solve? Has this requirement existed all along, or 
is it new?


I'm now seeing complaints for AES/CMAC and SHA in my driver. I have no 
problem updating the driver, of course, but I'd like to better 
understand the precipitating issue for the commit.


Mar  2 12:30:56 sosxen2 kernel: [   60.919198] alg: No test for cfb(aes) 
(cfb-aes-ccp)
Mar  2 12:30:56 sosxen2 kernel: [   60.924787] 367: alg: hash: update 
failed on test 3 for cmac-aes-ccp: used req->result
Mar  2 12:30:56 sosxen2 kernel: [   60.946571] 367: alg: hash: update 
failed on test 4 for sha1-ccp: used req->result
Mar  2 12:30:56 sosxen2 kernel: [   60.956461] 367: alg: hash: update 
failed on test 1 for hmac-sha1-ccp: used req->result
Mar  2 12:30:56 sosxen2 kernel: [   60.966117] 367: alg: hash: update 
failed on test 4 for sha224-ccp: used req->result

...

Thanks,
Gary


Re: [PATCH 3/3] crypto: ccp - protect RSA implementation from too large input data

2018-02-28 Thread Gary R Hook

On 02/24/2018 10:03 AM, Maciej S. Szmigiero wrote:

CCP RSA implementation uses a hardware input buffer which size depends only
on the current RSA key length. Key modulus and a message to be processed
is then copied to this buffer based on their own lengths.

Since the price for providing too long input data is a buffer overflow and
there already has been a case when this has happened let's better reject
such oversized input data and log an error message in this case so we know
what is going on.

Signed-off-by: Maciej S. Szmigiero 
---
  drivers/crypto/ccp/ccp-ops.c | 24 
  1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 406b95329b3d..517aeee30abf 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1770,10 +1770,6 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
if (!rsa->exp || !rsa->mod || !rsa->src || !rsa->dst)
return -EINVAL;
  
-	memset(, 0, sizeof(op));

-   op.cmd_q = cmd_q;
-   op.jobid = CCP_NEW_JOBID(cmd_q->ccp);
-
/* The RSA modulus must precede the message being acted upon, so
 * it must be copied to a DMA area where the message and the
 * modulus can be concatenated.  Therefore the input buffer
@@ -1785,6 +1781,26 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
o_len = 32 * ((rsa->key_size + 255) / 256);
i_len = o_len * 2;
  
+	if (rsa->mod_len > o_len) {

+   dev_err(cmd_q->ccp->dev,
+   "RSA modulus of %u bytes too large for key size of %u 
bits\n",
+   (unsigned int)rsa->mod_len,
+   (unsigned int)rsa->key_size);
+   return -EINVAL;
+   }
+
+   if (rsa->src_len > o_len) {
+   dev_err(cmd_q->ccp->dev,
+   "RSA data of %u bytes too large for key size of %u 
bits\n",
+   (unsigned int)rsa->src_len,
+   (unsigned int)rsa->key_size);
+   return -EINVAL;
+   }


We've talked about this, and we believe that a more central fix is 
warranted. I intend to post another patch tomorrow that should address

this problem.


+
+   memset(, 0, sizeof(op));
+   op.cmd_q = cmd_q;
+   op.jobid = CCP_NEW_JOBID(cmd_q->ccp);
+
sb_count = 0;
if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0)) {
/* sb_count is the number of storage block slots required





Re: [PATCH 2/3] crypto: ccp - return an actual key size from RSA max_size callback

2018-02-28 Thread Gary R Hook

On 02/24/2018 10:03 AM, Maciej S. Szmigiero wrote:

rsa-pkcs1pad uses a value returned from a RSA implementation max_size
callback as a size of an input buffer passed to the RSA implementation for
encrypt and sign operations.

CCP RSA implementation uses a hardware input buffer which size depends only
on the current RSA key length, so it should return this key length in
the max_size callback, too.
This also matches what the kernel software RSA implementation does.

Previously, the value returned from this callback was always the maximum
RSA key size the CCP hardware supports.
This resulted in this huge buffer being passed by rsa-pkcs1pad to CCP even
for smaller key sizes and then in a buffer overflow when ccp_run_rsa_cmd()
tried to copy this large input buffer into a RSA key length-sized hardware
input buffer.

Signed-off-by: Maciej S. Szmigiero <m...@maciej.szmigiero.name>


Acked-by: Gary R Hook <gary.h...@amd.com>


Fixes: ceeec0afd684 ("crypto: ccp - Add support for RSA on the CCP")
Cc: sta...@vger.kernel.org
---
  drivers/crypto/ccp/ccp-crypto-rsa.c | 7 +++
  1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-rsa.c 
b/drivers/crypto/ccp/ccp-crypto-rsa.c
index e6db8672d89c..05850dfd7940 100644
--- a/drivers/crypto/ccp/ccp-crypto-rsa.c
+++ b/drivers/crypto/ccp/ccp-crypto-rsa.c
@@ -60,10 +60,9 @@ static int ccp_rsa_complete(struct crypto_async_request 
*async_req, int ret)
  
  static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)

  {
-   if (ccp_version() > CCP_VERSION(3, 0))
-   return CCP5_RSA_MAXMOD;
-   else
-   return CCP_RSA_MAXMOD;
+   struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+   return ctx->u.rsa.n_len;
  }
  
  static int ccp_rsa_crypt(struct akcipher_request *req, bool encrypt)






Re: Can a driver->probe be called for two devices at the same time (WAS: Re: [PATCH] crypto/ccp: don't disable interrupts while setting up debugfs)

2018-02-27 Thread Gary R Hook

On 02/27/2018 01:36 PM, Sebastian Andrzej Siewior wrote:

On 2018-02-27 19:40:34 [+0100], Greg Kroah-Hartman wrote:

On Tue, Feb 27, 2018 at 06:33:14PM +0100, Sebastian Andrzej Siewior wrote:

On 2018-02-27 11:08:56 [-0600], Gary R Hook wrote:

That issue remains unclear to me: Are probes of PCI devices guaranteed to be
serialized? Observations on my CCPs says that they occur in order, but I
don't know for certain that serialization is guaranteed.

Is there a definitive statement on this somewhere that I just don't know
about?


The bus enforces this.


So the question if a driver can probe two devices simultaneously.


Depends on the bus type.


PCI


So the question is whether or not PCI enforces serial activity within a 
domain. The CCPs are all on different buses, so that doesn't matter.


I think we don't care in this situation, given that the CCP driver has 
minor requirements for locking. I just found it an interesting (albeit 
somewhat academic) question.


Thanks,
Gary


Re: Can a driver->probe be called for two devices at the same time (WAS: Re: [PATCH] crypto/ccp: don't disable interrupts while setting up debugfs)

2018-02-27 Thread Gary R Hook

On 02/27/2018 11:33 AM, Sebastian Andrzej Siewior wrote:

On 2018-02-27 11:08:56 [-0600], Gary R Hook wrote:

That issue remains unclear to me: Are probes of PCI devices guaranteed to be
serialized? Observations on my CCPs says that they occur in order, but I
don't know for certain that serialization is guaranteed.

Is there a definitive statement on this somewhere that I just don't know
about?


So the question if a driver can probe two devices simultaneously. I'm
not sure. We have PROBE_PREFER_ASYNCHRONOUS which defers the probe to
worker. However I have no idea if two of those worker can run at the
same time.


I think a mutex would be just fine; I got this wrong, clearly. Let me work
up a patch using a mutex.


I've sent one. Why not just ack it and be done with it?


Gary


Sebastian



Sorry, too much chaos right now. Of course.


Re: [PATCH] crypto/ccp: don't disable interrupts while setting up debugfs

2018-02-27 Thread Gary R Hook

On 02/26/2018 02:35 AM, Sebastian Andrzej Siewior wrote:

On 2018-02-25 21:04:27 [-0500], Hook, Gary wrote:

On 2/23/2018 5:33 PM, Sebastian Andrzej Siewior wrote:

I don't why we need take a single write lock and disable interrupts
while setting up debugfs. This is what what happens when we try anyway:


There is more than one CCP on some processors. The lock is intended to
serialize attempts to initialize the new directory, but a R/W lock isn't
required.


And they are probed in parallel? Any you need disable interrupts while
creating the debugfs folder? A mutex isn't enough?


That issue remains unclear to me: Are probes of PCI devices guaranteed 
to be serialized? Observations on my CCPs says that they occur in order, 
but I don't know for certain that serialization is guaranteed.


Is there a definitive statement on this somewhere that I just don't know 
about?


I think a mutex would be just fine; I got this wrong, clearly. Let me 
work up a patch using a mutex.


Gary




Re: [PATCH v2] hwrng: Clean up RNG list when last hwrng is unregistered

2018-01-08 Thread Gary R Hook

On 01/07/2018 11:05 PM, Herbert Xu wrote:

On Fri, Jan 05, 2018 at 11:28:23AM -0600, Gary R Hook wrote:


It may not have been obvious from the title but this fixes a bug
which will impact the use of any HW RNG that is the only RNG
registered. The breakage of rmmod/modprobe -r that this fix obviates
suggests that it needs to make the 4.15 kernel, please. Just want to
ensure this gets the proper attention. Thank you.


I don't think breaking rmmod is sufficiently serious to warrant
immediate inclusion at this point.  We can always send it via
stable after the release.

Thanks,



Oh. I just figured that problems introduced in a particular kernel level 
should be resolved (if possible) in that same level.


Your call, of course; thank you for the clarification.


Re: [PATCH v2] hwrng: Clean up RNG list when last hwrng is unregistered

2018-01-05 Thread Gary R Hook

On 12/15/2017 01:55 PM, Gary R Hook wrote:

Commit 142a27f0a731 added support for a "best" RNG, and in doing so
introduced a hang from rmmod/modprobe -r when the last RNG on the list
was unloaded.

When the hwrng list is depleted, return the global variables to their
original state and decrement all references to the object.


*ping*

It may not have been obvious from the title but this fixes a bug which 
will impact the use of any HW RNG that is the only RNG registered. The 
breakage of rmmod/modprobe -r that this fix obviates suggests that it 
needs to make the 4.15 kernel, please. Just want to ensure this gets the 
proper attention. Thank you.





Fixes: 142a27f0a731 ("hwrng: core - Reset user selected rng by writing "" to 
rng_current")
Signed-off-by: Gary R Hook <gary.h...@amd.com>
---

Changes since v1: fix misspelled word in subject

  drivers/char/hw_random/core.c |4 
  1 file changed, 4 insertions(+)

diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 657b8770b6b9..91bb98c42a1c 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -306,6 +306,10 @@ static int enable_best_rng(void)
ret = ((new_rng == current_rng) ? 0 : set_current_rng(new_rng));
if (!ret)
cur_rng_set_by_user = 0;
+   } else {
+   drop_current_rng();
+   cur_rng_set_by_user = 0;
+   ret = 0;
}
  
  	return ret;




[Desktop Entry]
Encoding=UTF-8
Name=Thunderbird Mail
Name[ast]=Veceru de corréu Thunderbird
Name[ca]=Client de correu Thunderbird
Name[cs]=Poštovní klient Thunderbird
Name[da]=Mozilla Thunderbird - e-post/nyhedsgruppe
Name[de]=Thunderbird-E-Mail und -Nachrichten
Name[el]=Ηλεκτρονική αλληλογραφία Thunderbird
Name[es]=Cliente de correo Thunderbird
Name[fi]=Thunderbird-sähköposti
Name[fr]=Messagerie Thunderbird
Name[gl]=Cliente de correo Thunderbird
Name[he]=Mozilla Thunderbird דוא״ל/חדשות
Name[hr]=Mozilla Thunderbird e-pošta/novosti
Name[hu]=Thunderbird levelezőkliens
Name[it]=Email Mozilla Thunderbird
Name[ja]=Thunderbird電子メールクライアント
Name[ko]=Mozilla Thunderbird
Name[nl]=Mozilla Thunderbird e-mail/nieuws
Name[pl]=Klient poczty Thunderbird
Name[pt_BR]=Cliente de E-mail Thunderbird
Name[ru]=Почтовый клиент Thunderbird
Name[sk]=Thunderbird - poštový klient
Name[sv]=E-postklienten Thunderbird
Name[ug]=Mozilla Thunderbird ئېلخەت/خەۋەر
Name[uk]=Поштова програма Thunderbird
Name[vi]=Trình điện thư Mozilla Thunderbird
Name[zh_CN]=Thunderbird 邮件/新闻
Name[zh_TW]=Thunderbird 郵件
Comment=Send and receive mail with Thunderbird
Comment[ast]=Lleer y escribir corréu electrónicu
Comment[ca]=Llegiu i escriviu correu
Comment[cs]=Čtení a psaní pošty
Comment[da]=Skriv/læs e-post/nyhedsgruppe med Mozilla Thunderbird
Comment[de]=E-Mails und Nachrichten mit Thunderbird lesen und schreiben
Comment[el]=Διαβάστε και γράψτε γράμματα με το Mozilla Thunderbird
Comment[es]=Lea y escriba correos y noticias con Thunderbird
Comment[fi]=Lue ja kirjoita sähköposteja
Comment[fr]=Lire et écrire des courriels
Comment[gl]=Lea e escriba correo electrónico
Comment[he]=קריאה/כתיבה של דוא״ל/חדשות באמצעות Mozilla Thunderbird
Comment[hr]=Čitajte/šaljite e-poštu s Thunderbird
Comment[hu]=Levelek írása és olvasása a Thunderbirddel
Comment[it]=Per leggere e scrivere email
Comment[ja]=メールの読み書き
Comment[ko]=Mozilla Thunderbird 메일/뉴스 읽기 및 쓰기 클라이언트
Comment[nl]=E-mail/nieuws lezen en schrijven met Mozilla Thunderbird
Comment[pl]=Czytanie i wysyłanie e-maili
Comment[pt_BR]=Leia e escreva suas mensagens
Comment[ru]=Читайте и пишите письма
Comment[sk]=Čítajte a píšte poštu pomocou programu Thunderbird
Comment[sv]=Läs och skriv e-post
Comment[ug]=ئېلخەت ۋە خەۋەرلەرنى Mozilla Thunderbird دا كۆرۈش ۋە يېزىش
Comment[uk]=Читання та написання листів
Comment[vi]=Đọc và soạn thư điện tử
Comment[zh_CN]=阅读邮件或新闻
Comment[zh_TW]=以 Mozilla Thunderbird 讀寫郵件或新聞
GenericName=Mail Client
GenericName[ast]=Client de correu
GenericName[ca]=Client de correu
GenericName[cs]=Poštovní klient
GenericName[da]=E-postklient
GenericName[de]=E-Mail-Anwendung
GenericName[el]=Λογισμικό αλληλογραφίας
GenericName[es]=Cliente de correo
GenericName[fi]=Sähköpostiohjelma
GenericName[fr]=Client de messagerie
GenericName[gl]=Cliente de correo electrónico
GenericName[he]=לקוח דוא״ל
GenericName[hr]=Klijent e-pošte
GenericName[hu]=Levelezőkliens
GenericName[it]=Client email
GenericName[ja]=電子メールクライアント
GenericName[ko]=메일 클라이언트
GenericName[nl]=E-mailprogramma
GenericName[pt_BR]=Cliente de E-mail
GenericName[ru]=Почтовый клиент
GenericName[sk]=Poštový klient
GenericName[ug]=ئېلخەت دېتالى
GenericName[uk]=Поштова програма
GenericName[vi]=Phần mềm khách quản lý thư điện tử
GenericName[zh_CN]=邮件新闻客户端
GenericName[zh_TW]=郵件用戶端
Keywords=Email;E-mail;Newsgroup;Feed;RSS
Keywords[ast]=Corréu;Corréu-e;Noticies;Discusiones;Mensaxes;Canales;RSS
Keywords[ca]=Correu;Email;E-mail;Mailing;Llistes;Notícies;RSS
Keywords[cs]=Email;E-mail;Pošta

Re: [PATCH] iommu/amd - Set the device table entry PPR bit for IOMMU V2 devices

2017-12-20 Thread Gary R Hook

Please ignore; sent to the wrong list. Mea culpa.

On 12/20/2017 10:57 AM, Gary R Hook wrote:

The AMD IOMMU specification Rev 3.00 (December 2016) introduces a
new Enhanced PPR Handling Support (EPHSup) bit in the MMIO register
offset 0030h (IOMMU Extended Feature Register).

When EPHSup=1, the IOMMU hardware requires the PPR bit of the
device table entry (DTE) to be set in order to support PPR for a
particular endpoint device.

Please see https://support.amd.com/TechDocs/48882_IOMMU.pdf for
this revision of the AMD IOMMU specification.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
  drivers/iommu/amd_iommu.c   |   20 +++-
  drivers/iommu/amd_iommu_types.h |2 ++
  2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index cb78933ef53f..5f3da95ff6a0 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1818,7 +1818,8 @@ static bool dma_ops_domain(struct protection_domain 
*domain)
return domain->flags & PD_DMA_OPS_MASK;
  }
  
-static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)

+static void set_dte_entry(u16 devid, struct protection_domain *domain,
+ bool ats, bool ppr)
  {
u64 pte_root = 0;
u64 flags = 0;
@@ -1835,6 +1836,13 @@ static void set_dte_entry(u16 devid, struct 
protection_domain *domain, bool ats)
if (ats)
flags |= DTE_FLAG_IOTLB;
  
+	if (ppr) {

+   struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
+
+   if (iommu_feature(iommu, FEATURE_EPHSUP))
+   pte_root |= 1ULL << DEV_ENTRY_PPR;
+   }
+
if (domain->flags & PD_IOMMUV2_MASK) {
u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
u64 glx  = domain->glx;
@@ -1897,9 +1905,9 @@ static void do_attach(struct iommu_dev_data *dev_data,
domain->dev_cnt += 1;
  
  	/* Update device table */

-   set_dte_entry(dev_data->devid, domain, ats);
+   set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2);
if (alias != dev_data->devid)
-   set_dte_entry(alias, domain, ats);
+   set_dte_entry(alias, domain, ats, dev_data->iommu_v2);
  
  	device_flush_dte(dev_data);

  }
@@ -2278,13 +2286,15 @@ static void update_device_table(struct 
protection_domain *domain)
struct iommu_dev_data *dev_data;
  
  	list_for_each_entry(dev_data, >dev_list, list) {

-   set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
+   set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled,
+ dev_data->iommu_v2);
  
  		if (dev_data->devid == dev_data->alias)

continue;
  
  		/* There is an alias, update device table entry for it */

-   set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled);
+   set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled,
+ dev_data->iommu_v2);
}
  }
  
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h

index f6b24c7d8b70..6a877ebd058b 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -98,6 +98,7 @@
  #define FEATURE_HE(1ULL<<8)
  #define FEATURE_PC(1ULL<<9)
  #define FEATURE_GAM_VAPIC (1ULL<<21)
+#define FEATURE_EPHSUP (1ULL<<50)
  
  #define FEATURE_PASID_SHIFT	32

  #define FEATURE_PASID_MASK(0x1fULL << FEATURE_PASID_SHIFT)
@@ -192,6 +193,7 @@
  /* macros and definitions for device table entries */
  #define DEV_ENTRY_VALID 0x00
  #define DEV_ENTRY_TRANSLATION   0x01
+#define DEV_ENTRY_PPR   0x34
  #define DEV_ENTRY_IR0x3d
  #define DEV_ENTRY_IW0x3e
  #define DEV_ENTRY_NO_PAGE_FAULT   0x62





[PATCH] iommu/amd - Set the device table entry PPR bit for IOMMU V2 devices

2017-12-20 Thread Gary R Hook
The AMD IOMMU specification Rev 3.00 (December 2016) introduces a
new Enhanced PPR Handling Support (EPHSup) bit in the MMIO register
offset 0030h (IOMMU Extended Feature Register).

When EPHSup=1, the IOMMU hardware requires the PPR bit of the
device table entry (DTE) to be set in order to support PPR for a
particular endpoint device.

Please see https://support.amd.com/TechDocs/48882_IOMMU.pdf for
this revision of the AMD IOMMU specification.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu.c   |   20 +++-
 drivers/iommu/amd_iommu_types.h |2 ++
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index cb78933ef53f..5f3da95ff6a0 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1818,7 +1818,8 @@ static bool dma_ops_domain(struct protection_domain 
*domain)
return domain->flags & PD_DMA_OPS_MASK;
 }
 
-static void set_dte_entry(u16 devid, struct protection_domain *domain, bool 
ats)
+static void set_dte_entry(u16 devid, struct protection_domain *domain,
+ bool ats, bool ppr)
 {
u64 pte_root = 0;
u64 flags = 0;
@@ -1835,6 +1836,13 @@ static void set_dte_entry(u16 devid, struct 
protection_domain *domain, bool ats)
if (ats)
flags |= DTE_FLAG_IOTLB;
 
+   if (ppr) {
+   struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
+
+   if (iommu_feature(iommu, FEATURE_EPHSUP))
+   pte_root |= 1ULL << DEV_ENTRY_PPR;
+   }
+
if (domain->flags & PD_IOMMUV2_MASK) {
u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
u64 glx  = domain->glx;
@@ -1897,9 +1905,9 @@ static void do_attach(struct iommu_dev_data *dev_data,
domain->dev_cnt += 1;
 
/* Update device table */
-   set_dte_entry(dev_data->devid, domain, ats);
+   set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2);
if (alias != dev_data->devid)
-   set_dte_entry(alias, domain, ats);
+   set_dte_entry(alias, domain, ats, dev_data->iommu_v2);
 
device_flush_dte(dev_data);
 }
@@ -2278,13 +2286,15 @@ static void update_device_table(struct 
protection_domain *domain)
struct iommu_dev_data *dev_data;
 
list_for_each_entry(dev_data, >dev_list, list) {
-   set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
+   set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled,
+ dev_data->iommu_v2);
 
if (dev_data->devid == dev_data->alias)
continue;
 
/* There is an alias, update device table entry for it */
-   set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled);
+   set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled,
+ dev_data->iommu_v2);
}
 }
 
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index f6b24c7d8b70..6a877ebd058b 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -98,6 +98,7 @@
 #define FEATURE_HE (1ULL<<8)
 #define FEATURE_PC (1ULL<<9)
 #define FEATURE_GAM_VAPIC  (1ULL<<21)
+#define FEATURE_EPHSUP (1ULL<<50)
 
 #define FEATURE_PASID_SHIFT32
 #define FEATURE_PASID_MASK (0x1fULL << FEATURE_PASID_SHIFT)
@@ -192,6 +193,7 @@
 /* macros and definitions for device table entries */
 #define DEV_ENTRY_VALID 0x00
 #define DEV_ENTRY_TRANSLATION   0x01
+#define DEV_ENTRY_PPR   0x34
 #define DEV_ENTRY_IR0x3d
 #define DEV_ENTRY_IW0x3e
 #define DEV_ENTRY_NO_PAGE_FAULT0x62



Re: [PATCH v2] hwrng: Clean up RNG list when last hwrng is unregistered

2017-12-19 Thread Gary R Hook

On 12/17/2017 03:49 AM, PrasannaKumar Muralidharan wrote:

On 17 December 2017 at 14:53, PrasannaKumar Muralidharan
<prasannatsmku...@gmail.com> wrote:

Hi Gary,

Some minor comments below.

On 16 December 2017 at 01:25, Gary R Hook <gary.h...@amd.com> wrote:


Commit 142a27f0a731 added support for a "best" RNG, and in doing so
introduced a hang from rmmod/modprobe -r when the last RNG on the list
was unloaded.


Nice catch. Thanks for fixing this.


When the hwrng list is depleted, return the global variables to their
original state and decrement all references to the object.

Fixes: 142a27f0a731 ("hwrng: core - Reset user selected rng by writing "" to 
rng_current")


Please cc the commit author (in this case its me) so that this patch
gets noticed easily.


D'oh! I did not do so on this version. My apologies.




Signed-off-by: Gary R Hook <gary.h...@amd.com>
---

Changes since v1: fix misspelled word in subject

  drivers/char/hw_random/core.c |4 
  1 file changed, 4 insertions(+)

diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 657b8770b6b9..91bb98c42a1c 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -306,6 +306,10 @@ static int enable_best_rng(void)
 ret = ((new_rng == current_rng) ? 0 : 
set_current_rng(new_rng));
 if (!ret)
 cur_rng_set_by_user = 0;
+   } else {
+   drop_current_rng();


When the hwrng list is empty just set current_rng = NULL instead of
calling drop_current_rng().


+   cur_rng_set_by_user = 0;
+   ret = 0;
 }

 return ret;



Regards,
PrasannaKumar


I am fine with the code as is.

Reviewed-by: PrasannaKumar Muralidharan <prasannatsmku...@gmail.com>

Regards,
PrasannaKumar





[PATCH v2] hwrng: Clean up RNG list when last hwrng is unregistered

2017-12-15 Thread Gary R Hook
Commit 142a27f0a731 added support for a "best" RNG, and in doing so
introduced a hang from rmmod/modprobe -r when the last RNG on the list
was unloaded.

When the hwrng list is depleted, return the global variables to their
original state and decrement all references to the object.

Fixes: 142a27f0a731 ("hwrng: core - Reset user selected rng by writing "" to 
rng_current")
Signed-off-by: Gary R Hook <gary.h...@amd.com>
---

Changes since v1: fix misspelled word in subject

 drivers/char/hw_random/core.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 657b8770b6b9..91bb98c42a1c 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -306,6 +306,10 @@ static int enable_best_rng(void)
ret = ((new_rng == current_rng) ? 0 : set_current_rng(new_rng));
if (!ret)
cur_rng_set_by_user = 0;
+   } else {
+   drop_current_rng();
+   cur_rng_set_by_user = 0;
+   ret = 0;
}
 
return ret;



[PATCH] hwrng: Clean up RNG list when last hwrng is unregisterd

2017-12-12 Thread Gary R Hook
Commit 142a27f0a731 added support for a "best" RNG, and in doing so
introduced a hang from rmmod/modprobe -r when the last RNG on the list
was unloaded.

When the hwrng list is depleted, return the global variables to their
original state and decrement all references to the object.

Fixes: 142a27f0a731 ("hwrng: core - Reset user selected rng by writing "" to 
rng_current")
Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/char/hw_random/core.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 657b8770b6b9..91bb98c42a1c 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -306,6 +306,10 @@ static int enable_best_rng(void)
ret = ((new_rng == current_rng) ? 0 : set_current_rng(new_rng));
if (!ret)
cur_rng_set_by_user = 0;
+   } else {
+   drop_current_rng();
+   cur_rng_set_by_user = 0;
+   ret = 0;
}
 
return ret;



Re: [Part2 PATCH v8 13/38] crypto: ccp: Add Secure Encrypted Virtualization (SEV) command support

2017-11-07 Thread Gary R Hook

On 11/06/2017 12:11 PM, Brijesh Singh wrote:

AMD's new Secure Encrypted Virtualization (SEV) feature allows the
memory contents of virtual machines to be transparently encrypted with a
key unique to the VM. The programming and management of the encryption
keys are handled by the AMD Secure Processor (AMD-SP) which exposes the
commands for these tasks. The complete spec is available at:

http://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf

Extend the AMD-SP driver to provide the following support:

  - an in-kernel API to communicate with the SEV firmware. The API can be
used by the hypervisor to create encryption context for a SEV guest.

  - a userspace IOCTL to manage the platform certificates.

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Improvements-by: Borislav Petkov <b...@suse.de>
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
  drivers/crypto/ccp/psp-dev.c | 344 +++
  drivers/crypto/ccp/psp-dev.h |  24 +++
  drivers/crypto/ccp/sp-dev.c  |   9 ++
  drivers/crypto/ccp/sp-dev.h  |   4 +
  include/linux/psp-sev.h  | 137 +
  5 files changed, 518 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index b5789f878560..9915a6c604a3 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -26,6 +26,12 @@
  #include "sp-dev.h"
  #include "psp-dev.h"
  
+#define DEVICE_NAME	"sev"

+
+static DEFINE_MUTEX(sev_cmd_mutex);
+static struct sev_misc_dev *misc_dev;
+static struct psp_device *psp_master;
+
  static struct psp_device *psp_alloc_struct(struct sp_device *sp)
  {
struct device *dev = sp->dev;
@@ -45,9 +51,285 @@ static struct psp_device *psp_alloc_struct(struct sp_device 
*sp)
  
  static irqreturn_t psp_irq_handler(int irq, void *data)

  {
+   struct psp_device *psp = data;
+   unsigned int status;
+   int reg;
+
+   /* Read the interrupt status: */
+   status = ioread32(psp->io_regs + PSP_P2CMSG_INTSTS);
+
+   /* Check if it is command completion: */
+   if (!(status & BIT(PSP_CMD_COMPLETE_REG)))
+   goto done;
+
+   /* Check if it is SEV command completion: */
+   reg = ioread32(psp->io_regs + PSP_CMDRESP);
+   if (reg & PSP_CMDRESP_RESP) {
+   psp->sev_int_rcvd = 1;
+   wake_up(>sev_int_queue);
+   }
+
+done:
+   /* Clear the interrupt status by writing the same value we read. */
+   iowrite32(status, psp->io_regs + PSP_P2CMSG_INTSTS);
+
return IRQ_HANDLED;
  }
  
+static void sev_wait_cmd_ioc(struct psp_device *psp, unsigned int *reg)

+{
+   psp->sev_int_rcvd = 0;
+
+   wait_event(psp->sev_int_queue, psp->sev_int_rcvd);
+   *reg = ioread32(psp->io_regs + PSP_CMDRESP);
+}
+
+static int sev_cmd_buffer_len(int cmd)
+{
+   switch (cmd) {
+   case SEV_CMD_INIT:  return sizeof(struct 
sev_data_init);
+   case SEV_CMD_PLATFORM_STATUS:   return sizeof(struct 
sev_user_data_status);
+   case SEV_CMD_PEK_CSR:   return sizeof(struct 
sev_data_pek_csr);
+   case SEV_CMD_PEK_CERT_IMPORT:   return sizeof(struct 
sev_data_pek_cert_import);
+   case SEV_CMD_PDH_CERT_EXPORT:   return sizeof(struct 
sev_data_pdh_cert_export);
+   case SEV_CMD_LAUNCH_START:  return sizeof(struct 
sev_data_launch_start);
+   case SEV_CMD_LAUNCH_UPDATE_DATA:return sizeof(struct 
sev_data_launch_update_data);
+   case SEV_CMD_LAUNCH_UPDATE_VMSA:return sizeof(struct 
sev_data_launch_update_vmsa);
+   case SEV_CMD_LAUNCH_FINISH: return sizeof(struct 
sev_data_launch_finish);
+   case SEV_CMD_LAUNCH_MEASURE:return sizeof(struct 
sev_data_launch_measure);
+   case SEV_CMD_ACTIVATE:  return sizeof(struct 
sev_data_activate);
+   case SEV_CMD_DEACTIVATE:return sizeof(struct 
sev_data_deactivate);
+   case SEV_CMD_DECOMMISSION:  return sizeof(struct 
sev_data_decommission);
+   case SEV_CMD_GUEST_STATUS:  return sizeof(struct 
sev_data_guest_status);
+   case SEV_CMD_DBG_DECRYPT:   return sizeof(struct 
sev_data_dbg);
+   case SEV_CMD_DBG_ENCRYPT:   return sizeof(struct 
sev_data_dbg);
+   case SEV_CMD_SEND_START:return sizeof(struct 
sev_data_send_start);
+   case SEV_CMD_SEND_UPDATE_DATA:  return sizeof(struct 
sev_data_send_update_data)

Re: [Part2 PATCH v8 12/38] crypto: ccp: Add Platform Security Processor (PSP) device support

2017-11-07 Thread Gary R Hook

On 11/06/2017 12:11 PM, Brijesh Singh wrote:

The Platform Security Processor (PSP) is part of the AMD Secure
Processor (AMD-SP) functionality. The PSP is a dedicated processor
that provides support for key management commands in Secure Encrypted
Virtualization (SEV) mode, along with software-based Trusted Execution
Environment (TEE) to enable third-party trusted applications.

Note that the key management functionality provided by the SEV firmware
can be used outside of the kvm-amd driver hence it doesn't need to
depend on CONFIG_KVM_AMD.

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Improvements-by: Borislav Petkov <b...@suse.de>
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>
Reviewed-by: Borislav Petkov <b...@suse.de>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
  drivers/crypto/ccp/Kconfig   |  11 +
  drivers/crypto/ccp/Makefile  |   1 +
  drivers/crypto/ccp/psp-dev.c | 105 +++
  drivers/crypto/ccp/psp-dev.h |  59 
  drivers/crypto/ccp/sp-dev.c  |  26 +++
  drivers/crypto/ccp/sp-dev.h  |  24 +-
  drivers/crypto/ccp/sp-pci.c  |  52 +
  7 files changed, 277 insertions(+), 1 deletion(-)
  create mode 100644 drivers/crypto/ccp/psp-dev.c
  create mode 100644 drivers/crypto/ccp/psp-dev.h

diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig
index 9c84f9838931..b9dfae47aefd 100644
--- a/drivers/crypto/ccp/Kconfig
+++ b/drivers/crypto/ccp/Kconfig
@@ -33,3 +33,14 @@ config CRYPTO_DEV_CCP_CRYPTO
  Support for using the cryptographic API with the AMD Cryptographic
  Coprocessor. This module supports offload of SHA and AES algorithms.
  If you choose 'M' here, this module will be called ccp_crypto.
+
+config CRYPTO_DEV_SP_PSP
+   bool "Platform Security Processor (PSP) device"
+   default y
+   depends on CRYPTO_DEV_CCP_DD && X86_64
+   help
+Provide support for the AMD Platform Security Processor (PSP).
+The PSP is a dedicated processor that provides support for key
+management commands in Secure Encrypted Virtualization (SEV) mode,
+along with software-based Trusted Execution Environment (TEE) to
+enable third-party trusted applications.
diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 57f8debfcfb3..008bae7e26ec 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -7,6 +7,7 @@ ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \
ccp-dmaengine.o \
ccp-debugfs.o
  ccp-$(CONFIG_PCI) += sp-pci.o
+ccp-$(CONFIG_CRYPTO_DEV_SP_PSP) += psp-dev.o
  
  obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o

  ccp-crypto-objs := ccp-crypto-main.o \
diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
new file mode 100644
index ..b5789f878560
--- /dev/null
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -0,0 +1,105 @@
+/*
+ * AMD Platform Security Processor (PSP) interface
+ *
+ * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Brijesh Singh <brijesh.si...@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "sp-dev.h"
+#include "psp-dev.h"
+
+static struct psp_device *psp_alloc_struct(struct sp_device *sp)
+{
+   struct device *dev = sp->dev;
+   struct psp_device *psp;
+
+   psp = devm_kzalloc(dev, sizeof(*psp), GFP_KERNEL);
+   if (!psp)
+   return NULL;
+
+   psp->dev = dev;
+   psp->sp = sp;
+
+   snprintf(psp->name, sizeof(psp->name), "psp-%u", sp->ord);
+
+   return psp;
+}
+
+static irqreturn_t psp_irq_handler(int irq, void *data)
+{
+   return IRQ_HANDLED;
+}
+
+int psp_dev_init(struct sp_device *sp)
+{
+   struct device *dev = sp->dev;
+   struct psp_device *psp;
+   int ret;
+
+   ret = -ENOMEM;
+   psp = psp_alloc_struct(sp);
+   if (!psp)
+   goto e_err;
+
+   sp->psp_data = psp;
+
+   psp->vdata = (struct psp_vdata *)sp->dev_vdata->psp_vdata;
+   if (!psp->vdata) {
+   ret = -ENODEV;
+   dev_err(dev, "missing driver data\n");
+   goto e_err;
+   }
+
+   psp->io_regs = sp->io_map + psp->vd

Re: [Part2 PATCH v6 15/38] crypto: ccp: Implement SEV_PLATFORM_STATUS ioctl command

2017-10-24 Thread Gary R Hook

On 10/19/2017 09:33 PM, Brijesh Singh wrote:

The SEV_PLATFORM_STATUS command can be used by the platform owner to
get the current status of the platform. The command is defined in
SEV spec section 5.5.

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Improvements-by: Borislav Petkov <b...@suse.de>
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
  drivers/crypto/ccp/psp-dev.c | 24 
  1 file changed, 24 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 99f3761206da..5c921b36bc23 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -174,6 +174,27 @@ static int sev_do_cmd(int cmd, void *data, int *psp_ret)
return ret;
  }
  
+static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp)

+{
+   struct sev_user_data_status *data;
+   int ret;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   ret = sev_do_cmd(SEV_CMD_PLATFORM_STATUS, data, >error);
+   if (ret)
+   goto e_free;
+
+   if (copy_to_user((void __user *)argp->data, data, sizeof(*data)))
+   ret = -EFAULT;
+
+e_free:
+   kfree(data);
+   return ret;
+}
+
  static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long 
arg)
  {
void __user *argp = (void __user *)arg;
@@ -194,6 +215,9 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
case SEV_FACTORY_RESET:
ret = sev_do_cmd(SEV_CMD_FACTORY_RESET, 0, );
break;
+   case SEV_PLATFORM_STATUS:
+   ret = sev_ioctl_do_platform_status();
+   break;
default:
ret = -EINVAL;
goto out;





Re: [Part2 PATCH v6.1 16/38] crypto: ccp: Implement SEV_PEK_GEN ioctl command

2017-10-24 Thread Gary R Hook

On 10/23/2017 04:55 PM, Brijesh Singh wrote:

The SEV_PEK_GEN command is used to generate a new Platform Endorsement
Key (PEK). The command is defined in SEV spec section 5.6.

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---

Changes since v6:
  * when sev_do_cmd() and sev_platform_shutdown() fails then propogate
the error status code from sev_do_cmd() because it can give us
much better reason for the failure.

  drivers/crypto/ccp/psp-dev.c | 31 +++
  1 file changed, 31 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index dd4bab143de9..18e2d8291997 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -195,6 +195,34 @@ static int sev_ioctl_do_platform_status(struct 
sev_issue_cmd *argp)
return ret;
  }
  
+static int sev_ioctl_do_pek_pdh_gen(int cmd, struct sev_issue_cmd *argp)

+{
+   int ret, err;
+
+   ret = sev_platform_init(NULL, >error);
+   if (ret)
+   return ret;
+
+   ret = sev_do_cmd(cmd, 0, >error);
+
+   if (sev_platform_shutdown()) {
+   /*
+* If both sev_do_cmd() and sev_platform_shutdown() commands
+* failed then propogate the error code from the sev_do_cmd()
+* because it contains a useful status code for the command
+* failure.
+*/
+   if (ret)
+   goto done;
+
+   argp->error = err;
+   ret = -EIO;
+   }
+
+done:
+   return ret;
+}
+
  static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long 
arg)
  {
void __user *argp = (void __user *)arg;
@@ -218,6 +246,9 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
case SEV_PLATFORM_STATUS:
ret = sev_ioctl_do_platform_status();
break;
+   case SEV_PEK_GEN:
+   ret = sev_ioctl_do_pek_pdh_gen(SEV_CMD_PEK_GEN, );
+   break;
default:
ret = -EINVAL;
goto out;





Re: [Part2 PATCH v6.1 19/38] crypto: ccp: Implement SEV_PEK_CERT_IMPORT ioctl command

2017-10-24 Thread Gary R Hook

On 10/23/2017 05:14 PM, Brijesh Singh wrote:

The SEV_PEK_CERT_IMPORT command can be used to import the signed PEK
certificate. The command is defined in SEV spec section 5.8.

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>



Acked-by: Gary R Hook <gary.h...@amd.com>




---

Changes since v6:
  * when sev_do_cmd() and sev_platform_shutdown() fails then propogate
the error status code from sev_do_cmd() because it can give us
much better reason for the failure.

  drivers/crypto/ccp/psp-dev.c | 92 
  include/linux/psp-sev.h  |  4 ++
  2 files changed, 96 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index aaf1c5cf821d..108fc06bcdb3 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -301,6 +301,95 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp)
return ret;
  }
  
+void *psp_copy_user_blob(u64 __user uaddr, u32 len)

+{
+   void *data;
+
+   if (!uaddr || !len)
+   return ERR_PTR(-EINVAL);
+
+   /* verify that blob length does not exceed our limit */
+   if (len > SEV_FW_BLOB_MAX_SIZE)
+   return ERR_PTR(-EINVAL);
+
+   data = kmalloc(len, GFP_KERNEL);
+   if (!data)
+   return ERR_PTR(-ENOMEM);
+
+   if (copy_from_user(data, (void __user *)(uintptr_t)uaddr, len))
+   goto e_free;
+
+   return data;
+
+e_free:
+   kfree(data);
+   return ERR_PTR(-EFAULT);
+}
+EXPORT_SYMBOL_GPL(psp_copy_user_blob);
+
+static int sev_ioctl_do_pek_cert_import(struct sev_issue_cmd *argp)
+{
+   struct sev_user_data_pek_cert_import input;
+   struct sev_data_pek_cert_import *data;
+   void *pek_blob, *oca_blob;
+   int ret, err;
+
+   if (copy_from_user(, (void __user *)argp->data, sizeof(input)))
+   return -EFAULT;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   /* copy PEK certificate blobs from userspace */
+   pek_blob = psp_copy_user_blob(input.pek_cert_address, 
input.pek_cert_len);
+   if (IS_ERR(pek_blob)) {
+   ret = PTR_ERR(pek_blob);
+   goto e_free;
+   }
+
+   data->pek_cert_address = __psp_pa(pek_blob);
+   data->pek_cert_len = input.pek_cert_len;
+
+   /* copy PEK certificate blobs from userspace */
+   oca_blob = psp_copy_user_blob(input.oca_cert_address, 
input.oca_cert_len);
+   if (IS_ERR(oca_blob)) {
+   ret = PTR_ERR(oca_blob);
+   goto e_free_pek;
+   }
+
+   data->oca_cert_address = __psp_pa(oca_blob);
+   data->oca_cert_len = input.oca_cert_len;
+
+   ret = sev_platform_init(NULL, >error);
+   if (ret)
+   goto e_free_oca;
+
+   ret = sev_do_cmd(SEV_CMD_PEK_CERT_IMPORT, data, >error);
+
+   if (sev_platform_shutdown()) {
+   /*
+* If both sev_do_cmd() and sev_platform_shutdown() commands
+* failed then propogate the error code from the sev_do_cmd()
+* because it contains a useful status code for the command
+* failure.
+*/
+   if (ret)
+   goto e_free_oca;
+
+   ret = -EIO;
+   argp->error = err;
+   }
+
+e_free_oca:
+   kfree(oca_blob);
+e_free_pek:
+   kfree(pek_blob);
+e_free:
+   kfree(data);
+   return ret;
+}
+
  static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long 
arg)
  {
void __user *argp = (void __user *)arg;
@@ -333,6 +422,9 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
case SEV_PEK_CSR:
ret = sev_ioctl_do_pek_csr();
break;
+   case SEV_PEK_CERT_IMPORT:
+   ret = sev_ioctl_do_pek_cert_import();
+   break;
default:
ret = -EINVAL;
goto out;
diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
index eac850a97610..d535153ca82d 100644
--- a/include/linux/psp-sev.h
+++ b/include/linux/psp-sev.h
@@ -620,6 +620,8 @@ int sev_guest_df_flush(int *error);
   */
  int sev_guest_decommission(struct sev_data_decommission *data, int *error);
  
+void *psp_copy_user_blob(u64 __user uaddr, u32 len);

+
  #else /* !CONFIG_CRYPTO_DEV_SP_PSP */
  
  static inline int

@@ -648,6 +650,8 @@ sev_issue_cmd_external_user(struct file *filep,
return -ENODEV;
  }
  
+static inline void *p

Re: [Part2 PATCH v6.1 20/38] crypto: ccp: Implement SEV_PDH_CERT_EXPORT ioctl command

2017-10-24 Thread Gary R Hook

On 10/23/2017 05:19 PM, Brijesh Singh wrote:

The SEV_PDH_CERT_EXPORT command can be used to export the PDH and its
certificate chain. The command is defined in SEV spec section 5.10.

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>



Acked-by: Gary R Hook <gary.h...@amd.com>




---

Changes since v6:
  * when sev_do_cmd() and sev_platform_shutdown() fails then propogate
the error status code from sev_do_cmd() because it can give us
much better reason for the failure.

  drivers/crypto/ccp/psp-dev.c | 110 +++
  1 file changed, 110 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 108fc06bcdb3..b9f594cb10c1 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -390,6 +390,113 @@ static int sev_ioctl_do_pek_cert_import(struct 
sev_issue_cmd *argp)
return ret;
  }
  
+static int sev_ioctl_do_pdh_cert_export(struct sev_issue_cmd *argp)

+{
+   struct sev_user_data_pdh_cert_export input;
+   void *pdh_blob = NULL, *cert_blob = NULL;
+   struct sev_data_pdh_cert_export *data;
+   int ret, err;
+
+   if (copy_from_user(, (void __user *)argp->data, sizeof(input)))
+   return -EFAULT;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   /* Userspace wants to query the certificate length */
+   if (!input.pdh_cert_address || !input.pdh_cert_len ||
+   !input.cert_chain_address || !input.cert_chain_address)
+   goto cmd;
+
+   /* allocate a physically contiguous buffer to store the PDH blob */
+   if (!access_ok(VERIFY_WRITE, input.pdh_cert_address, 
input.pdh_cert_len) ||
+   (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE)) {
+   ret = -EFAULT;
+   goto e_free;
+   }
+
+   pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL);
+   if (!pdh_blob) {
+   ret = -ENOMEM;
+   goto e_free;
+   }
+
+   data->pdh_cert_address = __psp_pa(pdh_blob);
+   data->pdh_cert_len = input.pdh_cert_len;
+
+   /* allocate a physically contiguous buffer to store the cert chain blob 
*/
+   if (!access_ok(VERIFY_WRITE, input.cert_chain_address, 
input.cert_chain_len) ||
+   (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE)) {
+   ret = -EFAULT;
+   goto e_free_pdh;
+   }
+
+   cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL);
+   if (!cert_blob) {
+   ret = -ENOMEM;
+   goto e_free_pdh;
+   }
+
+   data->cert_chain_address = __psp_pa(cert_blob);
+   data->cert_chain_len = input.cert_chain_len;
+
+cmd:
+   ret = sev_platform_init(NULL, >error);
+   if (ret)
+   goto e_free_cert;
+
+   ret = sev_do_cmd(SEV_CMD_PDH_CERT_EXPORT, data, >error);
+
+   /*
+* If we query the length, FW responded with expected data
+*/
+   input.cert_chain_len = data->cert_chain_len;
+   input.pdh_cert_len = data->pdh_cert_len;
+
+   if (sev_platform_shutdown()) {
+   /*
+* If both sev_do_cmd() and sev_platform_shutdown() commands
+* failed then propogate the error code from the sev_do_cmd()
+* because it contains a useful status code for the command
+* failure.
+*/
+   if (ret)
+   goto e_free_cert;
+
+   ret = -EIO;
+   argp->error = err;
+   goto e_free_cert;
+   }
+
+   if (copy_to_user((void __user *)argp->data, , sizeof(input))) {
+   ret = -EFAULT;
+   goto e_free_cert;
+   }
+
+   if (pdh_blob) {
+   if (copy_to_user((void __user *)input.pdh_cert_address,
+pdh_blob, input.pdh_cert_len)) {
+   ret = -EFAULT;
+   goto e_free_cert;
+   }
+   }
+
+   if (cert_blob) {
+   if (copy_to_user((void __user *)input.cert_chain_address,
+cert_blob, input.cert_chain_len))
+   ret = -EFAULT;
+   }
+
+e_free_cert:
+   kfree(cert_blob);
+e_free_pdh:
+   kfree(pdh_blob);
+e_free:
+   kfree(data);
+   return ret;
+}
+
  static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long 
arg)
  {
void __user *argp = (void __user *)arg;
@@ -425,6 +532,9 @@ static long sev_ioctl(struct file *fi

Re: [Part2 PATCH v6.1 18/38] crypto: ccp: Implement SEV_PEK_CSR ioctl command

2017-10-24 Thread Gary R Hook

On 10/23/2017 05:10 PM, Brijesh Singh wrote:

The SEV_PEK_CSR command can be used to generate a PEK certificate
signing request. The command is defined in SEV spec section 5.7.

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>
---



Acked-by: Gary R Hook <gary.h...@amd.com>





Changes since v6:
  * when sev_do_cmd() and sev_platform_shutdown() fails then propogate
the error status code from sev_do_cmd() because it can give us
much better reason for the failure.

  drivers/crypto/ccp/psp-dev.c | 81 
  1 file changed, 81 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 3672435150cf..aaf1c5cf821d 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -223,6 +223,84 @@ static int sev_ioctl_do_pek_pdh_gen(int cmd, struct 
sev_issue_cmd *argp)
return ret;
  }
  
+static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp)

+{
+   struct sev_user_data_pek_csr input;
+   struct sev_data_pek_csr *data;
+   void *blob = NULL;
+   int ret, err;
+
+   if (copy_from_user(, (void __user *)argp->data, sizeof(input)))
+   return -EFAULT;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   /* userspace wants to query CSR length */
+   if (!input.address || !input.length)
+   goto cmd;
+
+   /* allocate a physically contiguous buffer to store the CSR blob */
+   if (!access_ok(VERIFY_WRITE, input.address, input.length) ||
+   input.length > SEV_FW_BLOB_MAX_SIZE) {
+   ret = -EFAULT;
+   goto e_free;
+   }
+
+   blob = kmalloc(input.length, GFP_KERNEL);
+   if (!blob) {
+   ret = -ENOMEM;
+   goto e_free;
+   }
+
+   data->address = __psp_pa(blob);
+   data->len = input.length;
+
+cmd:
+   ret = sev_platform_init(NULL, >error);
+   if (ret)
+   goto e_free_blob;
+
+   ret = sev_do_cmd(SEV_CMD_PEK_CSR, data, >error);
+
+   /*
+* If we query the CSR length, FW responded with expected data
+*/
+   input.length = data->len;
+
+   if (sev_platform_shutdown()) {
+   /*
+* If both sev_do_cmd() and sev_platform_shutdown() commands
+* failed then propogate the error code from the sev_do_cmd()
+* because it contains a useful status code for the command
+* failure.
+*/
+   if (ret)
+   goto e_free_blob;
+
+   ret = -EIO;
+   argp->error = err;
+   goto e_free_blob;
+   }
+
+   if (copy_to_user((void __user *)argp->data, , sizeof(input))) {
+   ret = -EFAULT;
+   goto e_free_blob;
+   }
+
+   if (blob) {
+   if (copy_to_user((void __user *)input.address, blob, 
input.length))
+   ret = -EFAULT;
+   }
+
+e_free_blob:
+   kfree(blob);
+e_free:
+   kfree(data);
+   return ret;
+}
+
  static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long 
arg)
  {
void __user *argp = (void __user *)arg;
@@ -252,6 +330,9 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
case SEV_PDH_GEN:
ret = sev_ioctl_do_pek_pdh_gen(SEV_CMD_PDH_GEN, );
break;
+   case SEV_PEK_CSR:
+   ret = sev_ioctl_do_pek_csr();
+   break;
default:
ret = -EINVAL;
goto out;





Re: [Part2 PATCH v6 14/38] crypto: ccp: Implement SEV_FACTORY_RESET ioctl command

2017-10-24 Thread Gary R Hook

On 10/19/2017 09:33 PM, Brijesh Singh wrote:

The SEV_FACTORY_RESET command can be used by the platform owner to
reset the non-volatile SEV related data. The command is defined in
SEV spec section 5.4

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Improvements-by: Borislav Petkov <b...@suse.de>
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
  drivers/crypto/ccp/psp-dev.c | 28 +++-
  1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index e9966d5fc6c4..99f3761206da 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -176,7 +176,33 @@ static int sev_do_cmd(int cmd, void *data, int *psp_ret)
  
  static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)

  {
-   return -ENOTTY;
+   void __user *argp = (void __user *)arg;
+   struct sev_issue_cmd input;
+   int ret = -EFAULT;
+
+   if (ioctl != SEV_ISSUE_CMD)
+   return -EINVAL;
+
+   if (copy_from_user(, argp, sizeof(struct sev_issue_cmd)))
+   return -EFAULT;
+
+   if (input.cmd > SEV_MAX)
+   return -EINVAL;
+
+   switch (input.cmd) {
+
+   case SEV_FACTORY_RESET:
+   ret = sev_do_cmd(SEV_CMD_FACTORY_RESET, 0, );
+   break;
+   default:
+   ret = -EINVAL;
+   goto out;
+   }
+
+   if (copy_to_user(argp, , sizeof(struct sev_issue_cmd)))
+   ret = -EFAULT;
+out:
+   return ret;
  }
  
  static const struct file_operations sev_fops = {






Re: [Part2 PATCH v6 17/38] crypto: ccp: Implement SEV_PDH_GEN ioctl command

2017-10-24 Thread Gary R Hook

On 10/19/2017 09:33 PM, Brijesh Singh wrote:

The SEV_PDH_GEN command is used to re-generate the Platform
Diffie-Hellman (PDH) key. The command is defined in SEV spec section
5.6.

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
  drivers/crypto/ccp/psp-dev.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 1d7212da25a5..d9771d104eea 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -239,6 +239,9 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
case SEV_PEK_GEN:
ret = sev_ioctl_do_pek_pdh_gen(SEV_CMD_PEK_GEN, );
break;
+   case SEV_PDH_GEN:
+   ret = sev_ioctl_do_pek_pdh_gen(SEV_CMD_PDH_GEN, );
+   break;
default:
ret = -EINVAL;
goto out;





Re: [Part2 PATCH v6 12/38] crypto: ccp: Add Platform Security Processor (PSP) device support

2017-10-24 Thread Gary R Hook

On 10/19/2017 09:33 PM, Brijesh Singh wrote:

The Platform Security Processor (PSP) is part of the AMD Secure
Processor (AMD-SP) functionality. The PSP is a dedicated processor
that provides support for key management commands in Secure Encrypted
Virtualization (SEV) mode, along with software-based Trusted Execution
Environment (TEE) to enable third-party trusted applications.

Note that the key management functionality provided by the SEV firmware
can be used outside of the kvm-amd driver hence it doesn't need to
depend on CONFIG_KVM_AMD.

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Improvements-by: Borislav Petkov <b...@suse.de>
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>
Reviewed-by: Borislav Petkov <b...@suse.de>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
  drivers/crypto/ccp/Kconfig   |  11 +
  drivers/crypto/ccp/Makefile  |   1 +
  drivers/crypto/ccp/psp-dev.c | 105 +++
  drivers/crypto/ccp/psp-dev.h |  59 
  drivers/crypto/ccp/sp-dev.c  |  26 +++
  drivers/crypto/ccp/sp-dev.h  |  24 +-
  drivers/crypto/ccp/sp-pci.c  |  52 +
  7 files changed, 277 insertions(+), 1 deletion(-)
  create mode 100644 drivers/crypto/ccp/psp-dev.c
  create mode 100644 drivers/crypto/ccp/psp-dev.h

diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig
index 9c84f9838931..b9dfae47aefd 100644
--- a/drivers/crypto/ccp/Kconfig
+++ b/drivers/crypto/ccp/Kconfig
@@ -33,3 +33,14 @@ config CRYPTO_DEV_CCP_CRYPTO
  Support for using the cryptographic API with the AMD Cryptographic
  Coprocessor. This module supports offload of SHA and AES algorithms.
  If you choose 'M' here, this module will be called ccp_crypto.
+
+config CRYPTO_DEV_SP_PSP
+   bool "Platform Security Processor (PSP) device"
+   default y
+   depends on CRYPTO_DEV_CCP_DD && X86_64
+   help
+Provide support for the AMD Platform Security Processor (PSP).
+The PSP is a dedicated processor that provides support for key
+management commands in Secure Encrypted Virtualization (SEV) mode,
+along with software-based Trusted Execution Environment (TEE) to
+enable third-party trusted applications.
diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 57f8debfcfb3..008bae7e26ec 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -7,6 +7,7 @@ ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \
ccp-dmaengine.o \
ccp-debugfs.o
  ccp-$(CONFIG_PCI) += sp-pci.o
+ccp-$(CONFIG_CRYPTO_DEV_SP_PSP) += psp-dev.o
  
  obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o

  ccp-crypto-objs := ccp-crypto-main.o \
diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
new file mode 100644
index ..b5789f878560
--- /dev/null
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -0,0 +1,105 @@
+/*
+ * AMD Platform Security Processor (PSP) interface
+ *
+ * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Brijesh Singh <brijesh.si...@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "sp-dev.h"
+#include "psp-dev.h"
+
+static struct psp_device *psp_alloc_struct(struct sp_device *sp)
+{
+   struct device *dev = sp->dev;
+   struct psp_device *psp;
+
+   psp = devm_kzalloc(dev, sizeof(*psp), GFP_KERNEL);
+   if (!psp)
+   return NULL;
+
+   psp->dev = dev;
+   psp->sp = sp;
+
+   snprintf(psp->name, sizeof(psp->name), "psp-%u", sp->ord);
+
+   return psp;
+}
+
+static irqreturn_t psp_irq_handler(int irq, void *data)
+{
+   return IRQ_HANDLED;
+}
+
+int psp_dev_init(struct sp_device *sp)
+{
+   struct device *dev = sp->dev;
+   struct psp_device *psp;
+   int ret;
+
+   ret = -ENOMEM;
+   psp = psp_alloc_struct(sp);
+   if (!psp)
+   goto e_err;
+
+   sp->psp_data = psp;
+
+   psp->vdata = (struct psp_vdata *)sp->dev_vdata->psp_vdata;
+   if (!psp->vdata) {
+   ret = -ENODEV;
+   dev_err(dev, "missing driver data\n");
+   goto e_err;
+   }
+
+   psp->io_regs = sp->io_map + psp->vd

Re: [Part2 PATCH v6 09/38] crypto: ccp: Build the AMD secure processor driver only with AMD CPU support

2017-10-24 Thread Gary R Hook

On 10/19/2017 09:33 PM, Brijesh Singh wrote:

From: Borislav Petkov <b...@suse.de>

This is AMD-specific hardware so present it in Kconfig only when AMD
CPU support is enabled or on ARM64 where it is also used.

Signed-off-by: Borislav Petkov <b...@suse.de>
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>
Cc: Brijesh Singh <brijesh.si...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: "David S. Miller" <da...@davemloft.net>
Cc: linux-crypto@vger.kernel.org


Reviewed-by: Gary R Hook <gary.h...@amd.com>


---
  drivers/crypto/ccp/Kconfig | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig
index 6d626606b9c5..9c84f9838931 100644
--- a/drivers/crypto/ccp/Kconfig
+++ b/drivers/crypto/ccp/Kconfig
@@ -1,5 +1,6 @@
  config CRYPTO_DEV_CCP_DD
tristate "Secure Processor device driver"
+   depends on CPU_SUP_AMD || ARM64
default m
help
  Provides AMD Secure Processor device driver.





Re: [Part2 PATCH v6 11/38] crypto: ccp: Define SEV key management command id

2017-10-24 Thread Gary R Hook

On 10/19/2017 09:33 PM, Brijesh Singh wrote:

Define Secure Encrypted Virtualization (SEV) key management command id
and structure. The command definition is available in SEV KM [1] spec
0.14.

[1] http://support.amd.com/TechDocs/55766_SEV-KM API_Specification.pdf

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Improvements-by: Borislav Petkov <b...@suse.de>
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>
Reviewed-by: Borislav Petkov <b...@suse.de>


Acked-by: Gary R Hook <gary.h...@amd.com>



---
  include/linux/psp-sev.h | 494 
  1 file changed, 494 insertions(+)
  create mode 100644 include/linux/psp-sev.h

diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
new file mode 100644
index ..15bda519538e
--- /dev/null
+++ b/include/linux/psp-sev.h
@@ -0,0 +1,494 @@
+/*
+ * AMD Secure Encrypted Virtualization (SEV) driver interface
+ *
+ * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Brijesh Singh <brijesh.si...@amd.com>
+ *
+ * SEV spec 0.14 is available at:
+ * http://support.amd.com/TechDocs/55766_SEV-KM API_Specification.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PSP_SEV_H__
+#define __PSP_SEV_H__
+
+#include 
+
+#ifdef CONFIG_X86
+#include 
+
+#define __psp_pa(x)__sme_pa(x)
+#else
+#define __psp_pa(x)__pa(x)
+#endif
+
+#define SEV_FW_BLOB_MAX_SIZE   0x4000  /* 16KB */
+
+/**
+ * SEV platform state
+ */
+enum sev_state {
+   SEV_STATE_UNINIT= 0x0,
+   SEV_STATE_INIT  = 0x1,
+   SEV_STATE_WORKING   = 0x2,
+
+   SEV_STATE_MAX
+};
+
+/**
+ * SEV platform and guest management commands
+ */
+enum sev_cmd {
+   /* platform commands */
+   SEV_CMD_INIT= 0x001,
+   SEV_CMD_SHUTDOWN= 0x002,
+   SEV_CMD_FACTORY_RESET   = 0x003,
+   SEV_CMD_PLATFORM_STATUS = 0x004,
+   SEV_CMD_PEK_GEN = 0x005,
+   SEV_CMD_PEK_CSR = 0x006,
+   SEV_CMD_PEK_CERT_IMPORT = 0x007,
+   SEV_CMD_PDH_CERT_EXPORT = 0x008,
+   SEV_CMD_PDH_GEN = 0x009,
+   SEV_CMD_DF_FLUSH= 0x00A,
+
+   /* Guest commands */
+   SEV_CMD_DECOMMISSION= 0x020,
+   SEV_CMD_ACTIVATE= 0x021,
+   SEV_CMD_DEACTIVATE  = 0x022,
+   SEV_CMD_GUEST_STATUS= 0x023,
+
+   /* Guest launch commands */
+   SEV_CMD_LAUNCH_START= 0x030,
+   SEV_CMD_LAUNCH_UPDATE_DATA  = 0x031,
+   SEV_CMD_LAUNCH_UPDATE_VMSA  = 0x032,
+   SEV_CMD_LAUNCH_MEASURE  = 0x033,
+   SEV_CMD_LAUNCH_UPDATE_SECRET= 0x034,
+   SEV_CMD_LAUNCH_FINISH   = 0x035,
+
+   /* Guest migration commands (outgoing) */
+   SEV_CMD_SEND_START  = 0x040,
+   SEV_CMD_SEND_UPDATE_DATA= 0x041,
+   SEV_CMD_SEND_UPDATE_VMSA= 0x042,
+   SEV_CMD_SEND_FINISH = 0x043,
+
+   /* Guest migration commands (incoming) */
+   SEV_CMD_RECEIVE_START   = 0x050,
+   SEV_CMD_RECEIVE_UPDATE_DATA = 0x051,
+   SEV_CMD_RECEIVE_UPDATE_VMSA = 0x052,
+   SEV_CMD_RECEIVE_FINISH  = 0x053,
+
+   /* Guest debug commands */
+   SEV_CMD_DBG_DECRYPT = 0x060,
+   SEV_CMD_DBG_ENCRYPT = 0x061,
+
+   SEV_CMD_MAX,
+};
+
+/**
+ * status code returned by the commands
+ */
+enum psp_ret_code {
+   SEV_RET_SUCCESS = 0,
+   SEV_RET_INVALID_PLATFORM_STATE,
+   SEV_RET_INVALID_GUEST_STATE,
+   SEV_RET_INAVLID_CONFIG,
+   SEV_RET_INVALID_len,
+   SEV_RET_ALREADY_OWNED,
+   SEV_RET_INVALID_CERTIFICATE,
+   SEV_RET_POLICY_FAILURE,
+   SEV_RET_INACTIVE,
+   SEV_RET_INVALID_ADDRESS,
+   SEV_RET_BAD_SIGNATURE,
+   SEV_RET_BAD_MEASUREMENT,
+   SEV_RET_ASID_OWNED,
+   SEV_RET_INVALID_ASID,
+   SEV_RET_WBINVD_REQUIRED,
+   SEV_RET_DFFLUSH_REQUIRED,
+   SEV_RET_INVALID_GUEST,
+   SEV_RET_INVALID_COMMAND,
+   SEV_RET_ACTIVE,
+   SEV_RET_HWSEV_RET_PLATFORM,
+   SEV_RET_HWSEV_RET_UNSAFE,
+   SEV_RET_UNSUPPORTED,
+   SEV_RET_MAX,
+};
+
+/**
+ * struct sev_data_init - INIT command parameters
+ *
+ * @flags: processing flags
+ * @tmr_address: system physical address used for SEV-ES
+ * @tmr_len: len of tmr_address
+ */
+struct sev_data_

Re: [Part2 PATCH v6 10/38] crypto: ccp: Define SEV userspace ioctl and command id

2017-10-24 Thread Gary R Hook

On 10/19/2017 09:33 PM, Brijesh Singh wrote:

Add a include file which defines the ioctl and command id used for
issuing SEV platform management specific commands.

Cc: Paolo Bonzini <pbonz...@redhat.com>
Cc: "Radim Krčmář" <rkrc...@redhat.com>
Cc: Borislav Petkov <b...@suse.de>
Cc: Herbert Xu <herb...@gondor.apana.org.au>
Cc: Gary Hook <gary.h...@amd.com>
Cc: Tom Lendacky <thomas.lenda...@amd.com>
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Improvements-by: Borislav Petkov <b...@suse.de>
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>
Reviewed-by: Borislav Petkov <b...@suse.de>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
  include/uapi/linux/psp-sev.h | 113 +++
  1 file changed, 113 insertions(+)
  create mode 100644 include/uapi/linux/psp-sev.h

diff --git a/include/uapi/linux/psp-sev.h b/include/uapi/linux/psp-sev.h
new file mode 100644
index ..1dd98ba4ff22
--- /dev/null
+++ b/include/uapi/linux/psp-sev.h
@@ -0,0 +1,113 @@
+/*
+ * Userspace interface for AMD Secure Encrypted Virtualization (SEV)
+ * platform management commands.
+ *
+ * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Brijesh Singh <brijesh.si...@amd.com>
+ *
+ * SEV spec 0.14 is available at:
+ * http://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PSP_SEV_USER_H__
+#define __PSP_SEV_USER_H__
+
+#include 
+
+/**
+ * SEV platform commands
+ */
+enum {
+   SEV_FACTORY_RESET = 0,
+   SEV_PLATFORM_STATUS,
+   SEV_PEK_GEN,
+   SEV_PEK_CSR,
+   SEV_PDH_GEN,
+   SEV_PDH_CERT_EXPORT,
+   SEV_PEK_CERT_IMPORT,
+
+   SEV_MAX,
+};
+
+/**
+ * struct sev_user_data_status - PLATFORM_STATUS command parameters
+ *
+ * @major: major API version
+ * @minor: minor API version
+ * @state: platform state
+ * @flags: platform config flags
+ * @build: firmware build id for API version
+ * @guest_count: number of active guests
+ */
+struct sev_user_data_status {
+   __u8 api_major; /* Out */
+   __u8 api_minor; /* Out */
+   __u8 state; /* Out */
+   __u32 flags;/* Out */
+   __u8 build; /* Out */
+   __u32 guest_count;  /* Out */
+} __packed;
+
+/**
+ * struct sev_user_data_pek_csr - PEK_CSR command parameters
+ *
+ * @address: PEK certificate chain
+ * @length: length of certificate
+ */
+struct sev_user_data_pek_csr {
+   __u64 address;  /* In */
+   __u32 length;   /* In/Out */
+} __packed;
+
+/**
+ * struct sev_user_data_cert_import - PEK_CERT_IMPORT command parameters
+ *
+ * @pek_address: PEK certificate chain
+ * @pek_len: length of PEK certificate
+ * @oca_address: OCA certificate chain
+ * @oca_len: length of OCA certificate
+ */
+struct sev_user_data_pek_cert_import {
+   __u64 pek_cert_address; /* In */
+   __u32 pek_cert_len; /* In */
+   __u64 oca_cert_address; /* In */
+   __u32 oca_cert_len; /* In */
+} __packed;
+
+/**
+ * struct sev_user_data_pdh_cert_export - PDH_CERT_EXPORT command parameters
+ *
+ * @pdh_address: PDH certificate address
+ * @pdh_len: length of PDH certificate
+ * @cert_chain_address: PDH certificate chain
+ * @cert_chain_len: length of PDH certificate chain
+ */
+struct sev_user_data_pdh_cert_export {
+   __u64 pdh_cert_address; /* In */
+   __u32 pdh_cert_len; /* In/Out */
+   __u64 cert_chain_address;   /* In */
+   __u32 cert_chain_len;   /* In/Out */
+} __packed;
+
+/**
+ * struct sev_issue_cmd - SEV ioctl parameters
+ *
+ * @cmd: SEV commands to execute
+ * @opaque: pointer to the command structure
+ * @error: SEV FW return code on failure
+ */
+struct sev_issue_cmd {
+   __u32 cmd;  /* In */
+   __u64 data; /* In */
+   __u32 error;/* Out */
+} __packed;
+
+#define SEV_IOC_TYPE   'S'
+#define SEV_ISSUE_CMD  _IOWR(SEV_IOC_TYPE, 0x0, struct sev_issue_cmd)
+
+#endif /* __PSP_USER_SEV_H */





Re: [PATCH] crypto: ccp: remove unused variable qim

2017-10-17 Thread Gary R Hook

On 10/12/2017 11:55 AM, Colin King wrote:

From: Colin Ian King <colin.k...@canonical.com>

Variable qim is assigned but never read, it is redundant and can
be removed.

Cleans up clang warning: Value stored to 'qim' is never read

Fixes: 4b394a232df7 ("crypto: ccp - Let a v5 CCP provide the same function as 
v3")
Signed-off-by: Colin Ian King <colin.k...@canonical.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
 drivers/crypto/ccp/ccp-dev-v5.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c
index 65604fc65e8f..44a4d2779b15 100644
--- a/drivers/crypto/ccp/ccp-dev-v5.c
+++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -788,13 +788,12 @@ static int ccp5_init(struct ccp_device *ccp)
struct ccp_cmd_queue *cmd_q;
struct dma_pool *dma_pool;
char dma_pool_name[MAX_DMAPOOL_NAME_LEN];
-   unsigned int qmr, qim, i;
+   unsigned int qmr, i;
u64 status;
u32 status_lo, status_hi;
int ret;

/* Find available queues */
-   qim = 0;
qmr = ioread32(ccp->io_regs + Q_MASK_REG);
for (i = 0; i < MAX_HW_QUEUES; i++) {




Re: [RFC Part2 PATCH v3 02/26] crypto: ccp: Add Platform Security Processor (PSP) device support

2017-09-07 Thread Gary R Hook

On 09/07/2017 05:19 PM, Brijesh Singh wrote:

Hi Boris,

On 09/07/2017 09:27 AM, Borislav Petkov wrote:

...



The commit message above reads better to me as the help text than what
you have here.

Also, in order to make it easier for the user, I think we'll need a
CONFIG_AMD_MEM_ENCRYPT_SEV or so and make that depend on CONFIG_KVM_AMD,
this above and all the other pieces that are needed. Just so that when
the user builds such a kernel, all is enabled and not her having to go
look for what else is needed.

And then put the sev code behind that config option. Depending on how
ugly it gets...



I will add more detail in the help text. I will look into adding some
depends.

...


+
+void psp_add_device(struct psp_device *psp)


That function is needlessly global and should be static, AFAICT.

Better yet, it is called only once and its body is trivial so you can
completely get rid of it and meld it into the callsite.



Agreed, will do.

.


+
+static struct psp_device *psp_alloc_struct(struct sp_device *sp)


"psp_alloc()" is enough I guess.



I was trying to adhere to the existing ccp-dev.c function naming
conversion.


I would prefer that we not shorten this. The prior incarnation,
ccp_alloc_struct(), has/had been around for a while. And there are a 
number of
similarly named allocation functions in the driver that we like to keep 
sorted.

If anything, it should be more explanatory, IMO.







static.

Please audit all your functions in the psp pile and make them static if
not needed outside of their compilation unit.



Will do.


+{
+unsigned int status;
+irqreturn_t ret = IRQ_HANDLED;
+struct psp_device *psp = data;


Please sort function local variables declaration in a reverse christmas
tree order:

 longest_variable_name;
 shorter_var_name;
 even_shorter;
 i;



Got it, will do



+
+/* read the interrupt status */
+status = ioread32(psp->io_regs + PSP_P2CMSG_INTSTS);
+
+/* invoke subdevice interrupt handlers */
+if (status) {
+if (psp->sev_irq_handler)
+ret = psp->sev_irq_handler(irq, psp->sev_irq_data);
+if (psp->tee_irq_handler)
+ret = psp->tee_irq_handler(irq, psp->tee_irq_data);
+}
+
+/* clear the interrupt status */
+iowrite32(status, psp->io_regs + PSP_P2CMSG_INTSTS);


We're clearing the status by writing the same value back?!? Shouldn't
that be:

iowrite32(0, psp->io_regs + PSP_P2CMSG_INTSTS);



Actually the SW should write "1" to clear the bit. To make it clear, I
can use value 1 and add comment.




Below I see

iowrite32(0x, psp->io_regs + PSP_P2CMSG_INTSTS);

which is supposed to clear IRQs. Btw, you can write that:

iowrite32(-1, psp->io_regs + PSP_P2CMSG_INTSTS);



Sure, I will do that

...

...


+
+sp_set_psp_master(sp);


So this function is called only once and declared somewhere else. You
could simply do here:

 if (sp->set_psp_master_device)
 sp->set_psp_master_device(sp);

and get rid of one more global function.



Sure I can do that.




+/* Enable interrupt */
+dev_dbg(dev, "Enabling interrupts ...\n");
+iowrite32(7, psp->io_regs + PSP_P2CMSG_INTEN);


Uh, a magic "7"! Exciting!

I wonder what that means and whether it could be a define with an
explanatory name instead. Ditto for the other values...




I will try to define some macro instead of hard coded values.




+
+int psp_dev_resume(struct sp_device *sp)
+{
+return 0;
+}
+
+int psp_dev_suspend(struct sp_device *sp, pm_message_t state)
+{
+return 0;
+}


Those last two are completely useless. Delete them pls.



We don't have any PM support, I agree will delete it.

...


+int psp_request_sev_irq(struct psp_device *psp, irq_handler_t handler,
+void *data)
+{
+psp->sev_irq_data = data;
+psp->sev_irq_handler = handler;
+
+return 0;
+}
+
+int psp_free_sev_irq(struct psp_device *psp, void *data)
+{
+if (psp->sev_irq_handler) {
+psp->sev_irq_data = NULL;
+psp->sev_irq_handler = NULL;
+}
+
+return 0;
+}


Both void. Please do not return values from functions which are simply
void functions by design.



thanks, will fix it.

...


+int psp_request_sev_irq(struct psp_device *psp, irq_handler_t handler,
+void *data);
+int psp_free_sev_irq(struct psp_device *psp, void *data);
+
+int psp_request_tee_irq(struct psp_device *psp, irq_handler_t handler,
+void *data);


Let them stick out.


okay

...




+int psp_free_tee_irq(struct psp_device *psp, void *data);
+
+struct psp_device *psp_get_master_device(void);
+
+extern const struct psp_vdata psp_entry;
+
+#endif /* __PSP_DEV_H */
diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c


So this file is called sp-dev and the other psp-dev. Confusing.

And in general, why isn't the whole thing a single psp-dev and you can
save yourself all the registering blabla and have a single driver for
the whole PSP 

[PATCH] crypto:ccp - invoke the DMA callback in a standard way

2017-09-05 Thread Gary R Hook
From: amd <a...@sosxen2.amd.com>

Use the provided mechanism in dmaengine.h to invoke the
completion callback.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-dmaengine.c |4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-dmaengine.c 
b/drivers/crypto/ccp/ccp-dmaengine.c
index e01b08a28ce5..8afd62052edd 100644
--- a/drivers/crypto/ccp/ccp-dmaengine.c
+++ b/drivers/crypto/ccp/ccp-dmaengine.c
@@ -231,9 +231,7 @@ static struct ccp_dma_desc *ccp_handle_active_desc(struct 
ccp_dma_chan *chan,
spin_unlock_irqrestore(>lock, flags);
 
if (tx_desc) {
-   if (tx_desc->callback &&
-   (tx_desc->flags & DMA_PREP_INTERRUPT))
-   tx_desc->callback(tx_desc->callback_param);
+   dmaengine_desc_get_callback_invoke(tx_desc, NULL);
 
dma_run_dependencies(tx_desc);
}



[PATCH] crypto: ccp - unmap pages and remove unmap objects in callback

2017-09-05 Thread Gary R Hook
From: amd <a...@sosxen2.amd.com>

Clean up the mapped pages and the unmap object once we are done with
it. This enables the final clean-up of the object once the transfer
is complete.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-dmaengine.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/crypto/ccp/ccp-dmaengine.c 
b/drivers/crypto/ccp/ccp-dmaengine.c
index 901343dd513e..e01b08a28ce5 100644
--- a/drivers/crypto/ccp/ccp-dmaengine.c
+++ b/drivers/crypto/ccp/ccp-dmaengine.c
@@ -223,6 +223,7 @@ static struct ccp_dma_desc *ccp_handle_active_desc(struct 
ccp_dma_chan *chan,
desc->tx_desc.cookie, desc->status);
 
dma_cookie_complete(tx_desc);
+   dma_descriptor_unmap(tx_desc);
}
 
desc = __ccp_next_dma_desc(chan, desc);



Re: [PATCH] crypto: ccp - Fix XTS-AES-128 support on v5 CCPs

2017-08-22 Thread Gary R Hook

On 08/18/2017 11:02 PM, Herbert Xu wrote:

On Fri, Aug 18, 2017 at 11:41:04AM -0500, Gary R Hook wrote:

On Tue, Jul 25, 2017 at 02:12:11PM -0500, Gary R Hook wrote:

Version 5 CCPs have some new requirements for XTS-AES: the type field
must be specified, and the key requires 512 bits, with each part
occupying 256 bits and padded with zeroes.

cc: <sta...@vger.kernel.org> # 4.9.x+

Signed-off-by: Gary R Hook <gh...@amd.com>


Patch applied.  Thanks.


Herbert,

*ping*

This is a bug fix, Could we push this into 4.13, please?


I don't think this one is critical enough to go in right now.
Is there any reason why it can't wait until the next merge window?


I am happy to defer to your expertise in this area. My concern was
whether the patch had been overlooked. I see now that it had not.

Thank you, sir.


Re: [PATCH] crypto: ccp - Fix XTS-AES support on a version 5 CCP

2017-08-18 Thread Gary R Hook

On 08/18/2017 11:19 AM, Gary R Hook wrote:

On 07/17/2017 04:48 PM, Lendacky, Thomas wrote:

On 7/17/2017 3:08 PM, Gary R Hook wrote:

Version 5 CCPs have differing requirements for XTS-AES: key components
are stored in a 512-bit vector. The context must be little-endian
justified. AES-256 is supported now, so propagate the cipher size to
the command descriptor.

Signed-off-by: Gary R Hook <gary.h...@amd.com>


Herbert,

I see that this patch (and others that add function or fix bugs) has
been added to
cryptodev. I've not seen anything CCP-related pushed to Linux in a
while, however.

Is there something more I need to do to for these recent patches, to get
them promoted
to the mainline kernel..?


Please ignore. I realized (too late) that the referenced items missed 
the merge window

for 4.13.




Thanks much!
Gary



---
  drivers/crypto/ccp/ccp-crypto-aes-xts.c |   79 ---
  drivers/crypto/ccp/ccp-dev-v5.c |2 +
  drivers/crypto/ccp/ccp-dev.h|2 +
  drivers/crypto/ccp/ccp-ops.c|   56 ++
  4 files changed, 89 insertions(+), 50 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 58a4244b4752..8d248b198e22 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -1,7 +1,7 @@
  /*
   * AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
   *
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
   *
   * Author: Tom Lendacky <thomas.lenda...@amd.com>
   *
@@ -37,46 +37,26 @@ struct ccp_unit_size_map {
   u32 value;
  };

-static struct ccp_unit_size_map unit_size_map[] = {
+static struct ccp_unit_size_map xts_unit_sizes[] = {
   {
- .size   = 4096,
- .value  = CCP_XTS_AES_UNIT_SIZE_4096,
- },
- {
- .size   = 2048,
- .value  = CCP_XTS_AES_UNIT_SIZE_2048,
- },
- {
- .size   = 1024,
- .value  = CCP_XTS_AES_UNIT_SIZE_1024,
+ .size   = 16,
+ .value  = CCP_XTS_AES_UNIT_SIZE_16,
   },
   {
- .size   = 512,
+ .size   = 512,
   .value  = CCP_XTS_AES_UNIT_SIZE_512,
   },
   {
- .size   = 256,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
- },
- {
- .size   = 128,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
- },
- {
- .size   = 64,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
- },
- {
- .size   = 32,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+ .size   = 1024,
+ .value  = CCP_XTS_AES_UNIT_SIZE_1024,
   },
   {
- .size   = 16,
- .value  = CCP_XTS_AES_UNIT_SIZE_16,
+ .size   = 2048,
+ .value  = CCP_XTS_AES_UNIT_SIZE_2048,
   },
   {
- .size   = 1,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+ .size   = 4096,
+ .value  = CCP_XTS_AES_UNIT_SIZE_4096,
   },
  };


Because of the way the unit size check is performed, you can't delete
the intermediate size checks.  Those must remain so that unit sizes
that aren't supported by the CCP are sent to the fallback mechanism.

Also, re-arranging the order should be a separate patch if that doesn't
really fix anything.



@@ -97,14 +77,20 @@ static int ccp_aes_xts_setkey(struct crypto_ablkcipher 
*tfm, const u8 *key,
 unsigned int key_len)
  {
   struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm));
+ unsigned int ccpversion = ccp_version();

   /* Only support 128-bit AES key with a 128-bit Tweak key,
* otherwise use the fallback
*/
+


Remove the addition of the blank line and update the above comment to
indicate the new supported key size added below.


   switch (key_len) {
   case AES_KEYSIZE_128 * 2:
   memcpy(ctx->u.aes.key, key, key_len);
   break;
+ case AES_KEYSIZE_256 * 2:
+ if (ccpversion > CCP_VERSION(3, 0))
+ memcpy(ctx->u.aes.key, key, key_len);
+ break;


Isn't u.aes.key defined with a maximum buffer size of AES_MAX_KEY_SIZE
(which is 32)?  I think this will cause a buffer overrun on memcpy.


   }
   ctx->u.aes.key_len = key_len / 2;
   sg_init_one(>u.aes.key_sg, ctx->u.aes.key, key_len);
@@ -117,7 +103,10 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
  {
   struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
   struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
+ unsigned int ccpversion = ccp_version();
+ unsigned int fallback = 0;
   unsigned int unit;
+ u32 block_size = 0;
   u32 unit_size;
   int ret;

@@ -131,17 +120,29 @@ static int ccp_aes_xt

Re: [PATCH] crypto: ccp - Fix XTS-AES-128 support on v5 CCPs

2017-08-18 Thread Gary R Hook

On Tue, Jul 25, 2017 at 02:12:11PM -0500, Gary R Hook wrote:
> Version 5 CCPs have some new requirements for XTS-AES: the type field
> must be specified, and the key requires 512 bits, with each part
> occupying 256 bits and padded with zeroes.
>
> cc: <sta...@vger.kernel.org> # 4.9.x+
>
> Signed-off-by: Gary R Hook <gh...@amd.com>

Patch applied.  Thanks.


Herbert,

*ping*

This is a bug fix, Could we push this into 4.13, please?

Gary


Re: [PATCH] crypto: ccp - Fix XTS-AES support on a version 5 CCP

2017-08-18 Thread Gary R Hook

On 07/17/2017 04:48 PM, Lendacky, Thomas wrote:

On 7/17/2017 3:08 PM, Gary R Hook wrote:

Version 5 CCPs have differing requirements for XTS-AES: key components
are stored in a 512-bit vector. The context must be little-endian
justified. AES-256 is supported now, so propagate the cipher size to
the command descriptor.

Signed-off-by: Gary R Hook <gary.h...@amd.com>


Herbert,

I see that this patch (and others that add function or fix bugs) has 
been added to
cryptodev. I've not seen anything CCP-related pushed to Linux in a 
while, however.


Is there something more I need to do to for these recent patches, to get 
them promoted

to the mainline kernel..?

Thanks much!
Gary



---
  drivers/crypto/ccp/ccp-crypto-aes-xts.c |   79 ---
  drivers/crypto/ccp/ccp-dev-v5.c |2 +
  drivers/crypto/ccp/ccp-dev.h|2 +
  drivers/crypto/ccp/ccp-ops.c|   56 ++
  4 files changed, 89 insertions(+), 50 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 58a4244b4752..8d248b198e22 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -1,7 +1,7 @@
  /*
   * AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
   *
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
   *
   * Author: Tom Lendacky <thomas.lenda...@amd.com>
   *
@@ -37,46 +37,26 @@ struct ccp_unit_size_map {
   u32 value;
  };

-static struct ccp_unit_size_map unit_size_map[] = {
+static struct ccp_unit_size_map xts_unit_sizes[] = {
   {
- .size   = 4096,
- .value  = CCP_XTS_AES_UNIT_SIZE_4096,
- },
- {
- .size   = 2048,
- .value  = CCP_XTS_AES_UNIT_SIZE_2048,
- },
- {
- .size   = 1024,
- .value  = CCP_XTS_AES_UNIT_SIZE_1024,
+ .size   = 16,
+ .value  = CCP_XTS_AES_UNIT_SIZE_16,
   },
   {
- .size   = 512,
+ .size   = 512,
   .value  = CCP_XTS_AES_UNIT_SIZE_512,
   },
   {
- .size   = 256,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
- },
- {
- .size   = 128,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
- },
- {
- .size   = 64,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
- },
- {
- .size   = 32,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+ .size   = 1024,
+ .value  = CCP_XTS_AES_UNIT_SIZE_1024,
   },
   {
- .size   = 16,
- .value  = CCP_XTS_AES_UNIT_SIZE_16,
+ .size   = 2048,
+ .value  = CCP_XTS_AES_UNIT_SIZE_2048,
   },
   {
- .size   = 1,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+ .size   = 4096,
+ .value  = CCP_XTS_AES_UNIT_SIZE_4096,
   },
  };


Because of the way the unit size check is performed, you can't delete
the intermediate size checks.  Those must remain so that unit sizes
that aren't supported by the CCP are sent to the fallback mechanism.

Also, re-arranging the order should be a separate patch if that doesn't
really fix anything.



@@ -97,14 +77,20 @@ static int ccp_aes_xts_setkey(struct crypto_ablkcipher 
*tfm, const u8 *key,
 unsigned int key_len)
  {
   struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm));
+ unsigned int ccpversion = ccp_version();

   /* Only support 128-bit AES key with a 128-bit Tweak key,
* otherwise use the fallback
*/
+


Remove the addition of the blank line and update the above comment to
indicate the new supported key size added below.


   switch (key_len) {
   case AES_KEYSIZE_128 * 2:
   memcpy(ctx->u.aes.key, key, key_len);
   break;
+ case AES_KEYSIZE_256 * 2:
+ if (ccpversion > CCP_VERSION(3, 0))
+ memcpy(ctx->u.aes.key, key, key_len);
+ break;


Isn't u.aes.key defined with a maximum buffer size of AES_MAX_KEY_SIZE
(which is 32)?  I think this will cause a buffer overrun on memcpy.


   }
   ctx->u.aes.key_len = key_len / 2;
   sg_init_one(>u.aes.key_sg, ctx->u.aes.key, key_len);
@@ -117,7 +103,10 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
  {
   struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
   struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
+ unsigned int ccpversion = ccp_version();
+ unsigned int fallback = 0;
   unsigned int unit;
+ u32 block_size = 0;
   u32 unit_size;
   int ret;

@@ -131,17 +120,29 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
   return -EINVAL;

   unit_size = CCP_XTS_AES_UNIT_SIZE__LAST;
- if (req

Re: [PATCH v5 02/19] crypto: ccp: use -EAGAIN for transient busy indication

2017-08-14 Thread Gary R Hook

On 08/14/2017 10:21 AM, Gilad Ben-Yossef wrote:

Replace -EBUSY with -EAGAIN when reporting transient busy
indication in the absence of backlog.

Signed-off-by: Gilad Ben-Yossef <gi...@benyossef.com>


Reviewed-by: Gary R Hook <gary.h...@amd.com>


---
 drivers/crypto/ccp/ccp-crypto-main.c | 8 +++-
 drivers/crypto/ccp/ccp-dev.c | 7 +--
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-main.c 
b/drivers/crypto/ccp/ccp-crypto-main.c
index 35a9de7..403ff0a 100644
--- a/drivers/crypto/ccp/ccp-crypto-main.c
+++ b/drivers/crypto/ccp/ccp-crypto-main.c
@@ -222,9 +222,10 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd 
*crypto_cmd)

/* Check if the cmd can/should be queued */
if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
-   ret = -EBUSY;
-   if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG))
+   if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG)) {
+   ret = -EAGAIN;
goto e_lock;
+   }
}

/* Look for an entry with the same tfm.  If there is a cmd
@@ -243,9 +244,6 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd 
*crypto_cmd)
ret = ccp_enqueue_cmd(crypto_cmd->cmd);
if (!ccp_crypto_success(ret))
goto e_lock;/* Error, don't queue it */
-   if ((ret == -EBUSY) &&
-   !(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG))
-   goto e_lock;/* Not backlogging, don't queue it */
}

if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c
index 4e029b1..3d637e3 100644
--- a/drivers/crypto/ccp/ccp-dev.c
+++ b/drivers/crypto/ccp/ccp-dev.c
@@ -292,9 +292,12 @@ int ccp_enqueue_cmd(struct ccp_cmd *cmd)
i = ccp->cmd_q_count;

if (ccp->cmd_count >= MAX_CMD_QLEN) {
-   ret = -EBUSY;
-   if (cmd->flags & CCP_CMD_MAY_BACKLOG)
+   if (cmd->flags & CCP_CMD_MAY_BACKLOG) {
+   ret = -EBUSY;
list_add_tail(>entry, >backlog);
+   } else {
+   ret = -EAGAIN;
+   }
} else {
ret = -EINPROGRESS;
ccp->cmd_count++;



Re: crypto: ccp: use dma_mapping_error to check map error

2017-08-08 Thread Gary R Hook

On 08/08/2017 08:42 AM, Pan Bian wrote:

The return value of dma_map_single() should be checked by
dma_mapping_error(). However, in function ccp_init_dm_workarea(), its
return value is checked against NULL, which could result in failures.

Signed-off-by: Pan Bian <bianpan2...@163.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
 drivers/crypto/ccp/ccp-ops.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index c0dfdac..ca83d19 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -168,7 +168,7 @@ static int ccp_init_dm_workarea(struct ccp_dm_workarea *wa,

wa->dma.address = dma_map_single(wa->dev, wa->address, len,
 dir);
-   if (!wa->dma.address)
+   if (dma_mapping_error(wa->dev, wa->dma.address))
return -ENOMEM;

wa->dma.length = len;



Re: [PATCH v4 02/19] crypto: ccm: use -EAGAIN for transient busy indication

2017-08-08 Thread Gary R Hook

On 08/08/2017 07:03 AM, Gilad Ben-Yossef wrote:

Replace -EBUSY with -EAGAIN when reporting transient busy
indication in the absence of backlog.

Signed-off-by: Gilad Ben-Yossef 


Could we use "ccp" in the subject line, please?


---
 drivers/crypto/ccp/ccp-crypto-main.c | 8 +++-
 drivers/crypto/ccp/ccp-dev.c | 7 +--
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-main.c 
b/drivers/crypto/ccp/ccp-crypto-main.c
index 35a9de7..403ff0a 100644
--- a/drivers/crypto/ccp/ccp-crypto-main.c
+++ b/drivers/crypto/ccp/ccp-crypto-main.c
@@ -222,9 +222,10 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd 
*crypto_cmd)

/* Check if the cmd can/should be queued */
if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
-   ret = -EBUSY;
-   if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG))
+   if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG)) {
+   ret = -EAGAIN;
goto e_lock;
+   }
}

/* Look for an entry with the same tfm.  If there is a cmd
@@ -243,9 +244,6 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd 
*crypto_cmd)
ret = ccp_enqueue_cmd(crypto_cmd->cmd);
if (!ccp_crypto_success(ret))
goto e_lock;/* Error, don't queue it */
-   if ((ret == -EBUSY) &&
-   !(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG))
-   goto e_lock;/* Not backlogging, don't queue it */
}

if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c
index 4e029b1..3d637e3 100644
--- a/drivers/crypto/ccp/ccp-dev.c
+++ b/drivers/crypto/ccp/ccp-dev.c
@@ -292,9 +292,12 @@ int ccp_enqueue_cmd(struct ccp_cmd *cmd)
i = ccp->cmd_q_count;

if (ccp->cmd_count >= MAX_CMD_QLEN) {
-   ret = -EBUSY;
-   if (cmd->flags & CCP_CMD_MAY_BACKLOG)
+   if (cmd->flags & CCP_CMD_MAY_BACKLOG) {
+   ret = -EBUSY;
list_add_tail(>entry, >backlog);
+   } else {
+   ret = -EAGAIN;
+   }
} else {
ret = -EINPROGRESS;
ccp->cmd_count++;



Re: [PATCH] crypto: ccp - avoid uninitialized variable warning

2017-08-01 Thread Gary R Hook

On 07/31/2017 03:49 PM, Arnd Bergmann wrote:

The added support for version 5 CCPs introduced a false-positive
warning in the RSA implementation:

drivers/crypto/ccp/ccp-ops.c: In function 'ccp_run_rsa_cmd':
drivers/crypto/ccp/ccp-ops.c:1856:3: error: 'sb_count' may be used 
uninitialized in this function [-Werror=maybe-uninitialized]

This changes the code in a way that should make it easier for
the compiler to track the state of the sb_count variable, and
avoid the warning.

Fixes: 6ba46c7d4d7e ("crypto: ccp - Fix base RSA function for version 5 CCPs")
Signed-off-by: Arnd Bergmann <a...@arndb.de>
---
 drivers/crypto/ccp/ccp-ops.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 40c062ad8726..a8bc207b099a 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1758,6 +1758,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
o_len = 32 * ((rsa->key_size + 255) / 256);
i_len = o_len * 2;

+   sb_count = 0;
if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0)) {
/* sb_count is the number of storage block slots required
 * for the modulus.
@@ -1852,7 +1853,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
ccp_dm_free();

 e_sb:
-   if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0))
+   if (sb_count)
cmd_q->ccp->vdata->perform->sbfree(cmd_q, op.sb_key, sb_count);

return ret;



Reviewed-by: Gary R Hook <gary.h...@amd.com>


Re: [PATCH] crypto: ccp - avoid uninitialized variable warning

2017-08-01 Thread Gary R Hook

On 08/01/2017 03:35 PM, Arnd Bergmann wrote:

On Tue, Aug 1, 2017 at 4:52 PM, Gary R Hook <gary.h...@amd.com> wrote:

On 07/31/2017 03:49 PM, Arnd Bergmann wrote:


The added support for version 5 CCPs introduced a false-positive
warning in the RSA implementation:

drivers/crypto/ccp/ccp-ops.c: In function 'ccp_run_rsa_cmd':
drivers/crypto/ccp/ccp-ops.c:1856:3: error: 'sb_count' may be used
uninitialized in this function [-Werror=maybe-uninitialized]

This changes the code in a way that should make it easier for
the compiler to track the state of the sb_count variable, and
avoid the warning.

Fixes: 6ba46c7d4d7e ("crypto: ccp - Fix base RSA function for version 5
CCPs")
Signed-off-by: Arnd Bergmann <a...@arndb.de>
---
 drivers/crypto/ccp/ccp-ops.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 40c062ad8726..a8bc207b099a 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1758,6 +1758,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue
*cmd_q, struct ccp_cmd *cmd)
o_len = 32 * ((rsa->key_size + 255) / 256);
i_len = o_len * 2;

+   sb_count = 0;
if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0)) {
/* sb_count is the number of storage block slots required
 * for the modulus.
@@ -1852,7 +1853,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue
*cmd_q, struct ccp_cmd *cmd)
ccp_dm_free();

 e_sb:
-   if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0))
+   if (sb_count)
cmd_q->ccp->vdata->perform->sbfree(cmd_q, op.sb_key,
sb_count);

return ret;



This is a fine solution. However, having lived with this annoyance for a
while, and even hoping that a
a later compiler fixes it, I would have preferred to either:

1) Initialize the local variable at declaration time, or


I try to never do that in general, see https://rusty.ozlabs.org/?p=232


I know. I just globally disagree with a global decision of this sort.
Now I make errors that are more complex, partially because I've shot myself
in the foot repeatedly, and learned from it.

Nonetheless...

I will ack your suggested patch. Thank you for addressing this. I've learned
something.


Re: [PATCH] crypto: ccp - select CONFIG_CRYPTO_RSA

2017-08-01 Thread Gary R Hook

On 07/31/2017 04:10 PM, Arnd Bergmann wrote:

Without the base RSA code, we run into a link error:

ERROR: "rsa_parse_pub_key" [drivers/crypto/ccp/ccp-crypto.ko] undefined!
ERROR: "rsa_parse_priv_key" [drivers/crypto/ccp/ccp-crypto.ko] undefined!

Like the other drivers implementing RSA in hardware, this
can be avoided by always enabling the base support when we build
CCP.

Fixes: ceeec0afd684 ("crypto: ccp - Add support for RSA on the CCP")
Signed-off-by: Arnd Bergmann <a...@arndb.de>
---
 drivers/crypto/ccp/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig
index 15b63fd3d180..6d626606b9c5 100644
--- a/drivers/crypto/ccp/Kconfig
+++ b/drivers/crypto/ccp/Kconfig
@@ -27,6 +27,7 @@ config CRYPTO_DEV_CCP_CRYPTO
select CRYPTO_HASH
select CRYPTO_BLKCIPHER
select CRYPTO_AUTHENC
+   select CRYPTO_RSA
help
  Support for using the cryptographic API with the AMD Cryptographic
  Coprocessor. This module supports offload of SHA and AES algorithms.



Reviewed by: Gary R Hook <gary.h...@amd.com>


Re: [PATCH] crypto: ccp - avoid uninitialized variable warning

2017-08-01 Thread Gary R Hook

On 07/31/2017 03:49 PM, Arnd Bergmann wrote:

The added support for version 5 CCPs introduced a false-positive
warning in the RSA implementation:

drivers/crypto/ccp/ccp-ops.c: In function 'ccp_run_rsa_cmd':
drivers/crypto/ccp/ccp-ops.c:1856:3: error: 'sb_count' may be used 
uninitialized in this function [-Werror=maybe-uninitialized]

This changes the code in a way that should make it easier for
the compiler to track the state of the sb_count variable, and
avoid the warning.

Fixes: 6ba46c7d4d7e ("crypto: ccp - Fix base RSA function for version 5 CCPs")
Signed-off-by: Arnd Bergmann 
---
 drivers/crypto/ccp/ccp-ops.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 40c062ad8726..a8bc207b099a 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1758,6 +1758,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
o_len = 32 * ((rsa->key_size + 255) / 256);
i_len = o_len * 2;

+   sb_count = 0;
if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0)) {
/* sb_count is the number of storage block slots required
 * for the modulus.
@@ -1852,7 +1853,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
ccp_dm_free();

 e_sb:
-   if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0))
+   if (sb_count)
cmd_q->ccp->vdata->perform->sbfree(cmd_q, op.sb_key, sb_count);

return ret;



This is a fine solution. However, having lived with this annoyance for a 
while, and even hoping that a

a later compiler fixes it, I would have preferred to either:

1) Initialize the local variable at declaration time, or

2) Use this patch, which the compiler could optimize as it sees fit, and 
maintains a clear distinction

for the code path for older devices:

diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 40c062a..a3a884a 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1733,7 +1733,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue 
*cmd_q, struct ccp_cmd *cmd)

struct ccp_rsa_engine *rsa = >u.rsa;
struct ccp_dm_workarea exp, src, dst;
struct ccp_op op;
-   unsigned int sb_count, i_len, o_len;
+   unsigned int i_len, o_len;
int ret;

/* Check against the maximum allowable size, in bits */
@@ -1762,7 +1762,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue 
*cmd_q, struct ccp_cmd *cmd)

/* sb_count is the number of storage block slots required
 * for the modulus.
 */
-   sb_count = o_len / CCP_SB_BYTES;
+   unsigned int sb_count = o_len / CCP_SB_BYTES;
op.sb_key = cmd_q->ccp->vdata->perform->sballoc(cmd_q,
sb_count);
if (!op.sb_key)
@@ -1853,7 +1853,10 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue 
*cmd_q, struct ccp_cmd *cmd)


 e_sb:
if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0))
+   {
+   unsigned int sb_count = o_len / CCP_SB_BYTES;
cmd_q->ccp->vdata->perform->sbfree(cmd_q, op.sb_key, 
sb_count);

+   }

return ret;
 }


Discuss?



Re: [PATCH v3 0/3] Update support for XTS-AES on AMD CCPs

2017-07-25 Thread Gary R Hook

On 07/25/2017 02:21 PM, Hook, Gary wrote:

The following series adds support for XS-AES on version 5 CCPs, both
128- and 256-bit, and enhances/clarifies/simplifies some crypto layer
code.


Herbert:

Oops. The last patch in this series depends upon a fix that was sent 
just prior

to this. This series won't fully apply to cryptodev-2.6 without it, and thus
will have to wait until "Fix XTS-AES-128 support on v5 CCPs" is processed.

Sorry about that.



Changes since v2:
 - Move a CCP v5 fix out of this patch series and submit independently
 - In the unit-size check patch:
- Edit comments
- Remove unnecessary variable
- Delay a change (that belongs in the CCP v5 patch)

Changes since v1:
 - rework the validation of the unit-size; move to a separate patch
 - expand the key buffer to accommodate 256-bit keys
 - use xts_check_key() in the crypto layer


---

Gary R Hook (3):
  crypto: ccp - Add a call to xts_check_key()
  crypto: ccp - Rework the unit-size check for XTS-AES
  crypto: ccp - Add XTS-AES-256 support for CCP version 5


 drivers/crypto/ccp/ccp-crypto-aes-xts.c |   92
+--
 drivers/crypto/ccp/ccp-crypto.h |2 -
 drivers/crypto/ccp/ccp-ops.c|2 +
 3 files changed, 53 insertions(+), 43 deletions(-)

--


[PATCH v3 0/3] Update support for XTS-AES on AMD CCPs

2017-07-25 Thread Gary R Hook
The following series adds support for XS-AES on version 5 CCPs, both
128- and 256-bit, and enhances/clarifies/simplifies some crypto layer
code.

Changes since v2:
 - Move a CCP v5 fix out of this patch series and submit independently
 - In the unit-size check patch:
- Edit comments
- Remove unnecessary variable
- Delay a change (that belongs in the CCP v5 patch)

Changes since v1:
 - rework the validation of the unit-size; move to a separate patch
 - expand the key buffer to accommodate 256-bit keys
 - use xts_check_key() in the crypto layer


---

Gary R Hook (3):
  crypto: ccp - Add a call to xts_check_key()
  crypto: ccp - Rework the unit-size check for XTS-AES
  crypto: ccp - Add XTS-AES-256 support for CCP version 5


 drivers/crypto/ccp/ccp-crypto-aes-xts.c |   92 +--
 drivers/crypto/ccp/ccp-crypto.h |2 -
 drivers/crypto/ccp/ccp-ops.c|2 +
 3 files changed, 53 insertions(+), 43 deletions(-)

--


[PATCH v3 1/3] crypto: ccp - Add a call to xts_check_key()

2017-07-25 Thread Gary R Hook
Vet the key using the available standard function

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-xts.c |9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 3f26a415ef44..2b5d3a62fad9 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -97,7 +98,13 @@ static int ccp_aes_xts_complete(struct crypto_async_request 
*async_req, int ret)
 static int ccp_aes_xts_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
  unsigned int key_len)
 {
-   struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm));
+   struct crypto_tfm *xfm = crypto_ablkcipher_tfm(tfm);
+   struct ccp_ctx *ctx = crypto_tfm_ctx(xfm);
+   int ret;
+
+   ret = xts_check_key(xfm, key, key_len);
+   if (ret)
+   return ret;
 
/* Only support 128-bit AES key with a 128-bit Tweak key,
 * otherwise use the fallback



[PATCH v3 2/3] crypto: ccp - Rework the unit-size check for XTS-AES

2017-07-25 Thread Gary R Hook
The CCP supports a limited set of unit-size values. Change the check
for this parameter such that acceptable values match the enumeration.
Then clarify the conditions under which we must use the fallback
implementation.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-xts.c |   57 +++
 1 file changed, 20 insertions(+), 37 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 2b5d3a62fad9..5c2df880ab48 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -39,46 +39,26 @@ struct ccp_unit_size_map {
u32 value;
 };
 
-static struct ccp_unit_size_map unit_size_map[] = {
+static struct ccp_unit_size_map xts_unit_sizes[] = {
{
-   .size   = 4096,
-   .value  = CCP_XTS_AES_UNIT_SIZE_4096,
-   },
-   {
-   .size   = 2048,
-   .value  = CCP_XTS_AES_UNIT_SIZE_2048,
-   },
-   {
-   .size   = 1024,
-   .value  = CCP_XTS_AES_UNIT_SIZE_1024,
+   .size   = 16,
+   .value  = CCP_XTS_AES_UNIT_SIZE_16,
},
{
-   .size   = 512,
+   .size   = 512,
.value  = CCP_XTS_AES_UNIT_SIZE_512,
},
{
-   .size   = 256,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
-   },
-   {
-   .size   = 128,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
-   },
-   {
-   .size   = 64,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
-   },
-   {
-   .size   = 32,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+   .size   = 1024,
+   .value  = CCP_XTS_AES_UNIT_SIZE_1024,
},
{
-   .size   = 16,
-   .value  = CCP_XTS_AES_UNIT_SIZE_16,
+   .size   = 2048,
+   .value  = CCP_XTS_AES_UNIT_SIZE_2048,
},
{
-   .size   = 1,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+   .size   = 4096,
+   .value  = CCP_XTS_AES_UNIT_SIZE_4096,
},
 };
 
@@ -138,16 +118,19 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
if (!req->info)
return -EINVAL;
 
+   /* Check conditions under which the CCP can fulfill a request. The
+* device can handle input plaintext of a length that is a multiple
+* of the unit_size, bug the crypto implementation only supports
+* the unit_size being equal to the input length. This limits the
+* number of scenarios we can handle.
+*/
unit_size = CCP_XTS_AES_UNIT_SIZE__LAST;
-   if (req->nbytes <= unit_size_map[0].size) {
-   for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++) {
-   if (!(req->nbytes & (unit_size_map[unit].size - 1))) {
-   unit_size = unit_size_map[unit].value;
-   break;
-   }
+   for (unit = 0; unit < ARRAY_SIZE(xts_unit_sizes); unit++) {
+   if (req->nbytes == xts_unit_sizes[unit].size) {
+   unit_size = unit;
+   break;
}
}
-
if ((unit_size == CCP_XTS_AES_UNIT_SIZE__LAST) ||
(ctx->u.aes.key_len != AES_KEYSIZE_128)) {
SKCIPHER_REQUEST_ON_STACK(subreq, ctx->u.aes.tfm_skcipher);



[PATCH v3 3/3] crypto: ccp - Add XTS-AES-256 support for CCP version 5

2017-07-25 Thread Gary R Hook
Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-xts.c |   26 ++
 drivers/crypto/ccp/ccp-crypto.h |2 +-
 drivers/crypto/ccp/ccp-ops.c|2 ++
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 5c2df880ab48..94b5bcf5b628 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -80,19 +80,24 @@ static int ccp_aes_xts_setkey(struct crypto_ablkcipher 
*tfm, const u8 *key,
 {
struct crypto_tfm *xfm = crypto_ablkcipher_tfm(tfm);
struct ccp_ctx *ctx = crypto_tfm_ctx(xfm);
+   unsigned int ccpversion = ccp_version();
int ret;
 
ret = xts_check_key(xfm, key, key_len);
if (ret)
return ret;
 
-   /* Only support 128-bit AES key with a 128-bit Tweak key,
-* otherwise use the fallback
+   /* Version 3 devices support 128-bit keys; version 5 devices can
+* accommodate 128- and 256-bit keys.
 */
switch (key_len) {
case AES_KEYSIZE_128 * 2:
memcpy(ctx->u.aes.key, key, key_len);
break;
+   case AES_KEYSIZE_256 * 2:
+   if (ccpversion > CCP_VERSION(3, 0))
+   memcpy(ctx->u.aes.key, key, key_len);
+   break;
}
ctx->u.aes.key_len = key_len / 2;
sg_init_one(>u.aes.key_sg, ctx->u.aes.key, key_len);
@@ -105,6 +110,8 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
 {
struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
+   unsigned int ccpversion = ccp_version();
+   unsigned int fallback = 0;
unsigned int unit;
u32 unit_size;
int ret;
@@ -131,8 +138,19 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
break;
}
}
-   if ((unit_size == CCP_XTS_AES_UNIT_SIZE__LAST) ||
-   (ctx->u.aes.key_len != AES_KEYSIZE_128)) {
+   /* The CCP has restrictions on block sizes. Also, a version 3 device
+* only supports AES-128 operations; version 5 CCPs support both
+* AES-128 and -256 operations.
+*/
+   if (unit_size == CCP_XTS_AES_UNIT_SIZE__LAST)
+   fallback = 1;
+   if ((ccpversion < CCP_VERSION(5, 0)) &&
+   (ctx->u.aes.key_len != AES_KEYSIZE_128))
+   fallback = 1;
+   if ((ctx->u.aes.key_len != AES_KEYSIZE_128) &&
+   (ctx->u.aes.key_len != AES_KEYSIZE_256))
+   fallback = 1;
+   if (fallback) {
SKCIPHER_REQUEST_ON_STACK(subreq, ctx->u.aes.tfm_skcipher);
 
/* Use the fallback to process the request for any
diff --git a/drivers/crypto/ccp/ccp-crypto.h b/drivers/crypto/ccp/ccp-crypto.h
index 156b8233853f..880f8acdd0cd 100644
--- a/drivers/crypto/ccp/ccp-crypto.h
+++ b/drivers/crypto/ccp/ccp-crypto.h
@@ -91,7 +91,7 @@ struct ccp_aes_ctx {
 
struct scatterlist key_sg;
unsigned int key_len;
-   u8 key[AES_MAX_KEY_SIZE];
+   u8 key[AES_MAX_KEY_SIZE * 2];
 
u8 nonce[CTR_RFC3686_NONCE_SIZE];
 
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 6a2857274f61..6045e8c1d025 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1065,6 +1065,8 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue 
*cmd_q,
 
if (xts->key_len == AES_KEYSIZE_128)
aestype = CCP_AES_TYPE_128;
+   else if (xts->key_len == AES_KEYSIZE_256)
+   aestype = CCP_AES_TYPE_256;
else
return -EINVAL;
 



[PATCH] crypto: ccp - Fix XTS-AES-128 support on v5 CCPs

2017-07-25 Thread Gary R Hook
Version 5 CCPs have some new requirements for XTS-AES: the type field
must be specified, and the key requires 512 bits, with each part
occupying 256 bits and padded with zeroes.

cc: <sta...@vger.kernel.org> # 4.9.x+

Signed-off-by: Gary R Hook <gh...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-xts.c |4 ++-
 drivers/crypto/ccp/ccp-dev-v5.c |2 +
 drivers/crypto/ccp/ccp-dev.h|2 +
 drivers/crypto/ccp/ccp-ops.c|   43 +--
 include/linux/ccp.h |3 +-
 5 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 58a4244b4752..3f26a415ef44 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -1,8 +1,9 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
  *
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
+ * Author: Gary R Hook <gary.h...@amd.com>
  * Author: Tom Lendacky <thomas.lenda...@amd.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -164,6 +165,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
memset(>cmd, 0, sizeof(rctx->cmd));
INIT_LIST_HEAD(>cmd.entry);
rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
+   rctx->cmd.u.xts.type = CCP_AES_TYPE_128;
rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
   : CCP_AES_ACTION_DECRYPT;
rctx->cmd.u.xts.unit_size = unit_size;
diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c
index b3526336d608..9221db10d5ed 100644
--- a/drivers/crypto/ccp/ccp-dev-v5.c
+++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -145,6 +145,7 @@ union ccp_function {
 #defineCCP_AES_MODE(p) ((p)->aes.mode)
 #defineCCP_AES_TYPE(p) ((p)->aes.type)
 #defineCCP_XTS_SIZE(p) ((p)->aes_xts.size)
+#defineCCP_XTS_TYPE(p) ((p)->aes_xts.type)
 #defineCCP_XTS_ENCRYPT(p)  ((p)->aes_xts.encrypt)
 #defineCCP_DES3_SIZE(p)((p)->des3.size)
 #defineCCP_DES3_ENCRYPT(p) ((p)->des3.encrypt)
@@ -344,6 +345,7 @@ static int ccp5_perform_xts_aes(struct ccp_op *op)
CCP5_CMD_PROT() = 0;
 
function.raw = 0;
+   CCP_XTS_TYPE() = op->u.xts.type;
CCP_XTS_ENCRYPT() = op->u.xts.action;
CCP_XTS_SIZE() = op->u.xts.unit_size;
CCP5_CMD_FUNCTION() = function.raw;
diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h
index 9320931d89da..3d51180199ac 100644
--- a/drivers/crypto/ccp/ccp-dev.h
+++ b/drivers/crypto/ccp/ccp-dev.h
@@ -194,6 +194,7 @@
 #define CCP_AES_CTX_SB_COUNT   1
 
 #define CCP_XTS_AES_KEY_SB_COUNT   1
+#define CCP5_XTS_AES_KEY_SB_COUNT  2
 #define CCP_XTS_AES_CTX_SB_COUNT   1
 
 #define CCP_DES3_KEY_SB_COUNT  1
@@ -497,6 +498,7 @@ struct ccp_aes_op {
 };
 
 struct ccp_xts_aes_op {
+   enum ccp_aes_type type;
enum ccp_aes_action action;
enum ccp_xts_aes_unit_size unit_size;
 };
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index e23d138fc1ce..6a2857274f61 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1038,6 +1038,8 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue 
*cmd_q,
struct ccp_op op;
unsigned int unit_size, dm_offset;
bool in_place = false;
+   unsigned int sb_count;
+   enum ccp_aes_type aestype;
int ret;
 
switch (xts->unit_size) {
@@ -1061,7 +1063,9 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue 
*cmd_q,
return -EINVAL;
}
 
-   if (xts->key_len != AES_KEYSIZE_128)
+   if (xts->key_len == AES_KEYSIZE_128)
+   aestype = CCP_AES_TYPE_128;
+   else
return -EINVAL;
 
if (!xts->final && (xts->src_len & (AES_BLOCK_SIZE - 1)))
@@ -1083,23 +1087,44 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue 
*cmd_q,
op.sb_key = cmd_q->sb_key;
op.sb_ctx = cmd_q->sb_ctx;
op.init = 1;
+   op.u.xts.type = aestype;
op.u.xts.action = xts->action;
op.u.xts.unit_size = xts->unit_size;
 
-   /* All supported key sizes fit in a single (32-byte) SB entry
-* and must be in little endian format. Use the 256-bit byte
-* swap passthru option to convert from big endian to little
-* endian.
+   /* A version 3 device only supports 128-bit keys, which fits into a
+* single SB entry. A version 5 device uses a 512-bit vector, so two
+* SB entries.
 */
+   if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0))
+   sb_count = CCP_

[PATCH v2 4/4] crypto: ccp - Add XTS-AES-256 support for CCP version 5

2017-07-21 Thread Gary R Hook
Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-xts.c |   16 +---
 drivers/crypto/ccp/ccp-crypto.h |2 +-
 drivers/crypto/ccp/ccp-ops.c|3 +++
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 3c37794ffe2d..4a3fe4d5ac71 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -80,19 +80,24 @@ static int ccp_aes_xts_setkey(struct crypto_ablkcipher 
*tfm, const u8 *key,
 {
struct crypto_tfm *xfm = crypto_ablkcipher_tfm(tfm);
struct ccp_ctx *ctx = crypto_tfm_ctx(xfm);
+   unsigned int ccpversion = ccp_version();
int ret;
 
ret = xts_check_key(xfm, key, key_len);
if (ret)
return ret;
 
-   /* Only support 128-bit AES key with a 128-bit Tweak key,
-* otherwise use the fallback
+   /* Version 3 devices support 128-bit keys; version 5 devices can
+* accommodate 128- and 256-bit keys.
 */
switch (key_len) {
case AES_KEYSIZE_128 * 2:
memcpy(ctx->u.aes.key, key, key_len);
break;
+   case AES_KEYSIZE_256 * 2:
+   if (ccpversion > CCP_VERSION(3, 0))
+   memcpy(ctx->u.aes.key, key, key_len);
+   break;
}
ctx->u.aes.key_len = key_len / 2;
sg_init_one(>u.aes.key_sg, ctx->u.aes.key, key_len);
@@ -105,6 +110,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
 {
struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
+   unsigned int ccpversion = ccp_version();
unsigned int fallback = 0;
unsigned int unit;
u32 block_size;
@@ -141,7 +147,11 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
 */
if (unit_size == CCP_XTS_AES_UNIT_SIZE__LAST)
fallback = 1;
-   if (ctx->u.aes.key_len != AES_KEYSIZE_128)
+   if ((ccpversion < CCP_VERSION(5, 0)) &&
+   (ctx->u.aes.key_len != AES_KEYSIZE_128))
+   fallback = 1;
+   if ((ctx->u.aes.key_len != AES_KEYSIZE_128) &&
+   (ctx->u.aes.key_len != AES_KEYSIZE_256))
fallback = 1;
if (fallback) {
SKCIPHER_REQUEST_ON_STACK(subreq, ctx->u.aes.tfm_skcipher);
diff --git a/drivers/crypto/ccp/ccp-crypto.h b/drivers/crypto/ccp/ccp-crypto.h
index 156b8233853f..880f8acdd0cd 100644
--- a/drivers/crypto/ccp/ccp-crypto.h
+++ b/drivers/crypto/ccp/ccp-crypto.h
@@ -91,7 +91,7 @@ struct ccp_aes_ctx {
 
struct scatterlist key_sg;
unsigned int key_len;
-   u8 key[AES_MAX_KEY_SIZE];
+   u8 key[AES_MAX_KEY_SIZE * 2];
 
u8 nonce[CTR_RFC3686_NONCE_SIZE];
 
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 8113355151d2..fbd024f6e898 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1065,6 +1065,8 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue 
*cmd_q,
 
if (xts->key_len == AES_KEYSIZE_128)
aestype = CCP_AES_TYPE_128;
+   else if (xts->key_len == AES_KEYSIZE_256)
+   aestype = CCP_AES_TYPE_256;
else
return -EINVAL;
 
@@ -1089,6 +1091,7 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue 
*cmd_q,
op.sb_ctx = cmd_q->sb_ctx;
op.init = 1;
op.u.xts.action = xts->action;
+   op.u.xts.type = aestype;
op.u.xts.unit_size = xts->unit_size;
 
/* A version 3 device only supports 128-bit keys, which fits into a



[PATCH v2 0/4] Update support for XTS-AES on AMD CCPs

2017-07-21 Thread Gary R Hook
The following series adds support for XS-AES on version 5 CCPs,
both 128- and 256-bit, and enhances/clarifies/simplifies some
crypto layer code.

Changes since v1:
 - rework the validation of the unit-size; move to a separate patch
 - expand the key buffer to accommodate 256-bit keys
 - use xts_check_key() in the crypto layer

---

Gary R Hook (4):
  crypto: ccp - Add a call to xts_check_key()
  crypto: ccp - Enable XTS-AES-128 support on all CCPs
  crypto: ccp - Rework the unit-size check for XTS-AES
  crypto: ccp - Add XTS-AES-256 support for CCP version 5


 drivers/crypto/ccp/ccp-crypto-aes-xts.c |   98 +--
 drivers/crypto/ccp/ccp-crypto.h |2 -
 drivers/crypto/ccp/ccp-dev-v5.c |2 +
 drivers/crypto/ccp/ccp-dev.h|2 +
 drivers/crypto/ccp/ccp-ops.c|   55 +++--
 5 files changed, 106 insertions(+), 53 deletions(-)

--


[PATCH v2 3/4] crypto: ccp - Rework the unit-size check for XTS-AES

2017-07-21 Thread Gary R Hook
The CCP supports a limited set of unit-size values. Change the check
for this parameter such that acceptable values match the enumeration.
Then clarify the conditions under which we must use the fallback
implementation.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-xts.c |   75 ++-
 1 file changed, 35 insertions(+), 40 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 4a313f62dbea..3c37794ffe2d 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -1,8 +1,9 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
  *
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
+ * Author: Gary R Hook <gary.h...@amd.com>
  * Author: Tom Lendacky <thomas.lenda...@amd.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -38,46 +39,26 @@ struct ccp_unit_size_map {
u32 value;
 };
 
-static struct ccp_unit_size_map unit_size_map[] = {
+static struct ccp_unit_size_map xts_unit_sizes[] = {
{
-   .size   = 4096,
-   .value  = CCP_XTS_AES_UNIT_SIZE_4096,
-   },
-   {
-   .size   = 2048,
-   .value  = CCP_XTS_AES_UNIT_SIZE_2048,
-   },
-   {
-   .size   = 1024,
-   .value  = CCP_XTS_AES_UNIT_SIZE_1024,
+   .size   = 16,
+   .value  = CCP_XTS_AES_UNIT_SIZE_16,
},
{
-   .size   = 512,
+   .size   = 512,
.value  = CCP_XTS_AES_UNIT_SIZE_512,
},
{
-   .size   = 256,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
-   },
-   {
-   .size   = 128,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
-   },
-   {
-   .size   = 64,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
-   },
-   {
-   .size   = 32,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+   .size   = 1024,
+   .value  = CCP_XTS_AES_UNIT_SIZE_1024,
},
{
-   .size   = 16,
-   .value  = CCP_XTS_AES_UNIT_SIZE_16,
+   .size   = 2048,
+   .value  = CCP_XTS_AES_UNIT_SIZE_2048,
},
{
-   .size   = 1,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+   .size   = 4096,
+   .value  = CCP_XTS_AES_UNIT_SIZE_4096,
},
 };
 
@@ -124,7 +105,9 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
 {
struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
+   unsigned int fallback = 0;
unsigned int unit;
+   u32 block_size;
u32 unit_size;
int ret;
 
@@ -137,18 +120,30 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
if (!req->info)
return -EINVAL;
 
+   /* Check conditions under which the CCP can fulfill a request. The
+* device can handle input plaintext of a length that is a multiple
+* of the unit_size, bug the crypto implementation only supports
+* the unit_size being equal to the input length. This limits the
+* number of scenarios we can handle. Also validate the key length.
+*/
+   block_size = 0;
unit_size = CCP_XTS_AES_UNIT_SIZE__LAST;
-   if (req->nbytes <= unit_size_map[0].size) {
-   for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++) {
-   if (!(req->nbytes & (unit_size_map[unit].size - 1))) {
-   unit_size = unit_size_map[unit].value;
-   break;
-   }
+   for (unit = 0; unit < ARRAY_SIZE(xts_unit_sizes); unit++) {
+   if (req->nbytes == xts_unit_sizes[unit].size) {
+   unit_size = unit;
+   block_size = xts_unit_sizes[unit].size;
+   break;
}
}
-
-   if ((unit_size == CCP_XTS_AES_UNIT_SIZE__LAST) ||
-   (ctx->u.aes.key_len != AES_KEYSIZE_128)) {
+   /* The CCP has restrictions on block sizes. Also, a version 3 device
+* only supports AES-128 operations; version 5 CCPs support both
+* AES-128 and -256 operations.
+*/
+   if (unit_size == CCP_XTS_AES_UNIT_SIZE__LAST)
+   fallback = 1;
+   if (ctx->u.aes.key_len != AES_KEYSIZE_128)
+   fallback = 1;
+   if (fallback) {
SKCIPHER_REQUEST_ON_STACK(subreq, ctx->u.aes.tfm_skcipher);
 
/* Use the fallback to process the request for any



[PATCH v2 1/4] crypto: ccp - Add a call to xts_check_key()

2017-07-21 Thread Gary R Hook
Vet the key using the available standard function

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-xts.c |9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 58a4244b4752..4a313f62dbea 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -96,7 +97,13 @@ static int ccp_aes_xts_complete(struct crypto_async_request 
*async_req, int ret)
 static int ccp_aes_xts_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
  unsigned int key_len)
 {
-   struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm));
+   struct crypto_tfm *xfm = crypto_ablkcipher_tfm(tfm);
+   struct ccp_ctx *ctx = crypto_tfm_ctx(xfm);
+   int ret;
+
+   ret = xts_check_key(xfm, key, key_len);
+   if (ret)
+   return ret;
 
/* Only support 128-bit AES key with a 128-bit Tweak key,
 * otherwise use the fallback



[PATCH v2 2/4] crypto: ccp - Enable XTS-AES-128 support on all CCPs

2017-07-21 Thread Gary R Hook
Version 5 CCPs have some new requirements for XTS-AES: the type field
must be specified, and the key requires 512 bits, with each part
occupying 256 bits and padded with zeroes.

Signed-off-by: Gary R Hook <gh...@amd.com>
---
 drivers/crypto/ccp/ccp-dev-v5.c |2 ++
 drivers/crypto/ccp/ccp-dev.h|2 ++
 drivers/crypto/ccp/ccp-ops.c|   52 ---
 3 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c
index b3526336d608..0fb4519c5194 100644
--- a/drivers/crypto/ccp/ccp-dev-v5.c
+++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -145,6 +145,7 @@ union ccp_function {
 #defineCCP_AES_MODE(p) ((p)->aes.mode)
 #defineCCP_AES_TYPE(p) ((p)->aes.type)
 #defineCCP_XTS_SIZE(p) ((p)->aes_xts.size)
+#defineCCP_XTS_TYPE(p) ((p)->aes_xts.type)
 #defineCCP_XTS_ENCRYPT(p)  ((p)->aes_xts.encrypt)
 #defineCCP_DES3_SIZE(p)((p)->des3.size)
 #defineCCP_DES3_ENCRYPT(p) ((p)->des3.encrypt)
@@ -346,6 +347,7 @@ static int ccp5_perform_xts_aes(struct ccp_op *op)
function.raw = 0;
CCP_XTS_ENCRYPT() = op->u.xts.action;
CCP_XTS_SIZE() = op->u.xts.unit_size;
+   CCP_XTS_TYPE() = op->u.xts.type;
CCP5_CMD_FUNCTION() = function.raw;
 
CCP5_CMD_LEN() = op->src.u.dma.length;
diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h
index 9320931d89da..3d51180199ac 100644
--- a/drivers/crypto/ccp/ccp-dev.h
+++ b/drivers/crypto/ccp/ccp-dev.h
@@ -194,6 +194,7 @@
 #define CCP_AES_CTX_SB_COUNT   1
 
 #define CCP_XTS_AES_KEY_SB_COUNT   1
+#define CCP5_XTS_AES_KEY_SB_COUNT  2
 #define CCP_XTS_AES_CTX_SB_COUNT   1
 
 #define CCP_DES3_KEY_SB_COUNT  1
@@ -497,6 +498,7 @@ struct ccp_aes_op {
 };
 
 struct ccp_xts_aes_op {
+   enum ccp_aes_type type;
enum ccp_aes_action action;
enum ccp_xts_aes_unit_size unit_size;
 };
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index e23d138fc1ce..8113355151d2 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1038,6 +1038,8 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue 
*cmd_q,
struct ccp_op op;
unsigned int unit_size, dm_offset;
bool in_place = false;
+   unsigned int sb_count = 0;
+   enum ccp_aes_type aestype;
int ret;
 
switch (xts->unit_size) {
@@ -1061,9 +1063,12 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue 
*cmd_q,
return -EINVAL;
}
 
-   if (xts->key_len != AES_KEYSIZE_128)
+   if (xts->key_len == AES_KEYSIZE_128)
+   aestype = CCP_AES_TYPE_128;
+   else
return -EINVAL;
 
+
if (!xts->final && (xts->src_len & (AES_BLOCK_SIZE - 1)))
return -EINVAL;
 
@@ -1086,20 +1091,47 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue 
*cmd_q,
op.u.xts.action = xts->action;
op.u.xts.unit_size = xts->unit_size;
 
-   /* All supported key sizes fit in a single (32-byte) SB entry
-* and must be in little endian format. Use the 256-bit byte
-* swap passthru option to convert from big endian to little
-* endian.
+   /* A version 3 device only supports 128-bit keys, which fits into a
+* single SB entry. A version 5 device uses a 512-bit vector, so two
+* SB entries.
 */
+   if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0))
+   sb_count = CCP_XTS_AES_KEY_SB_COUNT;
+   else
+   sb_count = CCP5_XTS_AES_KEY_SB_COUNT;
ret = ccp_init_dm_workarea(, cmd_q,
-  CCP_XTS_AES_KEY_SB_COUNT * CCP_SB_BYTES,
+  sb_count * CCP_SB_BYTES,
   DMA_TO_DEVICE);
if (ret)
return ret;
 
-   dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128;
-   ccp_set_dm_area(, dm_offset, xts->key, 0, xts->key_len);
-   ccp_set_dm_area(, 0, xts->key, dm_offset, xts->key_len);
+   if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) {
+   /* All supported key sizes must be in little endian format.
+* Use the 256-bit byte swap passthru option to convert from
+* big endian to little endian.
+*/
+   dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128;
+   ccp_set_dm_area(, dm_offset, xts->key, 0, xts->key_len);
+   ccp_set_dm_area(, 0, xts->key, xts->key_len, xts->key_len);
+   } else {
+   /* The AES key is at the little end and the tweak key is
+* at the big end. Since the byteswap operation is only
+* 256-bit, load the buffer according to the way things
+   

Re: [PATCH] crypto: ccp - Fix XTS-AES support on a version 5 CCP

2017-07-21 Thread Gary R Hook

On 07/17/2017 04:48 PM, Lendacky, Thomas wrote:

On 7/17/2017 3:08 PM, Gary R Hook wrote:

Version 5 CCPs have differing requirements for XTS-AES: key components
are stored in a 512-bit vector. The context must be little-endian
justified. AES-256 is supported now, so propagate the cipher size to
the command descriptor.

Signed-off-by: Gary R Hook <gary.h...@amd.com>



Look for a version 2


---
  drivers/crypto/ccp/ccp-crypto-aes-xts.c |   79 ---
  drivers/crypto/ccp/ccp-dev-v5.c |2 +
  drivers/crypto/ccp/ccp-dev.h|2 +
  drivers/crypto/ccp/ccp-ops.c|   56 ++
  4 files changed, 89 insertions(+), 50 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 58a4244b4752..8d248b198e22 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -1,7 +1,7 @@
  /*
   * AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
   *
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
   *
   * Author: Tom Lendacky <thomas.lenda...@amd.com>
   *
@@ -37,46 +37,26 @@ struct ccp_unit_size_map {
   u32 value;
  };

-static struct ccp_unit_size_map unit_size_map[] = {
+static struct ccp_unit_size_map xts_unit_sizes[] = {
   {
- .size   = 4096,
- .value  = CCP_XTS_AES_UNIT_SIZE_4096,
- },
- {
- .size   = 2048,
- .value  = CCP_XTS_AES_UNIT_SIZE_2048,
- },
- {
- .size   = 1024,
- .value  = CCP_XTS_AES_UNIT_SIZE_1024,
+ .size   = 16,
+ .value  = CCP_XTS_AES_UNIT_SIZE_16,
   },
   {
- .size   = 512,
+ .size   = 512,
   .value  = CCP_XTS_AES_UNIT_SIZE_512,
   },
   {
- .size   = 256,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
- },
- {
- .size   = 128,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
- },
- {
- .size   = 64,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
- },
- {
- .size   = 32,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+ .size   = 1024,
+ .value  = CCP_XTS_AES_UNIT_SIZE_1024,
   },
   {
- .size   = 16,
- .value  = CCP_XTS_AES_UNIT_SIZE_16,
+ .size   = 2048,
+ .value  = CCP_XTS_AES_UNIT_SIZE_2048,
   },
   {
- .size   = 1,
- .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+ .size   = 4096,
+ .value  = CCP_XTS_AES_UNIT_SIZE_4096,
   },
  };


Because of the way the unit size check is performed, you can't delete
the intermediate size checks.  Those must remain so that unit sizes
that aren't supported by the CCP are sent to the fallback mechanism.


Given the limitations of the CCP (w.r.t. XTS-AES) I thought it more 
clear to look
for only those unit-sizes that are supported, and to use the enumerated 
value

as the index.


Also, re-arranging the order should be a separate patch if that doesn't
really fix anything.


Yes, agreed.



@@ -97,14 +77,20 @@ static int ccp_aes_xts_setkey(struct crypto_ablkcipher 
*tfm, const u8 *key,
 unsigned int key_len)
  {
   struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm));
+ unsigned int ccpversion = ccp_version();

   /* Only support 128-bit AES key with a 128-bit Tweak key,
* otherwise use the fallback
*/
+


Remove the addition of the blank line and update the above comment to
indicate the new supported key size added below.


Yes.




   switch (key_len) {
   case AES_KEYSIZE_128 * 2:
   memcpy(ctx->u.aes.key, key, key_len);
   break;
+ case AES_KEYSIZE_256 * 2:
+ if (ccpversion > CCP_VERSION(3, 0))
+ memcpy(ctx->u.aes.key, key, key_len);
+ break;


Isn't u.aes.key defined with a maximum buffer size of AES_MAX_KEY_SIZE
(which is 32)?  I think this will cause a buffer overrun on memcpy.


Yes, the structure member needs to be made larger.




   }
   ctx->u.aes.key_len = key_len / 2;
   sg_init_one(>u.aes.key_sg, ctx->u.aes.key, key_len);
@@ -117,7 +103,10 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
  {
   struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
   struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
+ unsigned int ccpversion = ccp_version();
+ unsigned int fallback = 0;
   unsigned int unit;
+ u32 block_size = 0;
   u32 unit_size;
   int ret;

@@ -131,17 +120,29 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
   return -EINVAL;

   unit_size = CCP_XTS_AES_UNIT_SIZE__LAST;
- if (req->nbytes <= unit_size_map[0].size) {


Thi

Re: Poor RNG performance on Ryzen

2017-07-21 Thread Gary R Hook

On 07/21/2017 09:47 AM, Theodore Ts'o wrote:

On Fri, Jul 21, 2017 at 01:39:13PM +0200, Oliver Mangold wrote:

Better, but obviously there is still much room for improvement by reducing
the number of calls to RDRAND.


Hmm, is there some way we can easily tell we are running on Ryzen?  Or
do we believe this is going to be true for all AMD devices?

I guess we could add some kind of "has_crappy_arch_get_random()" call
which could be defined by arch/x86, and change how aggressively we use
arch_get_random_*() depending on whether has_crappy_arch_get_random()
returns true or not


Just a quick note to say that we are aware of the issue, and that it is
being addressed.


Re: [PATCH] crypto: ccp - Fix XTS-AES support on a version 5 CCP

2017-07-18 Thread Gary R Hook

On 07/18/2017 01:28 AM, Stephan Müller wrote:

Am Montag, 17. Juli 2017, 22:08:27 CEST schrieb Gary R Hook:

Hi Gary,


Version 5 CCPs have differing requirements for XTS-AES: key components
are stored in a 512-bit vector. The context must be little-endian
justified. AES-256 is supported now, so propagate the cipher size to
the command descriptor.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-xts.c |   79


..


@@ -97,14 +77,20 @@ static int ccp_aes_xts_setkey(struct crypto_ablkcipher
*tfm, const u8 *key, unsigned int key_len)
 {
   struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm));
+ unsigned int ccpversion = ccp_version();

   /* Only support 128-bit AES key with a 128-bit Tweak key,
* otherwise use the fallback
*/
+


Can you please add xts_check_key here?


Certainly!



[PATCH 4/4] csrypto: ccp - Expand RSA support for a v5 ccp

2017-07-17 Thread Gary R Hook
A version 5 CCP can handle an RSA modulus up to 16k bits.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-rsa.c |5 -
 drivers/crypto/ccp/ccp-crypto.h |1 +
 drivers/crypto/ccp/ccp-dev-v3.c |1 +
 drivers/crypto/ccp/ccp-dev-v5.c |2 ++
 drivers/crypto/ccp/ccp-dev.h|1 +
 drivers/crypto/ccp/ccp-ops.c|3 ++-
 drivers/crypto/ccp/sp-dev.h |1 +
 7 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-rsa.c 
b/drivers/crypto/ccp/ccp-crypto-rsa.c
index d5544943f5f0..e6db8672d89c 100644
--- a/drivers/crypto/ccp/ccp-crypto-rsa.c
+++ b/drivers/crypto/ccp/ccp-crypto-rsa.c
@@ -60,7 +60,10 @@ static int ccp_rsa_complete(struct crypto_async_request 
*async_req, int ret)
 
 static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)
 {
-   return CCP_RSA_MAXMOD;
+   if (ccp_version() > CCP_VERSION(3, 0))
+   return CCP5_RSA_MAXMOD;
+   else
+   return CCP_RSA_MAXMOD;
 }
 
 static int ccp_rsa_crypt(struct akcipher_request *req, bool encrypt)
diff --git a/drivers/crypto/ccp/ccp-crypto.h b/drivers/crypto/ccp/ccp-crypto.h
index aa53b97f6f00..67c7620029e3 100644
--- a/drivers/crypto/ccp/ccp-crypto.h
+++ b/drivers/crypto/ccp/ccp-crypto.h
@@ -255,6 +255,7 @@ struct ccp_rsa_req_ctx {
 };
 
 #defineCCP_RSA_MAXMOD  (4 * 1024 / 8)
+#defineCCP5_RSA_MAXMOD (16 * 1024 / 8)
 
 /* Common Context Structure */
 struct ccp_ctx {
diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c
index c2861749e2ad..240bebbcb8ac 100644
--- a/drivers/crypto/ccp/ccp-dev-v3.c
+++ b/drivers/crypto/ccp/ccp-dev-v3.c
@@ -597,4 +597,5 @@ const struct ccp_vdata ccpv3 = {
.setup = NULL,
.perform = _actions,
.offset = 0x2,
+   .rsamax = CCP_RSA_MAX_WIDTH,
 };
diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c
index b77ac0a638d5..3f574d50c0f8 100644
--- a/drivers/crypto/ccp/ccp-dev-v5.c
+++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -1114,6 +1114,7 @@ const struct ccp_vdata ccpv5a = {
.setup = ccp5_config,
.perform = _actions,
.offset = 0x0,
+   .rsamax = CCP5_RSA_MAX_WIDTH,
 };
 
 const struct ccp_vdata ccpv5b = {
@@ -1122,4 +1123,5 @@ const struct ccp_vdata ccpv5b = {
.setup = ccp5other_config,
.perform = _actions,
.offset = 0x0,
+   .rsamax = CCP5_RSA_MAX_WIDTH,
 };
diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h
index 3d51180199ac..6810b65c1939 100644
--- a/drivers/crypto/ccp/ccp-dev.h
+++ b/drivers/crypto/ccp/ccp-dev.h
@@ -203,6 +203,7 @@
 #define CCP_SHA_SB_COUNT   1
 
 #define CCP_RSA_MAX_WIDTH  4096
+#define CCP5_RSA_MAX_WIDTH 16384
 
 #define CCP_PASSTHRU_BLOCKSIZE 256
 #define CCP_PASSTHRU_MASKSIZE  32
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 72c0f938abd7..c269f41e0526 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1770,7 +1770,8 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
unsigned int sb_count, i_len, o_len;
int ret;
 
-   if (rsa->key_size > CCP_RSA_MAX_WIDTH)
+   /* Check against the maximum allowable size, in bits */
+   if (rsa->key_size > cmd_q->ccp->vdata->rsamax)
return -EINVAL;
 
if (!rsa->exp || !rsa->mod || !rsa->src || !rsa->dst)
diff --git a/drivers/crypto/ccp/sp-dev.h b/drivers/crypto/ccp/sp-dev.h
index 3520da4e20cf..5ab486ade1ad 100644
--- a/drivers/crypto/ccp/sp-dev.h
+++ b/drivers/crypto/ccp/sp-dev.h
@@ -40,6 +40,7 @@ struct ccp_vdata {
void (*setup)(struct ccp_device *);
const struct ccp_actions *perform;
const unsigned int offset;
+   const unsigned int rsamax;
 };
 /* Structure to hold SP device data */
 struct sp_dev_vdata {



[PATCH 3/4] crypto: ccp - Add support for RSA on the CCP

2017-07-17 Thread Gary R Hook
Wire up the CCP as an RSA cipher provider.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/Makefile  |1 
 drivers/crypto/ccp/ccp-crypto-main.c |   19 ++
 drivers/crypto/ccp/ccp-crypto-rsa.c  |  296 ++
 drivers/crypto/ccp/ccp-crypto.h  |   31 
 4 files changed, 347 insertions(+)
 create mode 100644 drivers/crypto/ccp/ccp-crypto-rsa.c

diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 5f2adc5facfe..57f8debfcfb3 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -15,4 +15,5 @@ ccp-crypto-objs := ccp-crypto-main.o \
   ccp-crypto-aes-xts.o \
   ccp-crypto-aes-galois.o \
   ccp-crypto-des3.o \
+  ccp-crypto-rsa.o \
   ccp-crypto-sha.o
diff --git a/drivers/crypto/ccp/ccp-crypto-main.c 
b/drivers/crypto/ccp/ccp-crypto-main.c
index 78b9d26a381f..35a9de7fd475 100644
--- a/drivers/crypto/ccp/ccp-crypto-main.c
+++ b/drivers/crypto/ccp/ccp-crypto-main.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "ccp-crypto.h"
 
@@ -37,10 +38,15 @@ static unsigned int des3_disable;
 module_param(des3_disable, uint, 0444);
 MODULE_PARM_DESC(des3_disable, "Disable use of 3DES - any non-zero value");
 
+static unsigned int rsa_disable;
+module_param(rsa_disable, uint, 0444);
+MODULE_PARM_DESC(rsa_disable, "Disable use of RSA - any non-zero value");
+
 /* List heads for the supported algorithms */
 static LIST_HEAD(hash_algs);
 static LIST_HEAD(cipher_algs);
 static LIST_HEAD(aead_algs);
+static LIST_HEAD(akcipher_algs);
 
 /* For any tfm, requests for that tfm must be returned on the order
  * received.  With multiple queues available, the CCP can process more
@@ -358,6 +364,12 @@ static int ccp_register_algs(void)
return ret;
}
 
+   if (!rsa_disable) {
+   ret = ccp_register_rsa_algs(_algs);
+   if (ret)
+   return ret;
+   }
+
return 0;
 }
 
@@ -366,6 +378,7 @@ static void ccp_unregister_algs(void)
struct ccp_crypto_ahash_alg *ahash_alg, *ahash_tmp;
struct ccp_crypto_ablkcipher_alg *ablk_alg, *ablk_tmp;
struct ccp_crypto_aead *aead_alg, *aead_tmp;
+   struct ccp_crypto_akcipher_alg *akc_alg, *akc_tmp;
 
list_for_each_entry_safe(ahash_alg, ahash_tmp, _algs, entry) {
crypto_unregister_ahash(_alg->alg);
@@ -384,6 +397,12 @@ static void ccp_unregister_algs(void)
list_del(_alg->entry);
kfree(aead_alg);
}
+
+   list_for_each_entry_safe(akc_alg, akc_tmp, _algs, entry) {
+   crypto_unregister_akcipher(_alg->alg);
+   list_del(_alg->entry);
+   kfree(akc_alg);
+   }
 }
 
 static int ccp_crypto_init(void)
diff --git a/drivers/crypto/ccp/ccp-crypto-rsa.c 
b/drivers/crypto/ccp/ccp-crypto-rsa.c
new file mode 100644
index ..d5544943f5f0
--- /dev/null
+++ b/drivers/crypto/ccp/ccp-crypto-rsa.c
@@ -0,0 +1,296 @@
+/*
+ * AMD Cryptographic Coprocessor (CCP) RSA crypto API support
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ccp-crypto.h"
+
+static inline struct akcipher_request *akcipher_request_cast(
+   struct crypto_async_request *req)
+{
+   return container_of(req, struct akcipher_request, base);
+}
+
+static inline int ccp_copy_and_save_keypart(u8 **kpbuf, unsigned int *kplen,
+   const u8 *buf, size_t sz)
+{
+   int nskip;
+
+   for (nskip = 0; nskip < sz; nskip++)
+   if (buf[nskip])
+   break;
+   *kplen = sz - nskip;
+   *kpbuf = kzalloc(*kplen, GFP_KERNEL);
+   if (!*kpbuf)
+   return -ENOMEM;
+   memcpy(*kpbuf, buf + nskip, *kplen);
+
+   return 0;
+}
+
+static int ccp_rsa_complete(struct crypto_async_request *async_req, int ret)
+{
+   struct akcipher_request *req = akcipher_request_cast(async_req);
+   struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx(req);
+
+   if (ret)
+   return ret;
+
+   req->dst_len = rctx->cmd.u.rsa.key_size >> 3;
+
+   return 0;
+}
+
+static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)
+{
+   return CCP_RSA_MAXMOD;
+}
+
+static int ccp_rsa_crypt(struct akcipher_request *req, bool encrypt)
+{
+   struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+   struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
+ 

[PATCH 1/4] crypto: ccp - Fix base RSA function for version 5 CCPs

2017-07-17 Thread Gary R Hook
Version 5 devices have requirements for buffer lengths, as well as
parameter format (e.g. bits vs. bytes). Fix the base CCP driver
code to meet requirements all supported versions.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-dev-v5.c |   10 +++--
 drivers/crypto/ccp/ccp-ops.c|   78 +--
 2 files changed, 54 insertions(+), 34 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c
index 11febe2bd07c..b77ac0a638d5 100644
--- a/drivers/crypto/ccp/ccp-dev-v5.c
+++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -471,7 +471,7 @@ static int ccp5_perform_rsa(struct ccp_op *op)
CCP5_CMD_PROT() = 0;
 
function.raw = 0;
-   CCP_RSA_SIZE() = op->u.rsa.mod_size >> 3;
+   CCP_RSA_SIZE() = (op->u.rsa.mod_size + 7) >> 3;
CCP5_CMD_FUNCTION() = function.raw;
 
CCP5_CMD_LEN() = op->u.rsa.input_len;
@@ -486,10 +486,10 @@ static int ccp5_perform_rsa(struct ccp_op *op)
CCP5_CMD_DST_HI() = ccp_addr_hi(>dst.u.dma);
CCP5_CMD_DST_MEM() = CCP_MEMTYPE_SYSTEM;
 
-   /* Exponent is in LSB memory */
-   CCP5_CMD_KEY_LO() = op->sb_key * LSB_ITEM_SIZE;
-   CCP5_CMD_KEY_HI() = 0;
-   CCP5_CMD_KEY_MEM() = CCP_MEMTYPE_SB;
+   /* Key (Exponent) is in external memory */
+   CCP5_CMD_KEY_LO() = ccp_addr_lo(>exp.u.dma);
+   CCP5_CMD_KEY_HI() = ccp_addr_hi(>exp.u.dma);
+   CCP5_CMD_KEY_MEM() = CCP_MEMTYPE_SYSTEM;
 
return ccp5_do_cmd(, op->cmd_q);
 }
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index d1be07884a9b..72c0f938abd7 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1765,8 +1765,7 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
 static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
 {
struct ccp_rsa_engine *rsa = >u.rsa;
-   struct ccp_dm_workarea exp, src;
-   struct ccp_data dst;
+   struct ccp_dm_workarea exp, src, dst;
struct ccp_op op;
unsigned int sb_count, i_len, o_len;
int ret;
@@ -1777,30 +1776,40 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
if (!rsa->exp || !rsa->mod || !rsa->src || !rsa->dst)
return -EINVAL;
 
+   memset(, 0, sizeof(op));
+   op.cmd_q = cmd_q;
+   op.jobid = CCP_NEW_JOBID(cmd_q->ccp);
+
/* The RSA modulus must precede the message being acted upon, so
 * it must be copied to a DMA area where the message and the
 * modulus can be concatenated.  Therefore the input buffer
 * length required is twice the output buffer length (which
-* must be a multiple of 256-bits).
+* must be a multiple of 256-bits).  Compute o_len, i_len in bytes.
+* Buffer sizes must be a multiple of 32 bytes; rounding up may be
+* required.
 */
-   o_len = ((rsa->key_size + 255) / 256) * 32;
+   o_len = 32 * ((rsa->key_size + 255) / 256);
i_len = o_len * 2;
 
-   sb_count = o_len / CCP_SB_BYTES;
-
-   memset(, 0, sizeof(op));
-   op.cmd_q = cmd_q;
-   op.jobid = CCP_NEW_JOBID(cmd_q->ccp);
-   op.sb_key = cmd_q->ccp->vdata->perform->sballoc(cmd_q, sb_count);
-
-   if (!op.sb_key)
-   return -EIO;
+   if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0)) {
+   /* sb_count is the number of storage block slots required
+* for the modulus.
+*/
+   sb_count = o_len / CCP_SB_BYTES;
+   op.sb_key = cmd_q->ccp->vdata->perform->sballoc(cmd_q,
+   sb_count);
+   if (!op.sb_key)
+   return -EIO;
+   } else {
+   /* A version 5 device allows a modulus size that will not fit
+* in the LSB, so the command will transfer it from memory.
+* Set the sb key to the default, even though it's not used.
+*/
+   op.sb_key = cmd_q->sb_key;
+   }
 
-   /* The RSA exponent may span multiple (32-byte) SB entries and must
-* be in little endian format. Reverse copy each 32-byte chunk
-* of the exponent (En chunk to E0 chunk, E(n-1) chunk to E1 chunk)
-* and each byte within that chunk and do not perform any byte swap
-* operations on the passthru operation.
+   /* The RSA exponent must be in little endian format. Reverse its
+* byte order.
 */
ret = ccp_init_dm_workarea(, cmd_q, o_len, DMA_TO_DEVICE);
if (ret)
@@ -1809,11 +1818,22 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
ret = ccp_reverse_set_dm_area(, 0, rsa->exp, 0, rsa-&g

[PATCH 2/4] crypto: Add akcipher_set_reqsize() function

2017-07-17 Thread Gary R Hook
Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 0 files changed

diff --git a/include/crypto/internal/akcipher.h 
b/include/crypto/internal/akcipher.h
index 479a0078f0f7..805686ba2be4 100644
--- a/include/crypto/internal/akcipher.h
+++ b/include/crypto/internal/akcipher.h
@@ -38,6 +38,12 @@ static inline void *akcipher_request_ctx(struct 
akcipher_request *req)
return req->__ctx;
 }
 
+static inline void akcipher_set_reqsize(struct crypto_akcipher *akcipher,
+   unsigned int reqsize)
+{
+   crypto_akcipher_alg(akcipher)->reqsize = reqsize;
+}
+
 static inline void *akcipher_tfm_ctx(struct crypto_akcipher *tfm)
 {
return tfm->base.__crt_ctx;



[PATCH 0/4] Enable RSA Support on the CCP

2017-07-17 Thread Gary R Hook
This series accomplishes the following:

 - Fix RSA support in the base CCP driver
 - Add the akcipher_set_reqsize() function
 - Enable RSA support in the crypto layer
 - Allow for a larger RSA modulus in a version 5 CCP

---

Gary R Hook (4):
  crypto: ccp - Fix base RSA function for version 5 CCPs
  crypto: Add akcipher_set_reqsize() function
  crypto: ccp - Add support for RSA on the CCP
  csrypto: ccp - Expand RSA support for a v5 ccp


 drivers/crypto/ccp/Makefile  |1 
 drivers/crypto/ccp/ccp-crypto-main.c |   19 ++
 drivers/crypto/ccp/ccp-crypto-rsa.c  |  299 ++
 drivers/crypto/ccp/ccp-crypto.h  |   32 
 drivers/crypto/ccp/ccp-dev-v3.c  |1 
 drivers/crypto/ccp/ccp-dev-v5.c  |   12 +
 drivers/crypto/ccp/ccp-dev.h |1 
 drivers/crypto/ccp/ccp-ops.c |   81 ++---
 drivers/crypto/ccp/sp-dev.h  |1 
 9 files changed, 412 insertions(+), 35 deletions(-)
 create mode 100644 drivers/crypto/ccp/ccp-crypto-rsa.c

--


[PATCH] crypto: ccp - Fix XTS-AES support on a version 5 CCP

2017-07-17 Thread Gary R Hook
Version 5 CCPs have differing requirements for XTS-AES: key components
are stored in a 512-bit vector. The context must be little-endian
justified. AES-256 is supported now, so propagate the cipher size to
the command descriptor.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-xts.c |   79 ---
 drivers/crypto/ccp/ccp-dev-v5.c |2 +
 drivers/crypto/ccp/ccp-dev.h|2 +
 drivers/crypto/ccp/ccp-ops.c|   56 ++
 4 files changed, 89 insertions(+), 50 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c 
b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
index 58a4244b4752..8d248b198e22 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
  *
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
  * Author: Tom Lendacky <thomas.lenda...@amd.com>
  *
@@ -37,46 +37,26 @@ struct ccp_unit_size_map {
u32 value;
 };
 
-static struct ccp_unit_size_map unit_size_map[] = {
+static struct ccp_unit_size_map xts_unit_sizes[] = {
{
-   .size   = 4096,
-   .value  = CCP_XTS_AES_UNIT_SIZE_4096,
-   },
-   {
-   .size   = 2048,
-   .value  = CCP_XTS_AES_UNIT_SIZE_2048,
-   },
-   {
-   .size   = 1024,
-   .value  = CCP_XTS_AES_UNIT_SIZE_1024,
+   .size   = 16,
+   .value  = CCP_XTS_AES_UNIT_SIZE_16,
},
{
-   .size   = 512,
+   .size   = 512,
.value  = CCP_XTS_AES_UNIT_SIZE_512,
},
{
-   .size   = 256,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
-   },
-   {
-   .size   = 128,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
-   },
-   {
-   .size   = 64,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
-   },
-   {
-   .size   = 32,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+   .size   = 1024,
+   .value  = CCP_XTS_AES_UNIT_SIZE_1024,
},
{
-   .size   = 16,
-   .value  = CCP_XTS_AES_UNIT_SIZE_16,
+   .size   = 2048,
+   .value  = CCP_XTS_AES_UNIT_SIZE_2048,
},
{
-   .size   = 1,
-   .value  = CCP_XTS_AES_UNIT_SIZE__LAST,
+   .size   = 4096,
+   .value  = CCP_XTS_AES_UNIT_SIZE_4096,
},
 };
 
@@ -97,14 +77,20 @@ static int ccp_aes_xts_setkey(struct crypto_ablkcipher 
*tfm, const u8 *key,
  unsigned int key_len)
 {
struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm));
+   unsigned int ccpversion = ccp_version();
 
/* Only support 128-bit AES key with a 128-bit Tweak key,
 * otherwise use the fallback
 */
+
switch (key_len) {
case AES_KEYSIZE_128 * 2:
memcpy(ctx->u.aes.key, key, key_len);
break;
+   case AES_KEYSIZE_256 * 2:
+   if (ccpversion > CCP_VERSION(3, 0))
+   memcpy(ctx->u.aes.key, key, key_len);
+   break;
}
ctx->u.aes.key_len = key_len / 2;
sg_init_one(>u.aes.key_sg, ctx->u.aes.key, key_len);
@@ -117,7 +103,10 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
 {
struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
+   unsigned int ccpversion = ccp_version();
+   unsigned int fallback = 0;
unsigned int unit;
+   u32 block_size = 0;
u32 unit_size;
int ret;
 
@@ -131,17 +120,29 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request 
*req,
return -EINVAL;
 
unit_size = CCP_XTS_AES_UNIT_SIZE__LAST;
-   if (req->nbytes <= unit_size_map[0].size) {
-   for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++) {
-   if (!(req->nbytes & (unit_size_map[unit].size - 1))) {
-   unit_size = unit_size_map[unit].value;
-   break;
-   }
+   for (unit = ARRAY_SIZE(xts_unit_sizes); unit-- > 0; ) {
+   if (!(req->nbytes & (xts_unit_sizes[unit].size - 1))) {
+   unit_size = unit;
+   block_size = xts_unit_sizes[unit].size;
+   break;
}
}
 
-   if ((unit_size == CCP_XTS_AES_UNIT_SIZE__LAST) ||
-   (ctx->u.aes.key_len != AES_KEYSIZE_128)) {
+   /* The CCP has restrictions on block sizes. Also, a version 3 device
+* only supports AES-

[PATCH] crypto: ccp - Update copyright dates for 2017.

2017-07-17 Thread Gary R Hook
Some updates this year have not had copyright dates changed in modified
files. Correct this for 2017.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-galois.c |2 +-
 drivers/crypto/ccp/ccp-crypto-des3.c   |2 +-
 drivers/crypto/ccp/ccp-crypto-main.c   |2 +-
 drivers/crypto/ccp/ccp-crypto-sha.c|2 +-
 drivers/crypto/ccp/ccp-crypto.h|2 +-
 drivers/crypto/ccp/ccp-dev-v3.c|2 +-
 drivers/crypto/ccp/ccp-dev-v5.c|2 +-
 drivers/crypto/ccp/ccp-dev.c   |2 +-
 drivers/crypto/ccp/ccp-dev.h   |2 +-
 drivers/crypto/ccp/ccp-dmaengine.c |2 +-
 drivers/crypto/ccp/ccp-ops.c   |2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-galois.c 
b/drivers/crypto/ccp/ccp-crypto-aes-galois.c
index 38ee6f348ea9..52313524a4dd 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-galois.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-galois.c
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) AES GCM crypto API support
  *
- * Copyright (C) 2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2016,2017 Advanced Micro Devices, Inc.
  *
  * Author: Gary R Hook <gary.h...@amd.com>
  *
diff --git a/drivers/crypto/ccp/ccp-crypto-des3.c 
b/drivers/crypto/ccp/ccp-crypto-des3.c
index 5af7347ae03c..ae87b741f9d5 100644
--- a/drivers/crypto/ccp/ccp-crypto-des3.c
+++ b/drivers/crypto/ccp/ccp-crypto-des3.c
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) DES3 crypto API support
  *
- * Copyright (C) 2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2016,2017 Advanced Micro Devices, Inc.
  *
  * Author: Gary R Hook <gh...@amd.com>
  *
diff --git a/drivers/crypto/ccp/ccp-crypto-main.c 
b/drivers/crypto/ccp/ccp-crypto-main.c
index 8dccbddabef1..78b9d26a381f 100644
--- a/drivers/crypto/ccp/ccp-crypto-main.c
+++ b/drivers/crypto/ccp/ccp-crypto-main.c
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) crypto API support
  *
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
  * Author: Tom Lendacky <thomas.lenda...@amd.com>
  *
diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c 
b/drivers/crypto/ccp/ccp-crypto-sha.c
index ce97b3868f4a..8b9b16d433f7 100644
--- a/drivers/crypto/ccp/ccp-crypto-sha.c
+++ b/drivers/crypto/ccp/ccp-crypto-sha.c
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) SHA crypto API support
  *
- * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
  * Author: Tom Lendacky <thomas.lenda...@amd.com>
  * Author: Gary R Hook <gary.h...@amd.com>
diff --git a/drivers/crypto/ccp/ccp-crypto.h b/drivers/crypto/ccp/ccp-crypto.h
index dd5bf15f06e5..156b8233853f 100644
--- a/drivers/crypto/ccp/ccp-crypto.h
+++ b/drivers/crypto/ccp/ccp-crypto.h
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) crypto API support
  *
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
  * Author: Tom Lendacky <thomas.lenda...@amd.com>
  *
diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c
index 695fde887c11..c2861749e2ad 100644
--- a/drivers/crypto/ccp/ccp-dev-v3.c
+++ b/drivers/crypto/ccp/ccp-dev-v3.c
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) driver
  *
- * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
  * Author: Tom Lendacky <thomas.lenda...@amd.com>
  * Author: Gary R Hook <gary.h...@amd.com>
diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c
index b0391f03b0fe..b3526336d608 100644
--- a/drivers/crypto/ccp/ccp-dev-v5.c
+++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) driver
  *
- * Copyright (C) 2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2016,2017 Advanced Micro Devices, Inc.
  *
  * Author: Gary R Hook <gary.h...@amd.com>
  *
diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c
index b2d176164402..52eb3ed25a26 100644
--- a/drivers/crypto/ccp/ccp-dev.c
+++ b/drivers/crypto/ccp/ccp-dev.c
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) driver
  *
- * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
  * Author: Tom Lendacky <thomas.lenda...@amd.com>
  * Author: Gary R Hook <gary.h...@amd.com>
diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h
index b959e2402aa2..9320931d89da 100644
--- a/drivers/crypto/ccp/ccp-dev.h
+++ b/drivers/crypto/ccp/ccp-dev.h
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) driver
  *
- * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
 

Re: [PATCH v3 RESEND 5/5] crypto: ccp - remove ccp_present() check from device initialize

2017-07-03 Thread Gary R Hook

On 06/29/2017 11:54 AM, Singh, Brijesh wrote:

Since SP device driver supports multiples devices (e.g CCP, PSP), we
should not fail the driver init just because CCP device is not found.

Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
 drivers/crypto/ccp/sp-dev.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c
index edbf1bd9..a017233 100644
--- a/drivers/crypto/ccp/sp-dev.c
+++ b/drivers/crypto/ccp/sp-dev.c
@@ -244,12 +244,6 @@ static int __init sp_mod_init(void)
 if (ret)
 return ret;

-   /* Don't leave the driver loaded if init failed */
-   if (ccp_present() != 0) {
-   sp_pci_exit();
-   return -ENODEV;
-   }
-
 return 0;
 #endif

@@ -260,12 +254,6 @@ static int __init sp_mod_init(void)
 if (ret)
 return ret;

-   /* Don't leave the driver loaded if init failed */
-   if (ccp_present() != 0) {
-   sp_platform_exit();
-   return -ENODEV;
-   }
-
 return 0;
 #endif

--
2.9.4



Re: [PATCH v3 RESEND 4/5] crypto: ccp - rename ccp driver initialize files as sp device

2017-07-03 Thread Gary R Hook

On 06/29/2017 11:54 AM, Singh, Brijesh wrote:

CCP device initializes is now integerated into higher level SP device,
to avoid the confusion lets rename the ccp driver initialization files
(ccp-platform.c->sp-platform.c, ccp-pci.c->sp-pci.c). The patch does not
make any functional changes other than renaming file and structures

Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
 drivers/crypto/ccp/Makefile|  4 +-
 drivers/crypto/ccp/ccp-dev.h   |  6 --
 drivers/crypto/ccp/sp-dev.c| 12 ++--
 drivers/crypto/ccp/{ccp-pci.c => sp-pci.c} | 80
+++---
 .../crypto/ccp/{ccp-platform.c => sp-platform.c}   | 78
++---
 5 files changed, 87 insertions(+), 93 deletions(-)
 rename drivers/crypto/ccp/{ccp-pci.c => sp-pci.c} (71%)
 rename drivers/crypto/ccp/{ccp-platform.c => sp-platform.c} (66%)

diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index d2f1b52..5f2adc5 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -1,12 +1,12 @@
 obj-$(CONFIG_CRYPTO_DEV_CCP_DD) += ccp.o
-ccp-objs  := sp-dev.o ccp-platform.o
+ccp-objs  := sp-dev.o sp-platform.o
 ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \
 ccp-ops.o \
 ccp-dev-v3.o \
 ccp-dev-v5.o \
 ccp-dmaengine.o \
 ccp-debugfs.o
-ccp-$(CONFIG_PCI) += ccp-pci.o
+ccp-$(CONFIG_PCI) += sp-pci.o

 obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o
 ccp-crypto-objs := ccp-crypto-main.o \
diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h
index 193f309..b959e24 100644
--- a/drivers/crypto/ccp/ccp-dev.h
+++ b/drivers/crypto/ccp/ccp-dev.h
@@ -626,12 +626,6 @@ struct ccp5_desc {
 struct dword7 dw7;
 };

-int ccp_pci_init(void);
-void ccp_pci_exit(void);
-
-int ccp_platform_init(void);
-void ccp_platform_exit(void);
-
 void ccp_add_device(struct ccp_device *ccp);
 void ccp_del_device(struct ccp_device *ccp);

diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c
index 44e76e5..edbf1bd9 100644
--- a/drivers/crypto/ccp/sp-dev.c
+++ b/drivers/crypto/ccp/sp-dev.c
@@ -240,13 +240,13 @@ static int __init sp_mod_init(void)
 #ifdef CONFIG_X86
 int ret;

-   ret = ccp_pci_init();
+   ret = sp_pci_init();
 if (ret)
 return ret;

 /* Don't leave the driver loaded if init failed */
 if (ccp_present() != 0) {
-   ccp_pci_exit();
+   sp_pci_exit();
 return -ENODEV;
 }

@@ -256,13 +256,13 @@ static int __init sp_mod_init(void)
 #ifdef CONFIG_ARM64
 int ret;

-   ret = ccp_platform_init();
+   ret = sp_platform_init();
 if (ret)
 return ret;

 /* Don't leave the driver loaded if init failed */
 if (ccp_present() != 0) {
-   ccp_platform_exit();
+   sp_platform_exit();
 return -ENODEV;
 }

@@ -275,11 +275,11 @@ static int __init sp_mod_init(void)
 static void __exit sp_mod_exit(void)
 {
 #ifdef CONFIG_X86
-   ccp_pci_exit();
+   sp_pci_exit();
 #endif

 #ifdef CONFIG_ARM64
-   ccp_platform_exit();
+   sp_platform_exit();
 #endif
 }

diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/sp-pci.c
similarity index 71%
rename from drivers/crypto/ccp/ccp-pci.c
rename to drivers/crypto/ccp/sp-pci.c
index b29a093..9859aa6 100644
--- a/drivers/crypto/ccp/ccp-pci.c
+++ b/drivers/crypto/ccp/sp-pci.c
@@ -1,5 +1,5 @@
 /*
- * AMD Cryptographic Coprocessor (CCP) driver
+ * AMD Secure Processor device driver
  *
  * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
  *
@@ -28,35 +28,35 @@

 #define MSIX_VECTORS2

-struct ccp_pci {
+struct sp_pci {
 int msix_count;
 struct msix_entry msix_entry[MSIX_VECTORS];
 };

-static int ccp_get_msix_irqs(struct sp_device *sp)
+static int sp_get_msix_irqs(struct sp_device *sp)
 {
-   struct ccp_pci *ccp_pci = sp->dev_specific;
+   struct sp_pci *sp_pci = sp->dev_specific;
 struct device *dev = sp->dev;
 struct pci_dev *pdev = to_pci_dev(dev);
 int v, ret;

-   for (v = 0; v < ARRAY_SIZE(ccp_pci->msix_entry); v++)
-   ccp_pci->msix_entry[v].entry = v;
+   for (v = 0; v < ARRAY_SIZE(sp_pci->msix_entry); v++)
+   sp_pci->msix_entry[v].entry = v;

-   ret = pci_enable_msix_range(pdev, ccp_pci->msix_entry, 1, v);
+   ret = pci_enable_msix_range(pdev, sp_pci->msix_entry, 1, v);
 if (ret < 0)
 return ret;

-   ccp_pci->msix_count = ret;
+   sp_pci->msix_count = ret;
 sp->use_tasklet = true;

-   sp->psp_irq = ccp_pci->msix_entry[0].vector;
-   sp->ccp_irq = (ccp_pci->msix_count > 1) ?
ccp_pci->msix_e

Re: [PATCH v3 RESEND 2/5] crypto: ccp - Introduce the AMD Secure Processor device

2017-07-03 Thread Gary R Hook

On 06/29/2017 11:54 AM, Singh, Brijesh wrote:

The CCP device is part of the AMD Secure Processor. In order to expand
the usage of the AMD Secure Processor, create a framework that allows
functional components of the AMD Secure Processor to be initialized and
handled appropriately.

Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
 drivers/crypto/Kconfig|   6 +-
 drivers/crypto/ccp/Kconfig|  21 +++--
 drivers/crypto/ccp/Makefile   |   4 +-
 drivers/crypto/ccp/ccp-dev-v3.c   |   4 +-
 drivers/crypto/ccp/ccp-dev-v5.c   |   5 +-
 drivers/crypto/ccp/ccp-dev.c  | 106 +-
 drivers/crypto/ccp/ccp-dev.h  |  21 +
 drivers/crypto/ccp/ccp-pci.c  |  81 +++--
 drivers/crypto/ccp/ccp-platform.c |  70 ---
 drivers/crypto/ccp/sp-dev.c   | 180
++
 drivers/crypto/ccp/sp-dev.h   | 120 +
 include/linux/ccp.h   |   7 +-
 12 files changed, 461 insertions(+), 164 deletions(-)
 create mode 100644 drivers/crypto/ccp/sp-dev.c
 create mode 100644 drivers/crypto/ccp/sp-dev.h

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 0528a62..148b516 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -513,11 +513,11 @@ config CRYPTO_DEV_ATMEL_SHA
   will be called atmel-sha.

 config CRYPTO_DEV_CCP
-   bool "Support for AMD Cryptographic Coprocessor"
+   bool "Support for AMD Secure Processor"
 depends on ((X86 && PCI) || (ARM64 && (OF_ADDRESS || ACPI))) &&
HAS_IOMEM
 help
- The AMD Cryptographic Coprocessor provides hardware offload
support
- for encryption, hashing and related operations.
+ The AMD Secure Processor provides hardware offload support for
memory
+ encryption in virtualization and cryptographic hashing and
related operations.

 if CRYPTO_DEV_CCP
 source "drivers/crypto/ccp/Kconfig"
diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig
index 2238f77..15b63fd 100644
--- a/drivers/crypto/ccp/Kconfig
+++ b/drivers/crypto/ccp/Kconfig
@@ -1,22 +1,29 @@
 config CRYPTO_DEV_CCP_DD
-   tristate "Cryptographic Coprocessor device driver"
-   depends on CRYPTO_DEV_CCP
+   tristate "Secure Processor device driver"
 default m
+   help
+ Provides AMD Secure Processor device driver.
+ If you choose 'M' here, this module will be called ccp.
+
+config CRYPTO_DEV_SP_CCP
+   bool "Cryptographic Coprocessor device"
+   default y
+   depends on CRYPTO_DEV_CCP_DD
 select HW_RANDOM
 select DMA_ENGINE
 select DMADEVICES
 select CRYPTO_SHA1
 select CRYPTO_SHA256
 help
- Provides the interface to use the AMD Cryptographic Coprocessor
- which can be used to offload encryption operations such as SHA,
- AES and more. If you choose 'M' here, this module will be called
- ccp.
+ Provides the support for AMD Cryptographic Coprocessor (CCP)
device
+ which can be used to offload encryption operations such as
SHA, AES
+ and more.

 config CRYPTO_DEV_CCP_CRYPTO
 tristate "Encryption and hashing offload support"
-   depends on CRYPTO_DEV_CCP_DD
 default m
+   depends on CRYPTO_DEV_CCP_DD
+   depends on CRYPTO_DEV_SP_CCP
 select CRYPTO_HASH
 select CRYPTO_BLKCIPHER
 select CRYPTO_AUTHENC
diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 59493fd..d2f1b52 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -1,9 +1,9 @@
 obj-$(CONFIG_CRYPTO_DEV_CCP_DD) += ccp.o
-ccp-objs := ccp-dev.o \
+ccp-objs  := sp-dev.o ccp-platform.o
+ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \
 ccp-ops.o \
 ccp-dev-v3.o \
 ccp-dev-v5.o \
-   ccp-platform.o \
 ccp-dmaengine.o \
 ccp-debugfs.o
 ccp-$(CONFIG_PCI) += ccp-pci.o
diff --git a/drivers/crypto/ccp/ccp-dev-v3.c
b/drivers/crypto/ccp/ccp-dev-v3.c
index 52aa88b..57179034 100644
--- a/drivers/crypto/ccp/ccp-dev-v3.c
+++ b/drivers/crypto/ccp/ccp-dev-v3.c
@@ -359,8 +359,7 @@ static void ccp_irq_bh(unsigned long data)

 static irqreturn_t ccp_irq_handler(int irq, void *data)
 {
-   struct device *dev = data;
-   struct ccp_device *ccp = dev_get_drvdata(dev);
+   struct ccp_device *ccp = (struct ccp_device *)data;

 ccp_disable_queue_interrupts(ccp);
 if (ccp->use_tasklet)
@@ -597,6 +596,5 @@ const struct ccp_vdata ccpv3 = {
 .version = CCP_VERSION(3, 0),
 .setup = NULL,
 .perform = _actions,
-   .bar = 2,
 .offset = 0x2,
 };
diff --git a/drivers/crypto/ccp/ccp-dev-v5.c
b/drivers/crypto/ccp/ccp-dev-v5.c
index b10d2d2

Re: [PATCH v3 RESEND 3/5] crypto: cpp - Abstract interrupt registeration

2017-07-03 Thread Gary R Hook

On 06/29/2017 11:54 AM, Singh, Brijesh wrote:

The CCP and PSP devices part of AMD Secure Procesor may share the same
interrupt. Hence we expand the SP device to register a common interrupt
handler and provide functions to CCP and PSP devices to register their
interrupt callback which will be invoked upon interrupt.

Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
 drivers/crypto/ccp/ccp-dev-v3.c   |   6 +--
 drivers/crypto/ccp/ccp-dev-v5.c   |   7 ++-
 drivers/crypto/ccp/ccp-dev.c  |   3 +-
 drivers/crypto/ccp/ccp-dev.h  |   2 -
 drivers/crypto/ccp/ccp-pci.c  | 103
+++-
 drivers/crypto/ccp/ccp-platform.c |  57 ++--
 drivers/crypto/ccp/sp-dev.c   | 107
++
 drivers/crypto/ccp/sp-dev.h   |  16 +-
 8 files changed, 186 insertions(+), 115 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-dev-v3.c
b/drivers/crypto/ccp/ccp-dev-v3.c
index 57179034..695fde8 100644
--- a/drivers/crypto/ccp/ccp-dev-v3.c
+++ b/drivers/crypto/ccp/ccp-dev-v3.c
@@ -453,7 +453,7 @@ static int ccp_init(struct ccp_device *ccp)
 iowrite32(ccp->qim, ccp->io_regs + IRQ_STATUS_REG);

 /* Request an irq */
-   ret = ccp->get_irq(ccp);
+   ret = sp_request_ccp_irq(ccp->sp, ccp_irq_handler, ccp->name, ccp);
 if (ret) {
 dev_err(dev, "unable to allocate an IRQ\n");
 goto e_pool;
@@ -510,7 +510,7 @@ static int ccp_init(struct ccp_device *ccp)
 if (ccp->cmd_q[i].kthread)
 kthread_stop(ccp->cmd_q[i].kthread);

-   ccp->free_irq(ccp);
+   sp_free_ccp_irq(ccp->sp, ccp);

 e_pool:
 for (i = 0; i < ccp->cmd_q_count; i++)
@@ -549,7 +549,7 @@ static void ccp_destroy(struct ccp_device *ccp)
 if (ccp->cmd_q[i].kthread)
 kthread_stop(ccp->cmd_q[i].kthread);

-   ccp->free_irq(ccp);
+   sp_free_ccp_irq(ccp->sp, ccp);

 for (i = 0; i < ccp->cmd_q_count; i++)
 dma_pool_destroy(ccp->cmd_q[i].dma_pool);
diff --git a/drivers/crypto/ccp/ccp-dev-v5.c
b/drivers/crypto/ccp/ccp-dev-v5.c
index 8ed2b37..b0391f0 100644
--- a/drivers/crypto/ccp/ccp-dev-v5.c
+++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -880,7 +880,7 @@ static int ccp5_init(struct ccp_device *ccp)

 dev_dbg(dev, "Requesting an IRQ...\n");
 /* Request an irq */
-   ret = ccp->get_irq(ccp);
+   ret = sp_request_ccp_irq(ccp->sp, ccp5_irq_handler, ccp->name, ccp);
 if (ret) {
 dev_err(dev, "unable to allocate an IRQ\n");
 goto e_pool;
@@ -986,7 +986,7 @@ static int ccp5_init(struct ccp_device *ccp)
 kthread_stop(ccp->cmd_q[i].kthread);

 e_irq:
-   ccp->free_irq(ccp);
+   sp_free_ccp_irq(ccp->sp, ccp);

 e_pool:
 for (i = 0; i < ccp->cmd_q_count; i++)
@@ -1036,7 +1036,7 @@ static void ccp5_destroy(struct ccp_device *ccp)
 if (ccp->cmd_q[i].kthread)
 kthread_stop(ccp->cmd_q[i].kthread);

-   ccp->free_irq(ccp);
+   sp_free_ccp_irq(ccp->sp, ccp);

 for (i = 0; i < ccp->cmd_q_count; i++) {
 cmd_q = >cmd_q[i];
@@ -1105,7 +1105,6 @@ static const struct ccp_actions ccp5_actions = {
 .init = ccp5_init,
 .destroy = ccp5_destroy,
 .get_free_slots = ccp5_get_free_slots,
-   .irqhandler = ccp5_irq_handler,
 };

 const struct ccp_vdata ccpv5a = {
diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c
index 8a1674a..7c751bf 100644
--- a/drivers/crypto/ccp/ccp-dev.c
+++ b/drivers/crypto/ccp/ccp-dev.c
@@ -599,8 +599,7 @@ int ccp_dev_init(struct sp_device *sp)
 goto e_err;
 }

-   ccp->get_irq = sp->get_irq;
-   ccp->free_irq = sp->free_irq;
+   ccp->use_tasklet = sp->use_tasklet;

 ccp->io_regs = sp->io_map + ccp->vdata->offset;
 if (ccp->vdata->setup)
diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h
index ca44821..193f309 100644
--- a/drivers/crypto/ccp/ccp-dev.h
+++ b/drivers/crypto/ccp/ccp-dev.h
@@ -351,8 +351,6 @@ struct ccp_device {
 /* Bus specific device information
  */
 void *dev_specific;
-   int (*get_irq)(struct ccp_device *ccp);
-   void (*free_irq)(struct ccp_device *ccp);
 unsigned int qim;
 unsigned int irq;
 bool use_tasklet;
diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c
index ab2df96..b29a093 100644
--- a/drivers/crypto/ccp/ccp-pci.c
+++ b/drivers/crypto/ccp/ccp-pci.c
@@ -28,67 +28,37 @@

 #define MSIX_VECTORS2

-struct ccp_msix {
-   u32 vector;
-   char name[16];
-};
-
 struct ccp_pc

Re: [PATCH v3 RESEND 1/5] crypto: ccp - Use devres interface to allocate PCI/iomap and cleanup

2017-07-03 Thread Gary R Hook

On 06/29/2017 11:54 AM, Singh, Brijesh wrote:

Update pci and platform files to use devres interface to allocate the PCI
and iomap resources. Also add helper functions to consolicate module init,
exit and power mangagement code duplication.

Signed-off-by: Brijesh Singh <brijesh.si...@amd.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
 drivers/crypto/ccp/ccp-dev-v3.c   |   7 +++
 drivers/crypto/ccp/ccp-dev.c  |  61 
 drivers/crypto/ccp/ccp-dev.h  |   6 ++
 drivers/crypto/ccp/ccp-pci.c  | 114
+-
 drivers/crypto/ccp/ccp-platform.c |  56 ++-
 5 files changed, 106 insertions(+), 138 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-dev-v3.c
b/drivers/crypto/ccp/ccp-dev-v3.c
index 367c2e3..52aa88b 100644
--- a/drivers/crypto/ccp/ccp-dev-v3.c
+++ b/drivers/crypto/ccp/ccp-dev-v3.c
@@ -586,6 +586,13 @@ static const struct ccp_actions ccp3_actions = {
 .irqhandler = ccp_irq_handler,
 };

+const struct ccp_vdata ccpv3_platform = {
+   .version = CCP_VERSION(3, 0),
+   .setup = NULL,
+   .perform = _actions,
+   .offset = 0,
+};
+
 const struct ccp_vdata ccpv3 = {
 .version = CCP_VERSION(3, 0),
 .setup = NULL,
diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c
index 2506b50..abb3d68 100644
--- a/drivers/crypto/ccp/ccp-dev.c
+++ b/drivers/crypto/ccp/ccp-dev.c
@@ -538,8 +538,69 @@ bool ccp_queues_suspended(struct ccp_device *ccp)

 return ccp->cmd_q_count == suspended;
 }
+
+int ccp_dev_suspend(struct ccp_device *ccp, pm_message_t state)
+{
+   unsigned long flags;
+   unsigned int i;
+
+   spin_lock_irqsave(>cmd_lock, flags);
+
+   ccp->suspending = 1;
+
+   /* Wake all the queue kthreads to prepare for suspend */
+   for (i = 0; i < ccp->cmd_q_count; i++)
+   wake_up_process(ccp->cmd_q[i].kthread);
+
+   spin_unlock_irqrestore(>cmd_lock, flags);
+
+   /* Wait for all queue kthreads to say they're done */
+   while (!ccp_queues_suspended(ccp))
+   wait_event_interruptible(ccp->suspend_queue,
+ccp_queues_suspended(ccp));
+
+   return 0;
+}
+
+int ccp_dev_resume(struct ccp_device *ccp)
+{
+   unsigned long flags;
+   unsigned int i;
+
+   spin_lock_irqsave(>cmd_lock, flags);
+
+   ccp->suspending = 0;
+
+   /* Wake up all the kthreads */
+   for (i = 0; i < ccp->cmd_q_count; i++) {
+   ccp->cmd_q[i].suspended = 0;
+   wake_up_process(ccp->cmd_q[i].kthread);
+   }
+
+   spin_unlock_irqrestore(>cmd_lock, flags);
+
+   return 0;
+}
 #endif

+int ccp_dev_init(struct ccp_device *ccp)
+{
+   ccp->io_regs = ccp->io_map + ccp->vdata->offset;
+
+   if (ccp->vdata->setup)
+   ccp->vdata->setup(ccp);
+
+   return ccp->vdata->perform->init(ccp);
+}
+
+void ccp_dev_destroy(struct ccp_device *ccp)
+{
+   if (!ccp)
+   return;
+
+   ccp->vdata->perform->destroy(ccp);
+}
+
 static int __init ccp_mod_init(void)
 {
 #ifdef CONFIG_X86
diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h
index a70154a..df2e76e 100644
--- a/drivers/crypto/ccp/ccp-dev.h
+++ b/drivers/crypto/ccp/ccp-dev.h
@@ -652,6 +652,11 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp);
 void ccp5_debugfs_setup(struct ccp_device *ccp);
 void ccp5_debugfs_destroy(void);

+int ccp_dev_init(struct ccp_device *ccp);
+void ccp_dev_destroy(struct ccp_device *ccp);
+int ccp_dev_suspend(struct ccp_device *ccp, pm_message_t state);
+int ccp_dev_resume(struct ccp_device *ccp);
+
 /* Structure for computation functions that are device-specific */
 struct ccp_actions {
 int (*aes)(struct ccp_op *);
@@ -679,6 +684,7 @@ struct ccp_vdata {
 const unsigned int offset;
 };

+extern const struct ccp_vdata ccpv3_platform;
 extern const struct ccp_vdata ccpv3;
 extern const struct ccp_vdata ccpv5a;
 extern const struct ccp_vdata ccpv5b;
diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c
index e880d4cf4..490ad0a 100644
--- a/drivers/crypto/ccp/ccp-pci.c
+++ b/drivers/crypto/ccp/ccp-pci.c
@@ -150,28 +150,13 @@ static void ccp_free_irqs(struct ccp_device *ccp)
 ccp->irq = 0;
 }

-static int ccp_find_mmio_area(struct ccp_device *ccp)
-{
-   struct device *dev = ccp->dev;
-   struct pci_dev *pdev = to_pci_dev(dev);
-   resource_size_t io_len;
-   unsigned long io_flags;
-
-   io_flags = pci_resource_flags(pdev, ccp->vdata->bar);
-   io_len = pci_resource_len(pdev, ccp->vdata->bar);
-   if ((io_flags & IORESOURCE_MEM) &&
-   (io_len >= (ccp->vdata->offset + 0x800)))
-   return ccp->vdata->bar;
-
-   return -EIO;
-}
-
 static int ccp_pci_probe(struct pci_dev

Re: [PATCH] crypto: ccp-platform: print error message on platform_get_irq failure

2017-06-30 Thread Gary R Hook

On 06/30/2017 12:59 AM, Gustavo A. R. Silva wrote:

Print error message on platform_get_irq failure before return.

Signed-off-by: Gustavo A. R. Silva 
---
 drivers/crypto/ccp/ccp-platform.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/ccp-platform.c
b/drivers/crypto/ccp/ccp-platform.c
index e26969e..6020c4a 100644
--- a/drivers/crypto/ccp/ccp-platform.c
+++ b/drivers/crypto/ccp/ccp-platform.c
@@ -66,8 +66,10 @@ static int ccp_get_irq(struct ccp_device *ccp)
 int ret;

 ret = platform_get_irq(pdev, 0);
-   if (ret < 0)
+   if (ret < 0) {
+   dev_notice(dev, "unable to get IRQ (%d)\n", ret);
 return ret;
+   }


Good find.

I'm all for better and more messages, but I'd like to see more detail 
here, and in the
later dev_notice(). Can we have the messages better reflect the failure 
points?




 ccp->irq = ret;
 ret = request_irq(ccp->irq, ccp->vdata->perform->irqhandler, 0,
--
2.5.0



[PATCH v3] crypto: ccp - Provide an error path for debugfs setup failure

2017-06-28 Thread Gary R Hook
Changes since v2:
  - On failure remove only the DebugFS heirarchy for this device 
Changes since v1:
  - Remove unneeded local variable

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-debugfs.c |   15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-debugfs.c b/drivers/crypto/ccp/ccp-debugfs.c
index 3cd6c83754e0..59d4ca4e72d8 100644
--- a/drivers/crypto/ccp/ccp-debugfs.c
+++ b/drivers/crypto/ccp/ccp-debugfs.c
@@ -305,19 +305,19 @@ void ccp5_debugfs_setup(struct ccp_device *ccp)
 
ccp->debugfs_instance = debugfs_create_dir(ccp->name, ccp_debugfs_dir);
if (!ccp->debugfs_instance)
-   return;
+   goto err;
 
debugfs_info = debugfs_create_file("info", 0400,
   ccp->debugfs_instance, ccp,
   _debugfs_info_ops);
if (!debugfs_info)
-   return;
+   goto err;
 
debugfs_stats = debugfs_create_file("stats", 0600,
ccp->debugfs_instance, ccp,
_debugfs_stats_ops);
if (!debugfs_stats)
-   return;
+   goto err;
 
for (i = 0; i < ccp->cmd_q_count; i++) {
cmd_q = >cmd_q[i];
@@ -327,15 +327,20 @@ void ccp5_debugfs_setup(struct ccp_device *ccp)
debugfs_q_instance =
debugfs_create_dir(name, ccp->debugfs_instance);
if (!debugfs_q_instance)
-   return;
+   goto err;
 
debugfs_q_stats =
debugfs_create_file("stats", 0600,
debugfs_q_instance, cmd_q,
_debugfs_queue_ops);
if (!debugfs_q_stats)
-   return;
+   goto err;
}
+
+   return;
+
+err:
+   debugfs_remove_recursive(ccp->debugfs_instance);
 }
 
 void ccp5_debugfs_destroy(void)



Re: [PATCH 2] crypto: ccp - Provide a roll-back method for debugfs setup

2017-06-27 Thread Gary R Hook

On 06/27/2017 08:57 AM, Hook, Gary wrote:

Changes since v1:
 - Remove unneeded local variable


My apologies for this patch... Pretty sure that the first version won't pass
review anyway because of this.



Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-debugfs.c |   17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-debugfs.c
b/drivers/crypto/ccp/ccp-debugfs.c
index 3cd6c83754e0..88191c45ca7d 100644
--- a/drivers/crypto/ccp/ccp-debugfs.c
+++ b/drivers/crypto/ccp/ccp-debugfs.c
@@ -305,19 +305,19 @@ void ccp5_debugfs_setup(struct ccp_device *ccp)

 ccp->debugfs_instance = debugfs_create_dir(ccp->name,
ccp_debugfs_dir);
 if (!ccp->debugfs_instance)
-   return;
+   goto err;

 debugfs_info = debugfs_create_file("info", 0400,
ccp->debugfs_instance, ccp,
_debugfs_info_ops);
 if (!debugfs_info)
-   return;
+   goto err;

 debugfs_stats = debugfs_create_file("stats", 0600,
 ccp->debugfs_instance, ccp,
 _debugfs_stats_ops);
 if (!debugfs_stats)
-   return;
+   goto err;

 for (i = 0; i < ccp->cmd_q_count; i++) {
 cmd_q = >cmd_q[i];
@@ -327,15 +327,22 @@ void ccp5_debugfs_setup(struct ccp_device *ccp)
 debugfs_q_instance =
 debugfs_create_dir(name, ccp->debugfs_instance);
 if (!debugfs_q_instance)
-   return;
+   goto err;

 debugfs_q_stats =
 debugfs_create_file("stats", 0600,
 debugfs_q_instance, cmd_q,
 _debugfs_queue_ops);
 if (!debugfs_q_stats)
-   return;
+   goto err;
 }
+   return;
+
+err:
+   write_lock_irqsave(_debugfs_lock, flags);
+   debugfs_remove_recursive(ccp_debugfs_dir);
+   ccp_debugfs_dir = NULL;
+   write_unlock_irqrestore(_debugfs_lock, flags);
 }

 void ccp5_debugfs_destroy(void)



[PATCH] crypto: ccp - Change all references to use the JOB ID macro

2017-06-27 Thread Gary R Hook
Use the CCP_NEW_JOBID() macro when assigning an identifier

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-ops.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index c0dfdacbdff5..78f29d459df8 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1756,7 +1756,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
 
memset(, 0, sizeof(op));
op.cmd_q = cmd_q;
-   op.jobid = ccp_gen_jobid(cmd_q->ccp);
+   op.jobid = CCP_NEW_JOBID(cmd_q->ccp);
op.sb_key = cmd_q->ccp->vdata->perform->sballoc(cmd_q, sb_count);
 
if (!op.sb_key)
@@ -1992,7 +1992,7 @@ static int ccp_run_passthru_nomap_cmd(struct 
ccp_cmd_queue *cmd_q,
 
memset(, 0, sizeof(op));
op.cmd_q = cmd_q;
-   op.jobid = ccp_gen_jobid(cmd_q->ccp);
+   op.jobid = CCP_NEW_JOBID(cmd_q->ccp);
 
if (pt->bit_mod != CCP_PASSTHRU_BITWISE_NOOP) {
/* Load the mask */



[PATCH] crypto: ccp - Fix some line spacing

2017-06-27 Thread Gary R Hook
Add/remove blank lines as appropriate.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-dev.c |1 +
 include/linux/ccp.h  |1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c
index 2506b5025700..67cbb3e76888 100644
--- a/drivers/crypto/ccp/ccp-dev.c
+++ b/drivers/crypto/ccp/ccp-dev.c
@@ -415,6 +415,7 @@ static void ccp_do_cmd_complete(unsigned long data)
struct ccp_cmd *cmd = tdata->cmd;
 
cmd->callback(cmd->data, cmd->ret);
+
complete(>completion);
 }
 
diff --git a/include/linux/ccp.h b/include/linux/ccp.h
index 3285c944194a..c03ee844a99d 100644
--- a/include/linux/ccp.h
+++ b/include/linux/ccp.h
@@ -20,7 +20,6 @@
 #include 
 #include 
 
-
 struct ccp_device;
 struct ccp_cmd;
 



[PATCH 2] crypto: ccp - Provide a roll-back method for debugfs setup

2017-06-27 Thread Gary R Hook
Changes since v1:
 - Remove unneeded local variable

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-debugfs.c |   17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-debugfs.c b/drivers/crypto/ccp/ccp-debugfs.c
index 3cd6c83754e0..88191c45ca7d 100644
--- a/drivers/crypto/ccp/ccp-debugfs.c
+++ b/drivers/crypto/ccp/ccp-debugfs.c
@@ -305,19 +305,19 @@ void ccp5_debugfs_setup(struct ccp_device *ccp)
 
ccp->debugfs_instance = debugfs_create_dir(ccp->name, ccp_debugfs_dir);
if (!ccp->debugfs_instance)
-   return;
+   goto err;
 
debugfs_info = debugfs_create_file("info", 0400,
   ccp->debugfs_instance, ccp,
   _debugfs_info_ops);
if (!debugfs_info)
-   return;
+   goto err;
 
debugfs_stats = debugfs_create_file("stats", 0600,
ccp->debugfs_instance, ccp,
_debugfs_stats_ops);
if (!debugfs_stats)
-   return;
+   goto err;
 
for (i = 0; i < ccp->cmd_q_count; i++) {
cmd_q = >cmd_q[i];
@@ -327,15 +327,22 @@ void ccp5_debugfs_setup(struct ccp_device *ccp)
debugfs_q_instance =
debugfs_create_dir(name, ccp->debugfs_instance);
if (!debugfs_q_instance)
-   return;
+   goto err;
 
debugfs_q_stats =
debugfs_create_file("stats", 0600,
debugfs_q_instance, cmd_q,
_debugfs_queue_ops);
if (!debugfs_q_stats)
-   return;
+   goto err;
}
+   return;
+
+err:
+   write_lock_irqsave(_debugfs_lock, flags);
+   debugfs_remove_recursive(ccp_debugfs_dir);
+   ccp_debugfs_dir = NULL;
+   write_unlock_irqrestore(_debugfs_lock, flags);
 }
 
 void ccp5_debugfs_destroy(void)



Re: [PATCH 3/4] crypto: ccp - Add support for RSA on the CCP

2017-06-22 Thread Gary R Hook

On 06/22/2017 12:15 AM, Stephan Müller wrote:

Am Donnerstag, 22. Juni 2017, 00:48:01 CEST schrieb Gary R Hook:

Hi Gary,


Thanks, Stephen. Good catch(es). I will re-work this, but it looks like 
my changes should wait
until after the patch set posted by Brijesh (Introduce AMD Secure 
Processor device).


Please ignore these for now.





Wire up the v3 CCP as a cipher provider.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/Makefile  |1
 drivers/crypto/ccp/ccp-crypto-main.c |   21 ++
 drivers/crypto/ccp/ccp-crypto-rsa.c  |  286
++ drivers/crypto/ccp/ccp-crypto.h  |
31 
 drivers/crypto/ccp/ccp-debugfs.c |1
 drivers/crypto/ccp/ccp-dev.c |1
 drivers/crypto/ccp/ccp-ops.c |2
 include/linux/ccp.h  |1
 8 files changed, 341 insertions(+), 3 deletions(-)
 create mode 100644 drivers/crypto/ccp/ccp-crypto-rsa.c

diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 59493fd3a751..439bc2fcb464 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -15,4 +15,5 @@ ccp-crypto-objs := ccp-crypto-main.o \
  ccp-crypto-aes-xts.o \
  ccp-crypto-aes-galois.o \
  ccp-crypto-des3.o \
+ccp-crypto-rsa.o \
  ccp-crypto-sha.o
diff --git a/drivers/crypto/ccp/ccp-crypto-main.c
b/drivers/crypto/ccp/ccp-crypto-main.c index 8dccbddabef1..dd7d00c680e7
100644
--- a/drivers/crypto/ccp/ccp-crypto-main.c
+++ b/drivers/crypto/ccp/ccp-crypto-main.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "ccp-crypto.h"

@@ -37,10 +38,15 @@
 module_param(des3_disable, uint, 0444);
 MODULE_PARM_DESC(des3_disable, "Disable use of 3DES - any non-zero value");

+static unsigned int rsa_disable;
+module_param(rsa_disable, uint, 0444);
+MODULE_PARM_DESC(rsa_disable, "Disable use of RSA - any non-zero value");
+
 /* List heads for the supported algorithms */
 static LIST_HEAD(hash_algs);
 static LIST_HEAD(cipher_algs);
 static LIST_HEAD(aead_algs);
+static LIST_HEAD(akcipher_algs);

 /* For any tfm, requests for that tfm must be returned on the order
  * received.  With multiple queues available, the CCP can process more
@@ -358,6 +364,14 @@ static int ccp_register_algs(void)
   return ret;
   }

+ if (!rsa_disable) {
+ ret = ccp_register_rsa_algs(_algs);
+ if (ret) {
+ rsa_disable = 1;
+ return ret;
+ }
+ }
+
   return 0;
 }

@@ -366,6 +380,7 @@ static void ccp_unregister_algs(void)
   struct ccp_crypto_ahash_alg *ahash_alg, *ahash_tmp;
   struct ccp_crypto_ablkcipher_alg *ablk_alg, *ablk_tmp;
   struct ccp_crypto_aead *aead_alg, *aead_tmp;
+ struct ccp_crypto_akcipher_alg *akc_alg, *akc_tmp;

   list_for_each_entry_safe(ahash_alg, ahash_tmp, _algs, entry) {
   crypto_unregister_ahash(_alg->alg);
@@ -384,6 +399,12 @@ static void ccp_unregister_algs(void)
   list_del(_alg->entry);
   kfree(aead_alg);
   }
+
+ list_for_each_entry_safe(akc_alg, akc_tmp, _algs, entry) {
+ crypto_unregister_akcipher(_alg->alg);
+ list_del(_alg->entry);
+ kfree(akc_alg);
+ }
 }

 static int ccp_crypto_init(void)
diff --git a/drivers/crypto/ccp/ccp-crypto-rsa.c
b/drivers/crypto/ccp/ccp-crypto-rsa.c new file mode 100644
index ..4a2a71463594
--- /dev/null
+++ b/drivers/crypto/ccp/ccp-crypto-rsa.c
@@ -0,0 +1,286 @@
+/*
+ * AMD Cryptographic Coprocessor (CCP) RSA crypto API support
+ *
+ * Copyright (C) 2016 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ccp-crypto.h"
+
+static inline struct akcipher_request *akcipher_request_cast(
+ struct crypto_async_request *req)
+{
+ return container_of(req, struct akcipher_request, base);
+}
+
+static int ccp_rsa_complete(struct crypto_async_request *async_req, int
ret) +{
+ struct akcipher_request *req = akcipher_request_cast(async_req);
+ struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx(req);
+
+ if (!ret)
+ req->dst_len = rctx->cmd.u.rsa.key_size >> 3;
+
+ ret = 0;
+
+ return ret;
+}
+
+static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)
+{
+ return CCP_RSA_MAXMOD;
+}
+
+static int ccp_rsa_crypt(struct akcipher_request *req, bool encrypt)
+{
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+ struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
+

[PATCH 4/4] crypto: ccp - Expand RSA support for a v5 ccp

2017-06-21 Thread Gary R Hook
A V5 device can accommodate larger keys, as well as read the keys
directly from memory instead of requiring them to be in a local
storage block.


Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-rsa.c |5 -
 drivers/crypto/ccp/ccp-crypto.h |1 +
 drivers/crypto/ccp/ccp-dev-v3.c |1 +
 drivers/crypto/ccp/ccp-dev-v5.c |2 ++
 drivers/crypto/ccp/ccp-dev.h|2 ++
 drivers/crypto/ccp/ccp-ops.c|3 ++-
 6 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-rsa.c 
b/drivers/crypto/ccp/ccp-crypto-rsa.c
index 4a2a71463594..93e6b00ce34d 100644
--- a/drivers/crypto/ccp/ccp-crypto-rsa.c
+++ b/drivers/crypto/ccp/ccp-crypto-rsa.c
@@ -43,7 +43,10 @@ static int ccp_rsa_complete(struct crypto_async_request 
*async_req, int ret)
 
 static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)
 {
-   return CCP_RSA_MAXMOD;
+   if (ccp_version() > CCP_VERSION(3, 0))
+   return CCP5_RSA_MAXMOD;
+   else
+   return CCP_RSA_MAXMOD;
 }
 
 static int ccp_rsa_crypt(struct akcipher_request *req, bool encrypt)
diff --git a/drivers/crypto/ccp/ccp-crypto.h b/drivers/crypto/ccp/ccp-crypto.h
index 5d592ecc9af5..40598894113b 100644
--- a/drivers/crypto/ccp/ccp-crypto.h
+++ b/drivers/crypto/ccp/ccp-crypto.h
@@ -255,6 +255,7 @@ struct ccp_rsa_req_ctx {
 };
 
 #defineCCP_RSA_MAXMOD  (4 * 1024 / 8)
+#defineCCP5_RSA_MAXMOD (16 * 1024 / 8)
 
 /* Common Context Structure */
 struct ccp_ctx {
diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c
index 367c2e30656f..9b159b0a891e 100644
--- a/drivers/crypto/ccp/ccp-dev-v3.c
+++ b/drivers/crypto/ccp/ccp-dev-v3.c
@@ -592,4 +592,5 @@ static void ccp_destroy(struct ccp_device *ccp)
.perform = _actions,
.bar = 2,
.offset = 0x2,
+   .rsamax = CCP_RSA_MAX_WIDTH,
 };
diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c
index 632518efd685..6043552322fd 100644
--- a/drivers/crypto/ccp/ccp-dev-v5.c
+++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -1115,6 +1115,7 @@ static void ccp5other_config(struct ccp_device *ccp)
.perform = _actions,
.bar = 2,
.offset = 0x0,
+   .rsamax = CCP5_RSA_MAX_WIDTH,
 };
 
 const struct ccp_vdata ccpv5b = {
@@ -1124,4 +1125,5 @@ static void ccp5other_config(struct ccp_device *ccp)
.perform = _actions,
.bar = 2,
.offset = 0x0,
+   .rsamax = CCP5_RSA_MAX_WIDTH,
 };
diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h
index a70154ac7405..8242cf54d90f 100644
--- a/drivers/crypto/ccp/ccp-dev.h
+++ b/drivers/crypto/ccp/ccp-dev.h
@@ -200,6 +200,7 @@
 #define CCP_SHA_SB_COUNT   1
 
 #define CCP_RSA_MAX_WIDTH  4096
+#define CCP5_RSA_MAX_WIDTH 16384
 
 #define CCP_PASSTHRU_BLOCKSIZE 256
 #define CCP_PASSTHRU_MASKSIZE  32
@@ -677,6 +678,7 @@ struct ccp_vdata {
const struct ccp_actions *perform;
const unsigned int bar;
const unsigned int offset;
+   const unsigned int rsamax;
 };
 
 extern const struct ccp_vdata ccpv3;
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 2cdd15a92178..ea5e4ede1eed 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1737,7 +1737,8 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
unsigned int key_size_bytes;
int ret;
 
-   if (rsa->key_size > CCP_RSA_MAX_WIDTH)
+   /* Check against the maximum allowable size, in bits */
+   if (rsa->key_size > cmd_q->ccp->vdata->rsamax)
return -EINVAL;
 
if (!rsa->exp || !rsa->mod || !rsa->src || !rsa->dst)



[PATCH 3/4] crypto: ccp - Add support for RSA on the CCP

2017-06-21 Thread Gary R Hook
Wire up the v3 CCP as a cipher provider.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/Makefile  |1 
 drivers/crypto/ccp/ccp-crypto-main.c |   21 ++
 drivers/crypto/ccp/ccp-crypto-rsa.c  |  286 ++
 drivers/crypto/ccp/ccp-crypto.h  |   31 
 drivers/crypto/ccp/ccp-debugfs.c |1 
 drivers/crypto/ccp/ccp-dev.c |1 
 drivers/crypto/ccp/ccp-ops.c |2 
 include/linux/ccp.h  |1 
 8 files changed, 341 insertions(+), 3 deletions(-)
 create mode 100644 drivers/crypto/ccp/ccp-crypto-rsa.c

diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 59493fd3a751..439bc2fcb464 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -15,4 +15,5 @@ ccp-crypto-objs := ccp-crypto-main.o \
   ccp-crypto-aes-xts.o \
   ccp-crypto-aes-galois.o \
   ccp-crypto-des3.o \
+  ccp-crypto-rsa.o \
   ccp-crypto-sha.o
diff --git a/drivers/crypto/ccp/ccp-crypto-main.c 
b/drivers/crypto/ccp/ccp-crypto-main.c
index 8dccbddabef1..dd7d00c680e7 100644
--- a/drivers/crypto/ccp/ccp-crypto-main.c
+++ b/drivers/crypto/ccp/ccp-crypto-main.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "ccp-crypto.h"
 
@@ -37,10 +38,15 @@
 module_param(des3_disable, uint, 0444);
 MODULE_PARM_DESC(des3_disable, "Disable use of 3DES - any non-zero value");
 
+static unsigned int rsa_disable;
+module_param(rsa_disable, uint, 0444);
+MODULE_PARM_DESC(rsa_disable, "Disable use of RSA - any non-zero value");
+
 /* List heads for the supported algorithms */
 static LIST_HEAD(hash_algs);
 static LIST_HEAD(cipher_algs);
 static LIST_HEAD(aead_algs);
+static LIST_HEAD(akcipher_algs);
 
 /* For any tfm, requests for that tfm must be returned on the order
  * received.  With multiple queues available, the CCP can process more
@@ -358,6 +364,14 @@ static int ccp_register_algs(void)
return ret;
}
 
+   if (!rsa_disable) {
+   ret = ccp_register_rsa_algs(_algs);
+   if (ret) {
+   rsa_disable = 1;
+   return ret;
+   }
+   }
+
return 0;
 }
 
@@ -366,6 +380,7 @@ static void ccp_unregister_algs(void)
struct ccp_crypto_ahash_alg *ahash_alg, *ahash_tmp;
struct ccp_crypto_ablkcipher_alg *ablk_alg, *ablk_tmp;
struct ccp_crypto_aead *aead_alg, *aead_tmp;
+   struct ccp_crypto_akcipher_alg *akc_alg, *akc_tmp;
 
list_for_each_entry_safe(ahash_alg, ahash_tmp, _algs, entry) {
crypto_unregister_ahash(_alg->alg);
@@ -384,6 +399,12 @@ static void ccp_unregister_algs(void)
list_del(_alg->entry);
kfree(aead_alg);
}
+
+   list_for_each_entry_safe(akc_alg, akc_tmp, _algs, entry) {
+   crypto_unregister_akcipher(_alg->alg);
+   list_del(_alg->entry);
+   kfree(akc_alg);
+   }
 }
 
 static int ccp_crypto_init(void)
diff --git a/drivers/crypto/ccp/ccp-crypto-rsa.c 
b/drivers/crypto/ccp/ccp-crypto-rsa.c
new file mode 100644
index ..4a2a71463594
--- /dev/null
+++ b/drivers/crypto/ccp/ccp-crypto-rsa.c
@@ -0,0 +1,286 @@
+/*
+ * AMD Cryptographic Coprocessor (CCP) RSA crypto API support
+ *
+ * Copyright (C) 2016 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ccp-crypto.h"
+
+static inline struct akcipher_request *akcipher_request_cast(
+   struct crypto_async_request *req)
+{
+   return container_of(req, struct akcipher_request, base);
+}
+
+static int ccp_rsa_complete(struct crypto_async_request *async_req, int ret)
+{
+   struct akcipher_request *req = akcipher_request_cast(async_req);
+   struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx(req);
+
+   if (!ret)
+   req->dst_len = rctx->cmd.u.rsa.key_size >> 3;
+
+   ret = 0;
+
+   return ret;
+}
+
+static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)
+{
+   return CCP_RSA_MAXMOD;
+}
+
+static int ccp_rsa_crypt(struct akcipher_request *req, bool encrypt)
+{
+   struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+   struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
+   struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx(req);
+   int ret = 0;
+
+   memset(>cmd, 0, sizeof(rctx->cmd));
+   INIT_LIST_HEAD(>cmd.entry);
+   rctx->cmd.engine = CCP_ENGINE_RSA;
+
+   rctx->cmd.u.rsa.key_size = c

[PATCH 1/4] crypto: ccp - Fix base RSA function for version 5 CCPs

2017-06-21 Thread Gary R Hook
Version 5 devices have requirements for buffer lengths, as well as
parameter format (e.g. bits vs. bytes). Fix the base CCP driver
code to meet requirements all supported versions.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-dev-v5.c |   10 ++--
 drivers/crypto/ccp/ccp-ops.c|   95 ---
 2 files changed, 64 insertions(+), 41 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c
index b10d2d2075cb..632518efd685 100644
--- a/drivers/crypto/ccp/ccp-dev-v5.c
+++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -469,7 +469,7 @@ static int ccp5_perform_rsa(struct ccp_op *op)
CCP5_CMD_PROT() = 0;
 
function.raw = 0;
-   CCP_RSA_SIZE() = op->u.rsa.mod_size >> 3;
+   CCP_RSA_SIZE() = (op->u.rsa.mod_size + 7) >> 3;
CCP5_CMD_FUNCTION() = function.raw;
 
CCP5_CMD_LEN() = op->u.rsa.input_len;
@@ -484,10 +484,10 @@ static int ccp5_perform_rsa(struct ccp_op *op)
CCP5_CMD_DST_HI() = ccp_addr_hi(>dst.u.dma);
CCP5_CMD_DST_MEM() = CCP_MEMTYPE_SYSTEM;
 
-   /* Exponent is in LSB memory */
-   CCP5_CMD_KEY_LO() = op->sb_key * LSB_ITEM_SIZE;
-   CCP5_CMD_KEY_HI() = 0;
-   CCP5_CMD_KEY_MEM() = CCP_MEMTYPE_SB;
+   /* Key (Exponent) is in external memory */
+   CCP5_CMD_KEY_LO() = ccp_addr_lo(>exp.u.dma);
+   CCP5_CMD_KEY_HI() = ccp_addr_hi(>exp.u.dma);
+   CCP5_CMD_KEY_MEM() = CCP_MEMTYPE_SYSTEM;
 
return ccp5_do_cmd(, op->cmd_q);
 }
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index c0dfdacbdff5..11155e52c52c 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1731,10 +1731,10 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
 static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
 {
struct ccp_rsa_engine *rsa = >u.rsa;
-   struct ccp_dm_workarea exp, src;
-   struct ccp_data dst;
+   struct ccp_dm_workarea exp, src, dst;
struct ccp_op op;
unsigned int sb_count, i_len, o_len;
+   unsigned int key_size_bytes;
int ret;
 
if (rsa->key_size > CCP_RSA_MAX_WIDTH)
@@ -1743,31 +1743,41 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
if (!rsa->exp || !rsa->mod || !rsa->src || !rsa->dst)
return -EINVAL;
 
-   /* The RSA modulus must precede the message being acted upon, so
-* it must be copied to a DMA area where the message and the
-* modulus can be concatenated.  Therefore the input buffer
-* length required is twice the output buffer length (which
-* must be a multiple of 256-bits).
-*/
-   o_len = ((rsa->key_size + 255) / 256) * 32;
-   i_len = o_len * 2;
-
-   sb_count = o_len / CCP_SB_BYTES;
-
memset(, 0, sizeof(op));
op.cmd_q = cmd_q;
-   op.jobid = ccp_gen_jobid(cmd_q->ccp);
-   op.sb_key = cmd_q->ccp->vdata->perform->sballoc(cmd_q, sb_count);
+   op.jobid = CCP_NEW_JOBID(cmd_q->ccp);
 
-   if (!op.sb_key)
-   return -EIO;
+   /* Compute o_len, i_len in bytes. */
+   if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0)) {
+   /* The RSA modulus must precede the message being acted upon, so
+* it must be copied to a DMA area where the message and the
+* modulus can be concatenated.  Therefore the input buffer
+* length required is twice the output buffer length (which
+* must be a multiple of 256-bits). sb_count is the
+* number of storage block slots required for the modulus
+*/
+   key_size_bytes = (rsa->key_size + 7) >> 3;
+   o_len = ((rsa->key_size + 255) / 256) * CCP_SB_BYTES;
+   i_len = key_size_bytes * 2;
+
+   sb_count = o_len / CCP_SB_BYTES;
+
+   op.sb_key = cmd_q->ccp->vdata->perform->sballoc(cmd_q,
+   sb_count);
+   if (!op.sb_key)
+   return -EIO;
+   } else {
+   /* A version 5 device allows a modulus size that will not fit
+* in the LSB, so the command will transfer it from memory.
+* But more importantly, the buffer sizes must be a multiple
+* of 32 bytes; rounding up may be required.
+*/
+   key_size_bytes = 32 * ((rsa->key_size + 255) / 256);
+   o_len = key_size_bytes;
+   i_len = o_len * 2; /* bytes */
+   op.sb_key = cmd_q->sb_key;
+   }
 
-   /* The RSA exponent may span multiple (32-byte) SB entries and must
-* be in little endian format. Reverse copy each 32-byte chunk

[PATCH 2/4] crypto: Add akcipher_set_reqsize() function

2017-06-21 Thread Gary R Hook
Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 include/crypto/internal/akcipher.h |6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/crypto/internal/akcipher.h 
b/include/crypto/internal/akcipher.h
index 479a0078f0f7..805686ba2be4 100644
--- a/include/crypto/internal/akcipher.h
+++ b/include/crypto/internal/akcipher.h
@@ -38,6 +38,12 @@ static inline void *akcipher_request_ctx(struct 
akcipher_request *req)
return req->__ctx;
 }
 
+static inline void akcipher_set_reqsize(struct crypto_akcipher *akcipher,
+   unsigned int reqsize)
+{
+   crypto_akcipher_alg(akcipher)->reqsize = reqsize;
+}
+
 static inline void *akcipher_tfm_ctx(struct crypto_akcipher *tfm)
 {
return tfm->base.__crt_ctx;



[PATCH 0/4] Enable full RSA support on CCPs

2017-06-21 Thread Gary R Hook
The following series enables RSA operations on version 5 devices,
adds a set-reqsize function (to provide uniformity with other cipher
APIs), implements akcipher enablement in the crypto layer, and 
makes a tweak for expanded v5 device capabilities.

---

Gary R Hook (4):
  crypto: ccp - Fix base RSA function for version 5 CCPs
  crypto: Add akcipher_set_reqsize() function
  crypto: ccp - Add support for RSA on the CCP
  crypto: ccp - Expand RSA support for a v5 ccp


 drivers/crypto/ccp/Makefile  |1 
 drivers/crypto/ccp/ccp-crypto-main.c |   21 ++
 drivers/crypto/ccp/ccp-crypto-rsa.c  |  289 ++
 drivers/crypto/ccp/ccp-crypto.h  |   32 
 drivers/crypto/ccp/ccp-debugfs.c |1 
 drivers/crypto/ccp/ccp-dev-v3.c  |1 
 drivers/crypto/ccp/ccp-dev-v5.c  |   12 +
 drivers/crypto/ccp/ccp-dev.c |1 
 drivers/crypto/ccp/ccp-dev.h |2 
 drivers/crypto/ccp/ccp-ops.c |   98 +++-
 include/crypto/internal/akcipher.h   |6 +
 include/linux/ccp.h  |1 
 12 files changed, 421 insertions(+), 44 deletions(-)
 create mode 100644 drivers/crypto/ccp/ccp-crypto-rsa.c

--
Signature


[PATCH] crypto: ccp - Provide a roll-back method for debugfs setup

2017-06-21 Thread Gary R Hook
Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-debugfs.c |   18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-debugfs.c b/drivers/crypto/ccp/ccp-debugfs.c
index 3cd6c83754e0..99aba1622613 100644
--- a/drivers/crypto/ccp/ccp-debugfs.c
+++ b/drivers/crypto/ccp/ccp-debugfs.c
@@ -291,6 +291,7 @@ void ccp5_debugfs_setup(struct ccp_device *ccp)
struct dentry *debugfs_q_instance;
struct dentry *debugfs_q_stats;
unsigned long flags;
+   int rc = 0;
int i;
 
if (!debugfs_initialized())
@@ -305,19 +306,19 @@ void ccp5_debugfs_setup(struct ccp_device *ccp)
 
ccp->debugfs_instance = debugfs_create_dir(ccp->name, ccp_debugfs_dir);
if (!ccp->debugfs_instance)
-   return;
+   goto err;
 
debugfs_info = debugfs_create_file("info", 0400,
   ccp->debugfs_instance, ccp,
   _debugfs_info_ops);
if (!debugfs_info)
-   return;
+   goto err;
 
debugfs_stats = debugfs_create_file("stats", 0600,
ccp->debugfs_instance, ccp,
_debugfs_stats_ops);
if (!debugfs_stats)
-   return;
+   goto err;
 
for (i = 0; i < ccp->cmd_q_count; i++) {
cmd_q = >cmd_q[i];
@@ -327,15 +328,22 @@ void ccp5_debugfs_setup(struct ccp_device *ccp)
debugfs_q_instance =
debugfs_create_dir(name, ccp->debugfs_instance);
if (!debugfs_q_instance)
-   return;
+   goto err;
 
debugfs_q_stats =
debugfs_create_file("stats", 0600,
debugfs_q_instance, cmd_q,
_debugfs_queue_ops);
if (!debugfs_q_stats)
-   return;
+   goto err;
}
+   return;
+
+err:
+   write_lock_irqsave(_debugfs_lock, flags);
+   debugfs_remove_recursive(ccp_debugfs_dir);
+   ccp_debugfs_dir = NULL;
+   write_unlock_irqrestore(_debugfs_lock, flags);
 }
 
 void ccp5_debugfs_destroy(void)



[PATCH] crypto: ccp - Release locks before returning

2017-06-19 Thread Gary R Hook
krobot warning: make sure that all error return paths release locks.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/ccp-debugfs.c |7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-debugfs.c b/drivers/crypto/ccp/ccp-debugfs.c
index 6d86693b117f..3cd6c83754e0 100644
--- a/drivers/crypto/ccp/ccp-debugfs.c
+++ b/drivers/crypto/ccp/ccp-debugfs.c
@@ -297,12 +297,11 @@ void ccp5_debugfs_setup(struct ccp_device *ccp)
return;
 
write_lock_irqsave(_debugfs_lock, flags);
-   if (!ccp_debugfs_dir) {
+   if (!ccp_debugfs_dir)
ccp_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
-   if (!ccp_debugfs_dir)
-   return;
-   }
write_unlock_irqrestore(_debugfs_lock, flags);
+   if (!ccp_debugfs_dir)
+   return;
 
ccp->debugfs_instance = debugfs_create_dir(ccp->name, ccp_debugfs_dir);
if (!ccp->debugfs_instance)



Re: [PATCH v2 9/9] crypto: ccp - Use IPAD/OPAD constant

2017-05-19 Thread Gary R Hook

On 5/19/2017 1:53 AM, Corentin Labbe wrote:

This patch simply replace all occurrence of HMAC IPAD/OPAD value by their
define.

Signed-off-by: Corentin Labbe <clabbe.montj...@gmail.com>


Acked-by: Gary R Hook <gary.h...@amd.com>


---
  drivers/crypto/ccp/ccp-crypto-sha.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c 
b/drivers/crypto/ccp/ccp-crypto-sha.c

index 6b46eea94932..ce97b3868f4a 100644
--- a/drivers/crypto/ccp/ccp-crypto-sha.c
+++ b/drivers/crypto/ccp/ccp-crypto-sha.c
@@ -18,6 +18,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -308,8 +309,8 @@ static int ccp_sha_setkey(struct crypto_ahash *tfm, 
const u8 *key,

  }

  for (i = 0; i < block_size; i++) {
-   ctx->u.sha.ipad[i] = ctx->u.sha.key[i] ^ 0x36;
-   ctx->u.sha.opad[i] = ctx->u.sha.key[i] ^ 0x5c;
+   ctx->u.sha.ipad[i] = ctx->u.sha.key[i] ^ HMAC_IPAD_VALUE;
+   ctx->u.sha.opad[i] = ctx->u.sha.key[i] ^ HMAC_OPAD_VALUE;
  }

  sg_init_one(>u.sha.opad_sg, ctx->u.sha.opad, block_size);
--
2.13.0





[PATCH V2] crypto: ccp - Add debugfs entries for CCP information

2017-05-02 Thread Gary R Hook
Expose some data about the configuration and operation of the CCP
through debugfs entries: device name, capabilities, configuration,
statistics.

Allow the user to reset the counters to zero by writing (any value)
to the 'stats' file. This can be done per queue or per device.

Changes from V1:
 - Correct polarity of test when destroying devices at module unload

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/Makefile  |3 
 drivers/crypto/ccp/ccp-debugfs.c |  345 ++
 drivers/crypto/ccp/ccp-dev-v5.c  |   28 +++
 drivers/crypto/ccp/ccp-dev.c |2 
 drivers/crypto/ccp/ccp-dev.h |   20 ++
 5 files changed, 395 insertions(+), 3 deletions(-)
 create mode 100644 drivers/crypto/ccp/ccp-debugfs.c

diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 60919a3ec53b..59493fd3a751 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -4,7 +4,8 @@ ccp-objs := ccp-dev.o \
ccp-dev-v3.o \
ccp-dev-v5.o \
ccp-platform.o \
-   ccp-dmaengine.o
+   ccp-dmaengine.o \
+   ccp-debugfs.o
 ccp-$(CONFIG_PCI) += ccp-pci.o
 
 obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o
diff --git a/drivers/crypto/ccp/ccp-debugfs.c b/drivers/crypto/ccp/ccp-debugfs.c
new file mode 100644
index ..6d86693b117f
--- /dev/null
+++ b/drivers/crypto/ccp/ccp-debugfs.c
@@ -0,0 +1,345 @@
+/*
+ * AMD Cryptographic Coprocessor (CCP) driver
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+
+#include "ccp-dev.h"
+
+/* DebugFS helpers */
+#defineOBUFP   (obuf + oboff)
+#defineOBUFLEN 512
+#defineOBUFSPC (OBUFLEN - oboff)
+#defineOSCNPRINTF(fmt, ...) \
+   scnprintf(OBUFP, OBUFSPC, fmt, ## __VA_ARGS__)
+
+#define BUFLEN 63
+
+#defineRI_VERSION_NUM  0x003F
+#defineRI_AES_PRESENT  0x0040
+#defineRI_3DES_PRESENT 0x0080
+#defineRI_SHA_PRESENT  0x0100
+#defineRI_RSA_PRESENT  0x0200
+#defineRI_ECC_PRESENT  0x0400
+#defineRI_ZDE_PRESENT  0x0800
+#defineRI_ZCE_PRESENT  0x1000
+#defineRI_TRNG_PRESENT 0x2000
+#defineRI_ELFC_PRESENT 0x4000
+#defineRI_ELFC_SHIFT   14
+#defineRI_NUM_VQM  0x00078000
+#defineRI_NVQM_SHIFT   15
+#defineRI_NVQM(r)  (((r) * RI_NUM_VQM) >> RI_NVQM_SHIFT)
+#defineRI_LSB_ENTRIES  0x0FF8
+#defineRI_NLSB_SHIFT   19
+#defineRI_NLSB(r)  (((r) * RI_LSB_ENTRIES) >> RI_NLSB_SHIFT)
+
+static ssize_t ccp5_debugfs_info_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+   struct ccp_device *ccp = filp->private_data;
+   unsigned int oboff = 0;
+   unsigned int regval;
+   ssize_t ret;
+   char *obuf;
+
+   if (!ccp)
+   return 0;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   oboff += OSCNPRINTF("Device name: %s\n", ccp->name);
+   oboff += OSCNPRINTF("   RNG name: %s\n", ccp->rngname);
+   oboff += OSCNPRINTF("   # Queues: %d\n", ccp->cmd_q_count);
+   oboff += OSCNPRINTF(" # Cmds: %d\n", ccp->cmd_count);
+
+   regval = ioread32(ccp->io_regs + CMD5_PSP_CCP_VERSION);
+   oboff += OSCNPRINTF("Version: %d\n", regval & RI_VERSION_NUM);
+   oboff += OSCNPRINTF("Engines:");
+   if (regval & RI_AES_PRESENT)
+   oboff += OSCNPRINTF(" AES");
+   if (regval & RI_3DES_PRESENT)
+   oboff += OSCNPRINTF(" 3DES");
+   if (regval & RI_SHA_PRESENT)
+   oboff += OSCNPRINTF(" SHA");
+   if (regval & RI_RSA_PRESENT)
+   oboff += OSCNPRINTF(" RSA");
+   if (regval & RI_ECC_PRESENT)
+   oboff += OSCNPRINTF(" ECC");
+   if (regval & RI_ZDE_PRESENT)
+   oboff += OSCNPRINTF(" ZDE");
+   if (regval & RI_ZCE_PRESENT)
+   oboff += OSCNPRINTF(" ZCE");
+   if (regval & RI_TRNG_PRESENT)
+   oboff += OSCNPRINTF(" TRNG");
+   oboff += OSCNPRINTF("\n");
+   oboff += OSCNPRINTF(" Queues: %d\n",
+  (regval & RI_NUM_VQM) >> RI_NVQM_SHIFT);
+   oboff += OSCNPRINTF("LSB Entries: %d\n",
+  (regval & RI_LSB_ENTRIES) >> RI_NLSB_SHIFT);
+

[PATCH] crypto: ccp - Add debugfs entries for CCP information

2017-04-26 Thread Gary R Hook
Expose some data about the configuration and operation of the CCP
through debugfs entries: device name, capabilities, configuration,
statistics.

Allow the user to reset the counters to zero by writing (any value)
to the 'stats' file. This can be done per queue or per device.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/crypto/ccp/Makefile  |3 
 drivers/crypto/ccp/ccp-debugfs.c |  345 ++
 drivers/crypto/ccp/ccp-dev-v5.c  |   28 +++
 drivers/crypto/ccp/ccp-dev.c |2 
 drivers/crypto/ccp/ccp-dev.h |   20 ++
 5 files changed, 395 insertions(+), 3 deletions(-)
 create mode 100644 drivers/crypto/ccp/ccp-debugfs.c

diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 60919a3ec53b..59493fd3a751 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -4,7 +4,8 @@ ccp-objs := ccp-dev.o \
ccp-dev-v3.o \
ccp-dev-v5.o \
ccp-platform.o \
-   ccp-dmaengine.o
+   ccp-dmaengine.o \
+   ccp-debugfs.o
 ccp-$(CONFIG_PCI) += ccp-pci.o
 
 obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o
diff --git a/drivers/crypto/ccp/ccp-debugfs.c b/drivers/crypto/ccp/ccp-debugfs.c
new file mode 100644
index ..6d86693b117f
--- /dev/null
+++ b/drivers/crypto/ccp/ccp-debugfs.c
@@ -0,0 +1,345 @@
+/*
+ * AMD Cryptographic Coprocessor (CCP) driver
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+
+#include "ccp-dev.h"
+
+/* DebugFS helpers */
+#defineOBUFP   (obuf + oboff)
+#defineOBUFLEN 512
+#defineOBUFSPC (OBUFLEN - oboff)
+#defineOSCNPRINTF(fmt, ...) \
+   scnprintf(OBUFP, OBUFSPC, fmt, ## __VA_ARGS__)
+
+#define BUFLEN 63
+
+#defineRI_VERSION_NUM  0x003F
+#defineRI_AES_PRESENT  0x0040
+#defineRI_3DES_PRESENT 0x0080
+#defineRI_SHA_PRESENT  0x0100
+#defineRI_RSA_PRESENT  0x0200
+#defineRI_ECC_PRESENT  0x0400
+#defineRI_ZDE_PRESENT  0x0800
+#defineRI_ZCE_PRESENT  0x1000
+#defineRI_TRNG_PRESENT 0x2000
+#defineRI_ELFC_PRESENT 0x4000
+#defineRI_ELFC_SHIFT   14
+#defineRI_NUM_VQM  0x00078000
+#defineRI_NVQM_SHIFT   15
+#defineRI_NVQM(r)  (((r) * RI_NUM_VQM) >> RI_NVQM_SHIFT)
+#defineRI_LSB_ENTRIES  0x0FF8
+#defineRI_NLSB_SHIFT   19
+#defineRI_NLSB(r)  (((r) * RI_LSB_ENTRIES) >> RI_NLSB_SHIFT)
+
+static ssize_t ccp5_debugfs_info_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+   struct ccp_device *ccp = filp->private_data;
+   unsigned int oboff = 0;
+   unsigned int regval;
+   ssize_t ret;
+   char *obuf;
+
+   if (!ccp)
+   return 0;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   oboff += OSCNPRINTF("Device name: %s\n", ccp->name);
+   oboff += OSCNPRINTF("   RNG name: %s\n", ccp->rngname);
+   oboff += OSCNPRINTF("   # Queues: %d\n", ccp->cmd_q_count);
+   oboff += OSCNPRINTF(" # Cmds: %d\n", ccp->cmd_count);
+
+   regval = ioread32(ccp->io_regs + CMD5_PSP_CCP_VERSION);
+   oboff += OSCNPRINTF("Version: %d\n", regval & RI_VERSION_NUM);
+   oboff += OSCNPRINTF("Engines:");
+   if (regval & RI_AES_PRESENT)
+   oboff += OSCNPRINTF(" AES");
+   if (regval & RI_3DES_PRESENT)
+   oboff += OSCNPRINTF(" 3DES");
+   if (regval & RI_SHA_PRESENT)
+   oboff += OSCNPRINTF(" SHA");
+   if (regval & RI_RSA_PRESENT)
+   oboff += OSCNPRINTF(" RSA");
+   if (regval & RI_ECC_PRESENT)
+   oboff += OSCNPRINTF(" ECC");
+   if (regval & RI_ZDE_PRESENT)
+   oboff += OSCNPRINTF(" ZDE");
+   if (regval & RI_ZCE_PRESENT)
+   oboff += OSCNPRINTF(" ZCE");
+   if (regval & RI_TRNG_PRESENT)
+   oboff += OSCNPRINTF(" TRNG");
+   oboff += OSCNPRINTF("\n");
+   oboff += OSCNPRINTF(" Queues: %d\n",
+  (regval & RI_NUM_VQM) >> RI_NVQM_SHIFT);
+   oboff += OSCNPRINTF("LSB Entries: %d\n",
+  (regval & RI_LSB_ENTRIES) >> RI_NLSB_SHIFT);
+
+   ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+   kfree(o

  1   2   3   >