linux/drivers/crypto/ccp/ccp-crypto-rsa.c
<<
>>
Prefs
   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
  22static 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
  28static 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
  44static 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
  57static 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
  64static 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
  94static int ccp_rsa_encrypt(struct akcipher_request *req)
  95{
  96        return ccp_rsa_crypt(req, true);
  97}
  98
  99static int ccp_rsa_decrypt(struct akcipher_request *req)
 100{
 101        return ccp_rsa_crypt(req, false);
 102}
 103
 104static 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
 112static void ccp_rsa_free_key_bufs(struct ccp_ctx *ctx)
 113{
 114        /* Clean up old key data */
 115        kfree_sensitive(ctx->u.rsa.e_buf);
 116        ctx->u.rsa.e_buf = NULL;
 117        ctx->u.rsa.e_len = 0;
 118        kfree_sensitive(ctx->u.rsa.n_buf);
 119        ctx->u.rsa.n_buf = NULL;
 120        ctx->u.rsa.n_len = 0;
 121        kfree_sensitive(ctx->u.rsa.d_buf);
 122        ctx->u.rsa.d_buf = NULL;
 123        ctx->u.rsa.d_len = 0;
 124}
 125
 126static 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
 174key_err:
 175        ccp_rsa_free_key_bufs(ctx);
 176
 177n_key:
 178        return ret;
 179}
 180
 181static 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
 187static 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
 193static 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
 203static 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
 210static 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
 227struct 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
 235static 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
 245static 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
 276int 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}
 294