2 * AMD Cryptographic Coprocessor (CCP) SHA crypto API support
4 * Copyright (C) 2013 Advanced Micro Devices, Inc.
6 * Author: Tom Lendacky <thomas.lendacky@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/delay.h>
16 #include <linux/scatterlist.h>
17 #include <linux/crypto.h>
18 #include <crypto/algapi.h>
19 #include <crypto/hash.h>
20 #include <crypto/internal/hash.h>
21 #include <crypto/sha.h>
22 #include <crypto/scatterwalk.h>
24 #include "ccp-crypto.h"
27 static int ccp_sha_complete(struct crypto_async_request
*async_req
, int ret
)
29 struct ahash_request
*req
= ahash_request_cast(async_req
);
30 struct crypto_ahash
*tfm
= crypto_ahash_reqtfm(req
);
31 struct ccp_sha_req_ctx
*rctx
= ahash_request_ctx(req
);
32 unsigned int digest_size
= crypto_ahash_digestsize(tfm
);
38 /* Save remaining data to buffer */
39 unsigned int offset
= rctx
->nbytes
- rctx
->hash_rem
;
40 scatterwalk_map_and_copy(rctx
->buf
, rctx
->src
,
41 offset
, rctx
->hash_rem
, 0);
42 rctx
->buf_count
= rctx
->hash_rem
;
46 /* Update result area if supplied */
48 memcpy(req
->result
, rctx
->ctx
, digest_size
);
51 sg_free_table(&rctx
->data_sg
);
56 static int ccp_do_sha_update(struct ahash_request
*req
, unsigned int nbytes
,
59 struct crypto_ahash
*tfm
= crypto_ahash_reqtfm(req
);
60 struct ccp_ctx
*ctx
= crypto_ahash_ctx(tfm
);
61 struct ccp_sha_req_ctx
*rctx
= ahash_request_ctx(req
);
62 struct scatterlist
*sg
;
63 unsigned int block_size
=
64 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm
));
65 unsigned int sg_count
;
70 len
= (u64
)rctx
->buf_count
+ (u64
)nbytes
;
72 if (!final
&& (len
<= block_size
)) {
73 scatterwalk_map_and_copy(rctx
->buf
+ rctx
->buf_count
, req
->src
,
75 rctx
->buf_count
+= nbytes
;
81 rctx
->nbytes
= nbytes
;
84 rctx
->hash_rem
= final
? 0 : len
& (block_size
- 1);
85 rctx
->hash_cnt
= len
- rctx
->hash_rem
;
86 if (!final
&& !rctx
->hash_rem
) {
87 /* CCP can't do zero length final, so keep some data around */
88 rctx
->hash_cnt
-= block_size
;
89 rctx
->hash_rem
= block_size
;
92 /* Initialize the context scatterlist */
93 sg_init_one(&rctx
->ctx_sg
, rctx
->ctx
, sizeof(rctx
->ctx
));
96 if (rctx
->buf_count
&& nbytes
) {
97 /* Build the data scatterlist table - allocate enough entries
98 * for both data pieces (buffer and input data)
100 gfp
= req
->base
.flags
& CRYPTO_TFM_REQ_MAY_SLEEP
?
101 GFP_KERNEL
: GFP_ATOMIC
;
102 sg_count
= sg_nents(req
->src
) + 1;
103 ret
= sg_alloc_table(&rctx
->data_sg
, sg_count
, gfp
);
107 sg_init_one(&rctx
->buf_sg
, rctx
->buf
, rctx
->buf_count
);
108 sg
= ccp_crypto_sg_table_add(&rctx
->data_sg
, &rctx
->buf_sg
);
109 sg
= ccp_crypto_sg_table_add(&rctx
->data_sg
, req
->src
);
112 sg
= rctx
->data_sg
.sgl
;
113 } else if (rctx
->buf_count
) {
114 sg_init_one(&rctx
->buf_sg
, rctx
->buf
, rctx
->buf_count
);
121 rctx
->msg_bits
+= (rctx
->hash_cnt
<< 3); /* Total in bits */
123 memset(&rctx
->cmd
, 0, sizeof(rctx
->cmd
));
124 INIT_LIST_HEAD(&rctx
->cmd
.entry
);
125 rctx
->cmd
.engine
= CCP_ENGINE_SHA
;
126 rctx
->cmd
.u
.sha
.type
= rctx
->type
;
127 rctx
->cmd
.u
.sha
.ctx
= &rctx
->ctx_sg
;
128 rctx
->cmd
.u
.sha
.ctx_len
= sizeof(rctx
->ctx
);
129 rctx
->cmd
.u
.sha
.src
= sg
;
130 rctx
->cmd
.u
.sha
.src_len
= rctx
->hash_cnt
;
131 rctx
->cmd
.u
.sha
.opad
= ctx
->u
.sha
.key_len
?
132 &ctx
->u
.sha
.opad_sg
: NULL
;
133 rctx
->cmd
.u
.sha
.opad_len
= ctx
->u
.sha
.key_len
?
134 ctx
->u
.sha
.opad_count
: 0;
135 rctx
->cmd
.u
.sha
.first
= rctx
->first
;
136 rctx
->cmd
.u
.sha
.final
= rctx
->final
;
137 rctx
->cmd
.u
.sha
.msg_bits
= rctx
->msg_bits
;
141 ret
= ccp_crypto_enqueue_request(&req
->base
, &rctx
->cmd
);
146 static int ccp_sha_init(struct ahash_request
*req
)
148 struct crypto_ahash
*tfm
= crypto_ahash_reqtfm(req
);
149 struct ccp_ctx
*ctx
= crypto_ahash_ctx(tfm
);
150 struct ccp_sha_req_ctx
*rctx
= ahash_request_ctx(req
);
151 struct ccp_crypto_ahash_alg
*alg
=
152 ccp_crypto_ahash_alg(crypto_ahash_tfm(tfm
));
153 unsigned int block_size
=
154 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm
));
156 memset(rctx
, 0, sizeof(*rctx
));
158 rctx
->type
= alg
->type
;
161 if (ctx
->u
.sha
.key_len
) {
162 /* Buffer the HMAC key for first update */
163 memcpy(rctx
->buf
, ctx
->u
.sha
.ipad
, block_size
);
164 rctx
->buf_count
= block_size
;
170 static int ccp_sha_update(struct ahash_request
*req
)
172 return ccp_do_sha_update(req
, req
->nbytes
, 0);
175 static int ccp_sha_final(struct ahash_request
*req
)
177 return ccp_do_sha_update(req
, 0, 1);
180 static int ccp_sha_finup(struct ahash_request
*req
)
182 return ccp_do_sha_update(req
, req
->nbytes
, 1);
185 static int ccp_sha_digest(struct ahash_request
*req
)
189 ret
= ccp_sha_init(req
);
193 return ccp_sha_finup(req
);
196 static int ccp_sha_setkey(struct crypto_ahash
*tfm
, const u8
*key
,
197 unsigned int key_len
)
199 struct ccp_ctx
*ctx
= crypto_tfm_ctx(crypto_ahash_tfm(tfm
));
200 struct crypto_shash
*shash
= ctx
->u
.sha
.hmac_tfm
;
202 struct shash_desc sdesc
;
203 char ctx
[crypto_shash_descsize(shash
)];
205 unsigned int block_size
= crypto_shash_blocksize(shash
);
206 unsigned int digest_size
= crypto_shash_digestsize(shash
);
209 /* Set to zero until complete */
210 ctx
->u
.sha
.key_len
= 0;
212 /* Clear key area to provide zero padding for keys smaller
213 * than the block size
215 memset(ctx
->u
.sha
.key
, 0, sizeof(ctx
->u
.sha
.key
));
217 if (key_len
> block_size
) {
218 /* Must hash the input key */
219 desc
.sdesc
.tfm
= shash
;
220 desc
.sdesc
.flags
= crypto_ahash_get_flags(tfm
) &
221 CRYPTO_TFM_REQ_MAY_SLEEP
;
223 ret
= crypto_shash_digest(&desc
.sdesc
, key
, key_len
,
226 crypto_ahash_set_flags(tfm
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
230 key_len
= digest_size
;
232 memcpy(ctx
->u
.sha
.key
, key
, key_len
);
234 for (i
= 0; i
< block_size
; i
++) {
235 ctx
->u
.sha
.ipad
[i
] = ctx
->u
.sha
.key
[i
] ^ 0x36;
236 ctx
->u
.sha
.opad
[i
] = ctx
->u
.sha
.key
[i
] ^ 0x5c;
239 sg_init_one(&ctx
->u
.sha
.opad_sg
, ctx
->u
.sha
.opad
, block_size
);
240 ctx
->u
.sha
.opad_count
= block_size
;
242 ctx
->u
.sha
.key_len
= key_len
;
247 static int ccp_sha_cra_init(struct crypto_tfm
*tfm
)
249 struct ccp_ctx
*ctx
= crypto_tfm_ctx(tfm
);
250 struct crypto_ahash
*ahash
= __crypto_ahash_cast(tfm
);
252 ctx
->complete
= ccp_sha_complete
;
253 ctx
->u
.sha
.key_len
= 0;
255 crypto_ahash_set_reqsize(ahash
, sizeof(struct ccp_sha_req_ctx
));
260 static void ccp_sha_cra_exit(struct crypto_tfm
*tfm
)
264 static int ccp_hmac_sha_cra_init(struct crypto_tfm
*tfm
)
266 struct ccp_ctx
*ctx
= crypto_tfm_ctx(tfm
);
267 struct ccp_crypto_ahash_alg
*alg
= ccp_crypto_ahash_alg(tfm
);
268 struct crypto_shash
*hmac_tfm
;
270 hmac_tfm
= crypto_alloc_shash(alg
->child_alg
, 0, 0);
271 if (IS_ERR(hmac_tfm
)) {
272 pr_warn("could not load driver %s need for HMAC support\n",
274 return PTR_ERR(hmac_tfm
);
277 ctx
->u
.sha
.hmac_tfm
= hmac_tfm
;
279 return ccp_sha_cra_init(tfm
);
282 static void ccp_hmac_sha_cra_exit(struct crypto_tfm
*tfm
)
284 struct ccp_ctx
*ctx
= crypto_tfm_ctx(tfm
);
286 if (ctx
->u
.sha
.hmac_tfm
)
287 crypto_free_shash(ctx
->u
.sha
.hmac_tfm
);
289 ccp_sha_cra_exit(tfm
);
294 const char *drv_name
;
295 enum ccp_sha_type type
;
300 static struct ccp_sha_def sha_algs
[] = {
303 .drv_name
= "sha1-ccp",
304 .type
= CCP_SHA_TYPE_1
,
305 .digest_size
= SHA1_DIGEST_SIZE
,
306 .block_size
= SHA1_BLOCK_SIZE
,
310 .drv_name
= "sha224-ccp",
311 .type
= CCP_SHA_TYPE_224
,
312 .digest_size
= SHA224_DIGEST_SIZE
,
313 .block_size
= SHA224_BLOCK_SIZE
,
317 .drv_name
= "sha256-ccp",
318 .type
= CCP_SHA_TYPE_256
,
319 .digest_size
= SHA256_DIGEST_SIZE
,
320 .block_size
= SHA256_BLOCK_SIZE
,
324 static int ccp_register_hmac_alg(struct list_head
*head
,
325 const struct ccp_sha_def
*def
,
326 const struct ccp_crypto_ahash_alg
*base_alg
)
328 struct ccp_crypto_ahash_alg
*ccp_alg
;
329 struct ahash_alg
*alg
;
330 struct hash_alg_common
*halg
;
331 struct crypto_alg
*base
;
334 ccp_alg
= kzalloc(sizeof(*ccp_alg
), GFP_KERNEL
);
338 /* Copy the base algorithm and only change what's necessary */
339 *ccp_alg
= *base_alg
;
340 INIT_LIST_HEAD(&ccp_alg
->entry
);
342 strncpy(ccp_alg
->child_alg
, def
->name
, CRYPTO_MAX_ALG_NAME
);
345 alg
->setkey
= ccp_sha_setkey
;
350 snprintf(base
->cra_name
, CRYPTO_MAX_ALG_NAME
, "hmac(%s)", def
->name
);
351 snprintf(base
->cra_driver_name
, CRYPTO_MAX_ALG_NAME
, "hmac-%s",
353 base
->cra_init
= ccp_hmac_sha_cra_init
;
354 base
->cra_exit
= ccp_hmac_sha_cra_exit
;
356 ret
= crypto_register_ahash(alg
);
358 pr_err("%s ahash algorithm registration error (%d)\n",
359 base
->cra_name
, ret
);
364 list_add(&ccp_alg
->entry
, head
);
369 static int ccp_register_sha_alg(struct list_head
*head
,
370 const struct ccp_sha_def
*def
)
372 struct ccp_crypto_ahash_alg
*ccp_alg
;
373 struct ahash_alg
*alg
;
374 struct hash_alg_common
*halg
;
375 struct crypto_alg
*base
;
378 ccp_alg
= kzalloc(sizeof(*ccp_alg
), GFP_KERNEL
);
382 INIT_LIST_HEAD(&ccp_alg
->entry
);
384 ccp_alg
->type
= def
->type
;
387 alg
->init
= ccp_sha_init
;
388 alg
->update
= ccp_sha_update
;
389 alg
->final
= ccp_sha_final
;
390 alg
->finup
= ccp_sha_finup
;
391 alg
->digest
= ccp_sha_digest
;
394 halg
->digestsize
= def
->digest_size
;
397 snprintf(base
->cra_name
, CRYPTO_MAX_ALG_NAME
, "%s", def
->name
);
398 snprintf(base
->cra_driver_name
, CRYPTO_MAX_ALG_NAME
, "%s",
400 base
->cra_flags
= CRYPTO_ALG_TYPE_AHASH
| CRYPTO_ALG_ASYNC
|
401 CRYPTO_ALG_KERN_DRIVER_ONLY
|
402 CRYPTO_ALG_NEED_FALLBACK
;
403 base
->cra_blocksize
= def
->block_size
;
404 base
->cra_ctxsize
= sizeof(struct ccp_ctx
);
405 base
->cra_priority
= CCP_CRA_PRIORITY
;
406 base
->cra_type
= &crypto_ahash_type
;
407 base
->cra_init
= ccp_sha_cra_init
;
408 base
->cra_exit
= ccp_sha_cra_exit
;
409 base
->cra_module
= THIS_MODULE
;
411 ret
= crypto_register_ahash(alg
);
413 pr_err("%s ahash algorithm registration error (%d)\n",
414 base
->cra_name
, ret
);
419 list_add(&ccp_alg
->entry
, head
);
421 ret
= ccp_register_hmac_alg(head
, def
, ccp_alg
);
426 int ccp_register_sha_algs(struct list_head
*head
)
430 for (i
= 0; i
< ARRAY_SIZE(sha_algs
); i
++) {
431 ret
= ccp_register_sha_alg(head
, &sha_algs
[i
]);