[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 
---
 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 
+ *
+ * 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);
+   struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx(req);
+   int ret = 0;
+
+   

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 
---
 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 
+ *
+ * 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;
+
+ 

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

2017-06-22 Thread Tom Lendacky

On 6/21/2017 5:48 PM, Gary R Hook wrote:

Wire up the v3 CCP as a cipher provider.


The V5 support will be invoked through this also.  Maybe something like:

Wire up the CCP as an RSA cipher provider.



Signed-off-by: Gary R Hook 
---
  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;


Not sure what this does...  The return of the error code will cause the
init to fail and unregister everything. This path won't be taken again
to make use of the change in value.


+   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 
+ *
+ * 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;


This seems odd.  You should probably make this similar to the other CCP
complete functions:

if (ret)
return ret;

req->dst_len = ...

return 0;


+}
+
+static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)
+{
+   return 

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

2017-06-21 Thread Stephan Müller
Am Donnerstag, 22. Juni 2017, 00:48:01 CEST schrieb Gary R Hook:

Hi Gary,

> Wire up the v3 CCP as a cipher provider.
> 
> Signed-off-by: Gary R Hook 
> ---
>  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 
> + *
> + * 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);
> + 

[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 
---
 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 
+ *
+ * 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 = ctx->u.rsa.key_len; /* in bits */
+   if (encrypt) {
+   rctx->cmd.u.rsa.exp =