2 * AMD Cryptographic Coprocessor (CCP) RSA crypto API support
4 * Copyright (C) 2017 Advanced Micro Devices, Inc.
6 * Author: Gary R Hook <gary.hook@amd.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/sched.h>
15 #include <linux/scatterlist.h>
16 #include <linux/crypto.h>
17 #include <crypto/algapi.h>
18 #include <crypto/internal/rsa.h>
19 #include <crypto/internal/akcipher.h>
20 #include <crypto/akcipher.h>
21 #include <crypto/scatterwalk.h>
23 #include "ccp-crypto.h"
25 static inline struct akcipher_request
*akcipher_request_cast(
26 struct crypto_async_request
*req
)
28 return container_of(req
, struct akcipher_request
, base
);
31 static inline int ccp_copy_and_save_keypart(u8
**kpbuf
, unsigned int *kplen
,
32 const u8
*buf
, size_t sz
)
36 for (nskip
= 0; nskip
< sz
; nskip
++)
40 *kpbuf
= kzalloc(*kplen
, GFP_KERNEL
);
43 memcpy(*kpbuf
, buf
+ nskip
, *kplen
);
48 static int ccp_rsa_complete(struct crypto_async_request
*async_req
, int ret
)
50 struct akcipher_request
*req
= akcipher_request_cast(async_req
);
51 struct ccp_rsa_req_ctx
*rctx
= akcipher_request_ctx(req
);
56 req
->dst_len
= rctx
->cmd
.u
.rsa
.key_size
>> 3;
61 static unsigned int ccp_rsa_maxsize(struct crypto_akcipher
*tfm
)
63 if (ccp_version() > CCP_VERSION(3, 0))
64 return CCP5_RSA_MAXMOD
;
66 return CCP_RSA_MAXMOD
;
69 static int ccp_rsa_crypt(struct akcipher_request
*req
, bool encrypt
)
71 struct crypto_akcipher
*tfm
= crypto_akcipher_reqtfm(req
);
72 struct ccp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
73 struct ccp_rsa_req_ctx
*rctx
= akcipher_request_ctx(req
);
76 memset(&rctx
->cmd
, 0, sizeof(rctx
->cmd
));
77 INIT_LIST_HEAD(&rctx
->cmd
.entry
);
78 rctx
->cmd
.engine
= CCP_ENGINE_RSA
;
80 rctx
->cmd
.u
.rsa
.key_size
= ctx
->u
.rsa
.key_len
; /* in bits */
82 rctx
->cmd
.u
.rsa
.exp
= &ctx
->u
.rsa
.e_sg
;
83 rctx
->cmd
.u
.rsa
.exp_len
= ctx
->u
.rsa
.e_len
;
85 rctx
->cmd
.u
.rsa
.exp
= &ctx
->u
.rsa
.d_sg
;
86 rctx
->cmd
.u
.rsa
.exp_len
= ctx
->u
.rsa
.d_len
;
88 rctx
->cmd
.u
.rsa
.mod
= &ctx
->u
.rsa
.n_sg
;
89 rctx
->cmd
.u
.rsa
.mod_len
= ctx
->u
.rsa
.n_len
;
90 rctx
->cmd
.u
.rsa
.src
= req
->src
;
91 rctx
->cmd
.u
.rsa
.src_len
= req
->src_len
;
92 rctx
->cmd
.u
.rsa
.dst
= req
->dst
;
94 ret
= ccp_crypto_enqueue_request(&req
->base
, &rctx
->cmd
);
99 static int ccp_rsa_encrypt(struct akcipher_request
*req
)
101 return ccp_rsa_crypt(req
, true);
104 static int ccp_rsa_decrypt(struct akcipher_request
*req
)
106 return ccp_rsa_crypt(req
, false);
109 static int ccp_check_key_length(unsigned int len
)
112 if (len
< 8 || len
> 4096)
117 static void ccp_rsa_free_key_bufs(struct ccp_ctx
*ctx
)
119 /* Clean up old key data */
120 kzfree(ctx
->u
.rsa
.e_buf
);
121 ctx
->u
.rsa
.e_buf
= NULL
;
122 ctx
->u
.rsa
.e_len
= 0;
123 kzfree(ctx
->u
.rsa
.n_buf
);
124 ctx
->u
.rsa
.n_buf
= NULL
;
125 ctx
->u
.rsa
.n_len
= 0;
126 kzfree(ctx
->u
.rsa
.d_buf
);
127 ctx
->u
.rsa
.d_buf
= NULL
;
128 ctx
->u
.rsa
.d_len
= 0;
131 static int ccp_rsa_setkey(struct crypto_akcipher
*tfm
, const void *key
,
132 unsigned int keylen
, bool private)
134 struct ccp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
135 struct rsa_key raw_key
;
138 ccp_rsa_free_key_bufs(ctx
);
139 memset(&raw_key
, 0, sizeof(raw_key
));
141 /* Code borrowed from crypto/rsa.c */
143 ret
= rsa_parse_priv_key(&raw_key
, key
, keylen
);
145 ret
= rsa_parse_pub_key(&raw_key
, key
, keylen
);
149 ret
= ccp_copy_and_save_keypart(&ctx
->u
.rsa
.n_buf
, &ctx
->u
.rsa
.n_len
,
150 raw_key
.n
, raw_key
.n_sz
);
153 sg_init_one(&ctx
->u
.rsa
.n_sg
, ctx
->u
.rsa
.n_buf
, ctx
->u
.rsa
.n_len
);
155 ctx
->u
.rsa
.key_len
= ctx
->u
.rsa
.n_len
<< 3; /* convert to bits */
156 if (ccp_check_key_length(ctx
->u
.rsa
.key_len
)) {
161 ret
= ccp_copy_and_save_keypart(&ctx
->u
.rsa
.e_buf
, &ctx
->u
.rsa
.e_len
,
162 raw_key
.e
, raw_key
.e_sz
);
165 sg_init_one(&ctx
->u
.rsa
.e_sg
, ctx
->u
.rsa
.e_buf
, ctx
->u
.rsa
.e_len
);
168 ret
= ccp_copy_and_save_keypart(&ctx
->u
.rsa
.d_buf
,
170 raw_key
.d
, raw_key
.d_sz
);
173 sg_init_one(&ctx
->u
.rsa
.d_sg
,
174 ctx
->u
.rsa
.d_buf
, ctx
->u
.rsa
.d_len
);
180 ccp_rsa_free_key_bufs(ctx
);
186 static int ccp_rsa_setprivkey(struct crypto_akcipher
*tfm
, const void *key
,
189 return ccp_rsa_setkey(tfm
, key
, keylen
, true);
192 static int ccp_rsa_setpubkey(struct crypto_akcipher
*tfm
, const void *key
,
195 return ccp_rsa_setkey(tfm
, key
, keylen
, false);
198 static int ccp_rsa_init_tfm(struct crypto_akcipher
*tfm
)
200 struct ccp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
202 akcipher_set_reqsize(tfm
, sizeof(struct ccp_rsa_req_ctx
));
203 ctx
->complete
= ccp_rsa_complete
;
208 static void ccp_rsa_exit_tfm(struct crypto_akcipher
*tfm
)
210 struct ccp_ctx
*ctx
= crypto_tfm_ctx(&tfm
->base
);
212 ccp_rsa_free_key_bufs(ctx
);
215 static struct akcipher_alg ccp_rsa_defaults
= {
216 .encrypt
= ccp_rsa_encrypt
,
217 .decrypt
= ccp_rsa_decrypt
,
218 .sign
= ccp_rsa_decrypt
,
219 .verify
= ccp_rsa_encrypt
,
220 .set_pub_key
= ccp_rsa_setpubkey
,
221 .set_priv_key
= ccp_rsa_setprivkey
,
222 .max_size
= ccp_rsa_maxsize
,
223 .init
= ccp_rsa_init_tfm
,
224 .exit
= ccp_rsa_exit_tfm
,
227 .cra_driver_name
= "rsa-ccp",
228 .cra_priority
= CCP_CRA_PRIORITY
,
229 .cra_module
= THIS_MODULE
,
230 .cra_ctxsize
= 2 * sizeof(struct ccp_ctx
),
235 unsigned int version
;
237 const char *driver_name
;
238 unsigned int reqsize
;
239 struct akcipher_alg
*alg_defaults
;
242 static struct ccp_rsa_def rsa_algs
[] = {
244 .version
= CCP_VERSION(3, 0),
246 .driver_name
= "rsa-ccp",
247 .reqsize
= sizeof(struct ccp_rsa_req_ctx
),
248 .alg_defaults
= &ccp_rsa_defaults
,
252 int ccp_register_rsa_alg(struct list_head
*head
, const struct ccp_rsa_def
*def
)
254 struct ccp_crypto_akcipher_alg
*ccp_alg
;
255 struct akcipher_alg
*alg
;
258 ccp_alg
= kzalloc(sizeof(*ccp_alg
), GFP_KERNEL
);
262 INIT_LIST_HEAD(&ccp_alg
->entry
);
265 *alg
= *def
->alg_defaults
;
266 snprintf(alg
->base
.cra_name
, CRYPTO_MAX_ALG_NAME
, "%s", def
->name
);
267 snprintf(alg
->base
.cra_driver_name
, CRYPTO_MAX_ALG_NAME
, "%s",
269 ret
= crypto_register_akcipher(alg
);
271 pr_err("%s akcipher algorithm registration error (%d)\n",
272 alg
->base
.cra_name
, ret
);
277 list_add(&ccp_alg
->entry
, head
);
282 int ccp_register_rsa_algs(struct list_head
*head
)
285 unsigned int ccpversion
= ccp_version();
287 /* Register the RSA algorithm in standard mode
288 * This works for CCP v3 and later
290 for (i
= 0; i
< ARRAY_SIZE(rsa_algs
); i
++) {
291 if (rsa_algs
[i
].version
> ccpversion
)
293 ret
= ccp_register_rsa_alg(head
, &rsa_algs
[i
]);