root/drivers/crypto/ccp/ccp-crypto-rsa.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. akcipher_request_cast
  2. ccp_copy_and_save_keypart
  3. ccp_rsa_complete
  4. ccp_rsa_maxsize
  5. ccp_rsa_crypt
  6. ccp_rsa_encrypt
  7. ccp_rsa_decrypt
  8. ccp_check_key_length
  9. ccp_rsa_free_key_bufs
  10. ccp_rsa_setkey
  11. ccp_rsa_setprivkey
  12. ccp_rsa_setpubkey
  13. ccp_rsa_init_tfm
  14. ccp_rsa_exit_tfm
  15. ccp_register_rsa_alg
  16. ccp_register_rsa_algs

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * AMD Cryptographic Coprocessor (CCP) RSA crypto API support
   4  *
   5  * Copyright (C) 2017 Advanced Micro Devices, Inc.
   6  *
   7  * Author: Gary R Hook <gary.hook@amd.com>
   8  */
   9 
  10 #include <linux/module.h>
  11 #include <linux/sched.h>
  12 #include <linux/scatterlist.h>
  13 #include <linux/crypto.h>
  14 #include <crypto/algapi.h>
  15 #include <crypto/internal/rsa.h>
  16 #include <crypto/internal/akcipher.h>
  17 #include <crypto/akcipher.h>
  18 #include <crypto/scatterwalk.h>
  19 
  20 #include "ccp-crypto.h"
  21 
  22 static inline struct akcipher_request *akcipher_request_cast(
  23         struct crypto_async_request *req)
  24 {
  25         return container_of(req, struct akcipher_request, base);
  26 }
  27 
  28 static inline int ccp_copy_and_save_keypart(u8 **kpbuf, unsigned int *kplen,
  29                                             const u8 *buf, size_t sz)
  30 {
  31         int nskip;
  32 
  33         for (nskip = 0; nskip < sz; nskip++)
  34                 if (buf[nskip])
  35                         break;
  36         *kplen = sz - nskip;
  37         *kpbuf = kmemdup(buf + nskip, *kplen, GFP_KERNEL);
  38         if (!*kpbuf)
  39                 return -ENOMEM;
  40 
  41         return 0;
  42 }
  43 
  44 static int ccp_rsa_complete(struct crypto_async_request *async_req, int ret)
  45 {
  46         struct akcipher_request *req = akcipher_request_cast(async_req);
  47         struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx(req);
  48 
  49         if (ret)
  50                 return ret;
  51 
  52         req->dst_len = rctx->cmd.u.rsa.key_size >> 3;
  53 
  54         return 0;
  55 }
  56 
  57 static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)
  58 {
  59         struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
  60 
  61         return ctx->u.rsa.n_len;
  62 }
  63 
  64 static int ccp_rsa_crypt(struct akcipher_request *req, bool encrypt)
  65 {
  66         struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
  67         struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
  68         struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx(req);
  69         int ret = 0;
  70 
  71         memset(&rctx->cmd, 0, sizeof(rctx->cmd));
  72         INIT_LIST_HEAD(&rctx->cmd.entry);
  73         rctx->cmd.engine = CCP_ENGINE_RSA;
  74 
  75         rctx->cmd.u.rsa.key_size = ctx->u.rsa.key_len; /* in bits */
  76         if (encrypt) {
  77                 rctx->cmd.u.rsa.exp = &ctx->u.rsa.e_sg;
  78                 rctx->cmd.u.rsa.exp_len = ctx->u.rsa.e_len;
  79         } else {
  80                 rctx->cmd.u.rsa.exp = &ctx->u.rsa.d_sg;
  81                 rctx->cmd.u.rsa.exp_len = ctx->u.rsa.d_len;
  82         }
  83         rctx->cmd.u.rsa.mod = &ctx->u.rsa.n_sg;
  84         rctx->cmd.u.rsa.mod_len = ctx->u.rsa.n_len;
  85         rctx->cmd.u.rsa.src = req->src;
  86         rctx->cmd.u.rsa.src_len = req->src_len;
  87         rctx->cmd.u.rsa.dst = req->dst;
  88 
  89         ret = ccp_crypto_enqueue_request(&req->base, &rctx->cmd);
  90 
  91         return ret;
  92 }
  93 
  94 static int ccp_rsa_encrypt(struct akcipher_request *req)
  95 {
  96         return ccp_rsa_crypt(req, true);
  97 }
  98 
  99 static int ccp_rsa_decrypt(struct akcipher_request *req)
 100 {
 101         return ccp_rsa_crypt(req, false);
 102 }
 103 
 104 static int ccp_check_key_length(unsigned int len)
 105 {
 106         /* In bits */
 107         if (len < 8 || len > 4096)
 108                 return -EINVAL;
 109         return 0;
 110 }
 111 
 112 static void ccp_rsa_free_key_bufs(struct ccp_ctx *ctx)
 113 {
 114         /* Clean up old key data */
 115         kzfree(ctx->u.rsa.e_buf);
 116         ctx->u.rsa.e_buf = NULL;
 117         ctx->u.rsa.e_len = 0;
 118         kzfree(ctx->u.rsa.n_buf);
 119         ctx->u.rsa.n_buf = NULL;
 120         ctx->u.rsa.n_len = 0;
 121         kzfree(ctx->u.rsa.d_buf);
 122         ctx->u.rsa.d_buf = NULL;
 123         ctx->u.rsa.d_len = 0;
 124 }
 125 
 126 static int ccp_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
 127                           unsigned int keylen, bool private)
 128 {
 129         struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
 130         struct rsa_key raw_key;
 131         int ret;
 132 
 133         ccp_rsa_free_key_bufs(ctx);
 134         memset(&raw_key, 0, sizeof(raw_key));
 135 
 136         /* Code borrowed from crypto/rsa.c */
 137         if (private)
 138                 ret = rsa_parse_priv_key(&raw_key, key, keylen);
 139         else
 140                 ret = rsa_parse_pub_key(&raw_key, key, keylen);
 141         if (ret)
 142                 goto n_key;
 143 
 144         ret = ccp_copy_and_save_keypart(&ctx->u.rsa.n_buf, &ctx->u.rsa.n_len,
 145                                         raw_key.n, raw_key.n_sz);
 146         if (ret)
 147                 goto key_err;
 148         sg_init_one(&ctx->u.rsa.n_sg, ctx->u.rsa.n_buf, ctx->u.rsa.n_len);
 149 
 150         ctx->u.rsa.key_len = ctx->u.rsa.n_len << 3; /* convert to bits */
 151         if (ccp_check_key_length(ctx->u.rsa.key_len)) {
 152                 ret = -EINVAL;
 153                 goto key_err;
 154         }
 155 
 156         ret = ccp_copy_and_save_keypart(&ctx->u.rsa.e_buf, &ctx->u.rsa.e_len,
 157                                         raw_key.e, raw_key.e_sz);
 158         if (ret)
 159                 goto key_err;
 160         sg_init_one(&ctx->u.rsa.e_sg, ctx->u.rsa.e_buf, ctx->u.rsa.e_len);
 161 
 162         if (private) {
 163                 ret = ccp_copy_and_save_keypart(&ctx->u.rsa.d_buf,
 164                                                 &ctx->u.rsa.d_len,
 165                                                 raw_key.d, raw_key.d_sz);
 166                 if (ret)
 167                         goto key_err;
 168                 sg_init_one(&ctx->u.rsa.d_sg,
 169                             ctx->u.rsa.d_buf, ctx->u.rsa.d_len);
 170         }
 171 
 172         return 0;
 173 
 174 key_err:
 175         ccp_rsa_free_key_bufs(ctx);
 176 
 177 n_key:
 178         return ret;
 179 }
 180 
 181 static int ccp_rsa_setprivkey(struct crypto_akcipher *tfm, const void *key,
 182                               unsigned int keylen)
 183 {
 184         return ccp_rsa_setkey(tfm, key, keylen, true);
 185 }
 186 
 187 static int ccp_rsa_setpubkey(struct crypto_akcipher *tfm, const void *key,
 188                              unsigned int keylen)
 189 {
 190         return ccp_rsa_setkey(tfm, key, keylen, false);
 191 }
 192 
 193 static int ccp_rsa_init_tfm(struct crypto_akcipher *tfm)
 194 {
 195         struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
 196 
 197         akcipher_set_reqsize(tfm, sizeof(struct ccp_rsa_req_ctx));
 198         ctx->complete = ccp_rsa_complete;
 199 
 200         return 0;
 201 }
 202 
 203 static void ccp_rsa_exit_tfm(struct crypto_akcipher *tfm)
 204 {
 205         struct ccp_ctx *ctx = crypto_tfm_ctx(&tfm->base);
 206 
 207         ccp_rsa_free_key_bufs(ctx);
 208 }
 209 
 210 static struct akcipher_alg ccp_rsa_defaults = {
 211         .encrypt = ccp_rsa_encrypt,
 212         .decrypt = ccp_rsa_decrypt,
 213         .set_pub_key = ccp_rsa_setpubkey,
 214         .set_priv_key = ccp_rsa_setprivkey,
 215         .max_size = ccp_rsa_maxsize,
 216         .init = ccp_rsa_init_tfm,
 217         .exit = ccp_rsa_exit_tfm,
 218         .base = {
 219                 .cra_name = "rsa",
 220                 .cra_driver_name = "rsa-ccp",
 221                 .cra_priority = CCP_CRA_PRIORITY,
 222                 .cra_module = THIS_MODULE,
 223                 .cra_ctxsize = 2 * sizeof(struct ccp_ctx),
 224         },
 225 };
 226 
 227 struct ccp_rsa_def {
 228         unsigned int version;
 229         const char *name;
 230         const char *driver_name;
 231         unsigned int reqsize;
 232         struct akcipher_alg *alg_defaults;
 233 };
 234 
 235 static struct ccp_rsa_def rsa_algs[] = {
 236         {
 237                 .version        = CCP_VERSION(3, 0),
 238                 .name           = "rsa",
 239                 .driver_name    = "rsa-ccp",
 240                 .reqsize        = sizeof(struct ccp_rsa_req_ctx),
 241                 .alg_defaults   = &ccp_rsa_defaults,
 242         }
 243 };
 244 
 245 static int ccp_register_rsa_alg(struct list_head *head,
 246                                 const struct ccp_rsa_def *def)
 247 {
 248         struct ccp_crypto_akcipher_alg *ccp_alg;
 249         struct akcipher_alg *alg;
 250         int ret;
 251 
 252         ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL);
 253         if (!ccp_alg)
 254                 return -ENOMEM;
 255 
 256         INIT_LIST_HEAD(&ccp_alg->entry);
 257 
 258         alg = &ccp_alg->alg;
 259         *alg = *def->alg_defaults;
 260         snprintf(alg->base.cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
 261         snprintf(alg->base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
 262                  def->driver_name);
 263         ret = crypto_register_akcipher(alg);
 264         if (ret) {
 265                 pr_err("%s akcipher algorithm registration error (%d)\n",
 266                        alg->base.cra_name, ret);
 267                 kfree(ccp_alg);
 268                 return ret;
 269         }
 270 
 271         list_add(&ccp_alg->entry, head);
 272 
 273         return 0;
 274 }
 275 
 276 int ccp_register_rsa_algs(struct list_head *head)
 277 {
 278         int i, ret;
 279         unsigned int ccpversion = ccp_version();
 280 
 281         /* Register the RSA algorithm in standard mode
 282          * This works for CCP v3 and later
 283          */
 284         for (i = 0; i < ARRAY_SIZE(rsa_algs); i++) {
 285                 if (rsa_algs[i].version > ccpversion)
 286                         continue;
 287                 ret = ccp_register_rsa_alg(head, &rsa_algs[i]);
 288                 if (ret)
 289                         return ret;
 290         }
 291 
 292         return 0;
 293 }

/* [<][>][^][v][top][bottom][index][help] */