3 * Copyright (C) 2016 Cavium, Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License
7 * as published by the Free Software Foundation.
10 #include <crypto/aes.h>
11 #include <crypto/algapi.h>
12 #include <crypto/authenc.h>
13 #include <crypto/cryptd.h>
14 #include <crypto/crypto_wq.h>
15 #include <crypto/des.h>
16 #include <crypto/xts.h>
17 #include <linux/crypto.h>
18 #include <linux/err.h>
19 #include <linux/list.h>
20 #include <linux/scatterlist.h>
23 #include "cptvf_algs.h"
25 struct cpt_device_handle
{
26 void *cdev
[MAX_DEVICES
];
30 static struct cpt_device_handle dev_handle
;
32 static void cvm_callback(u32 status
, void *arg
)
34 struct crypto_async_request
*req
= (struct crypto_async_request
*)arg
;
36 req
->complete(req
, !status
);
39 static inline void update_input_iv(struct cpt_request_info
*req_info
,
40 u8
*iv
, u32 enc_iv_len
,
43 /* Setting the iv information */
44 req_info
->in
[*argcnt
].vptr
= (void *)iv
;
45 req_info
->in
[*argcnt
].size
= enc_iv_len
;
46 req_info
->req
.dlen
+= enc_iv_len
;
51 static inline void update_output_iv(struct cpt_request_info
*req_info
,
52 u8
*iv
, u32 enc_iv_len
,
55 /* Setting the iv information */
56 req_info
->out
[*argcnt
].vptr
= (void *)iv
;
57 req_info
->out
[*argcnt
].size
= enc_iv_len
;
58 req_info
->rlen
+= enc_iv_len
;
63 static inline void update_input_data(struct cpt_request_info
*req_info
,
64 struct scatterlist
*inp_sg
,
65 u32 nbytes
, u32
*argcnt
)
67 req_info
->req
.dlen
+= nbytes
;
70 u32 len
= min(nbytes
, inp_sg
->length
);
71 u8
*ptr
= sg_virt(inp_sg
);
73 req_info
->in
[*argcnt
].vptr
= (void *)ptr
;
74 req_info
->in
[*argcnt
].size
= len
;
82 static inline void update_output_data(struct cpt_request_info
*req_info
,
83 struct scatterlist
*outp_sg
,
84 u32 nbytes
, u32
*argcnt
)
86 req_info
->rlen
+= nbytes
;
89 u32 len
= min(nbytes
, outp_sg
->length
);
90 u8
*ptr
= sg_virt(outp_sg
);
92 req_info
->out
[*argcnt
].vptr
= (void *)ptr
;
93 req_info
->out
[*argcnt
].size
= len
;
100 static inline u32
create_ctx_hdr(struct ablkcipher_request
*req
, u32 enc
,
103 struct crypto_ablkcipher
*tfm
= crypto_ablkcipher_reqtfm(req
);
104 struct cvm_enc_ctx
*ctx
= crypto_ablkcipher_ctx(tfm
);
105 struct cvm_req_ctx
*rctx
= ablkcipher_request_ctx(req
);
106 struct fc_context
*fctx
= &rctx
->fctx
;
107 u64
*offset_control
= &rctx
->control_word
;
108 u32 enc_iv_len
= crypto_ablkcipher_ivsize(tfm
);
109 struct cpt_request_info
*req_info
= &rctx
->cpt_req
;
110 u64
*ctrl_flags
= NULL
;
112 req_info
->ctrl
.s
.grp
= 0;
113 req_info
->ctrl
.s
.dma_mode
= DMA_GATHER_SCATTER
;
114 req_info
->ctrl
.s
.se_req
= SE_CORE_REQ
;
116 req_info
->req
.opcode
.s
.major
= MAJOR_OP_FC
|
117 DMA_MODE_FLAG(DMA_GATHER_SCATTER
);
119 req_info
->req
.opcode
.s
.minor
= 2;
121 req_info
->req
.opcode
.s
.minor
= 3;
123 req_info
->req
.param1
= req
->nbytes
; /* Encryption Data length */
124 req_info
->req
.param2
= 0; /*Auth data length */
126 fctx
->enc
.enc_ctrl
.e
.enc_cipher
= ctx
->cipher_type
;
127 fctx
->enc
.enc_ctrl
.e
.aes_key
= ctx
->key_type
;
128 fctx
->enc
.enc_ctrl
.e
.iv_source
= FROM_DPTR
;
130 if (ctx
->cipher_type
== AES_XTS
)
131 memcpy(fctx
->enc
.encr_key
, ctx
->enc_key
, ctx
->key_len
* 2);
133 memcpy(fctx
->enc
.encr_key
, ctx
->enc_key
, ctx
->key_len
);
134 ctrl_flags
= (u64
*)&fctx
->enc
.enc_ctrl
.flags
;
135 *ctrl_flags
= cpu_to_be64(*ctrl_flags
);
137 *offset_control
= cpu_to_be64(((u64
)(enc_iv_len
) << 16));
138 /* Storing Packet Data Information in offset
139 * Control Word First 8 bytes
141 req_info
->in
[*argcnt
].vptr
= (u8
*)offset_control
;
142 req_info
->in
[*argcnt
].size
= CONTROL_WORD_LEN
;
143 req_info
->req
.dlen
+= CONTROL_WORD_LEN
;
146 req_info
->in
[*argcnt
].vptr
= (u8
*)fctx
;
147 req_info
->in
[*argcnt
].size
= sizeof(struct fc_context
);
148 req_info
->req
.dlen
+= sizeof(struct fc_context
);
155 static inline u32
create_input_list(struct ablkcipher_request
*req
, u32 enc
,
158 struct cvm_req_ctx
*rctx
= ablkcipher_request_ctx(req
);
159 struct cpt_request_info
*req_info
= &rctx
->cpt_req
;
162 create_ctx_hdr(req
, enc
, &argcnt
);
163 update_input_iv(req_info
, req
->info
, enc_iv_len
, &argcnt
);
164 update_input_data(req_info
, req
->src
, req
->nbytes
, &argcnt
);
165 req_info
->incnt
= argcnt
;
170 static inline void store_cb_info(struct ablkcipher_request
*req
,
171 struct cpt_request_info
*req_info
)
173 req_info
->callback
= (void *)cvm_callback
;
174 req_info
->callback_arg
= (void *)&req
->base
;
177 static inline void create_output_list(struct ablkcipher_request
*req
,
180 struct cvm_req_ctx
*rctx
= ablkcipher_request_ctx(req
);
181 struct cpt_request_info
*req_info
= &rctx
->cpt_req
;
184 /* OUTPUT Buffer Processing
185 * AES encryption/decryption output would be
186 * received in the following format
188 * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----|
189 * [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ]
191 /* Reading IV information */
192 update_output_iv(req_info
, req
->info
, enc_iv_len
, &argcnt
);
193 update_output_data(req_info
, req
->dst
, req
->nbytes
, &argcnt
);
194 req_info
->outcnt
= argcnt
;
197 static inline int cvm_enc_dec(struct ablkcipher_request
*req
, u32 enc
)
199 struct crypto_ablkcipher
*tfm
= crypto_ablkcipher_reqtfm(req
);
200 struct cvm_req_ctx
*rctx
= ablkcipher_request_ctx(req
);
201 u32 enc_iv_len
= crypto_ablkcipher_ivsize(tfm
);
202 struct fc_context
*fctx
= &rctx
->fctx
;
203 struct cpt_request_info
*req_info
= &rctx
->cpt_req
;
207 memset(req_info
, 0, sizeof(struct cpt_request_info
));
208 memset(fctx
, 0, sizeof(struct fc_context
));
209 create_input_list(req
, enc
, enc_iv_len
);
210 create_output_list(req
, enc_iv_len
);
211 store_cb_info(req
, req_info
);
212 cdev
= dev_handle
.cdev
[smp_processor_id()];
213 status
= cptvf_do_request(cdev
, req_info
);
214 /* We perform an asynchronous send and once
215 * the request is completed the driver would
216 * intimate through registered call back functions
225 static int cvm_encrypt(struct ablkcipher_request
*req
)
227 return cvm_enc_dec(req
, true);
230 static int cvm_decrypt(struct ablkcipher_request
*req
)
232 return cvm_enc_dec(req
, false);
235 static int cvm_xts_setkey(struct crypto_ablkcipher
*cipher
, const u8
*key
,
238 struct crypto_tfm
*tfm
= crypto_ablkcipher_tfm(cipher
);
239 struct cvm_enc_ctx
*ctx
= crypto_tfm_ctx(tfm
);
241 const u8
*key1
= key
;
242 const u8
*key2
= key
+ (keylen
/ 2);
244 err
= xts_check_key(tfm
, key
, keylen
);
247 ctx
->key_len
= keylen
;
248 memcpy(ctx
->enc_key
, key1
, keylen
/ 2);
249 memcpy(ctx
->enc_key
+ KEY2_OFFSET
, key2
, keylen
/ 2);
250 ctx
->cipher_type
= AES_XTS
;
251 switch (ctx
->key_len
) {
253 ctx
->key_type
= AES_128_BIT
;
256 ctx
->key_type
= AES_256_BIT
;
265 static int cvm_validate_keylen(struct cvm_enc_ctx
*ctx
, u32 keylen
)
267 if ((keylen
== 16) || (keylen
== 24) || (keylen
== 32)) {
268 ctx
->key_len
= keylen
;
269 switch (ctx
->key_len
) {
271 ctx
->key_type
= AES_128_BIT
;
274 ctx
->key_type
= AES_192_BIT
;
277 ctx
->key_type
= AES_256_BIT
;
283 if (ctx
->cipher_type
== DES3_CBC
)
292 static int cvm_setkey(struct crypto_ablkcipher
*cipher
, const u8
*key
,
293 u32 keylen
, u8 cipher_type
)
295 struct crypto_tfm
*tfm
= crypto_ablkcipher_tfm(cipher
);
296 struct cvm_enc_ctx
*ctx
= crypto_tfm_ctx(tfm
);
298 ctx
->cipher_type
= cipher_type
;
299 if (!cvm_validate_keylen(ctx
, keylen
)) {
300 memcpy(ctx
->enc_key
, key
, keylen
);
303 crypto_ablkcipher_set_flags(cipher
,
304 CRYPTO_TFM_RES_BAD_KEY_LEN
);
309 static int cvm_cbc_aes_setkey(struct crypto_ablkcipher
*cipher
, const u8
*key
,
312 return cvm_setkey(cipher
, key
, keylen
, AES_CBC
);
315 static int cvm_ecb_aes_setkey(struct crypto_ablkcipher
*cipher
, const u8
*key
,
318 return cvm_setkey(cipher
, key
, keylen
, AES_ECB
);
321 static int cvm_cfb_aes_setkey(struct crypto_ablkcipher
*cipher
, const u8
*key
,
324 return cvm_setkey(cipher
, key
, keylen
, AES_CFB
);
327 static int cvm_cbc_des3_setkey(struct crypto_ablkcipher
*cipher
, const u8
*key
,
330 return cvm_setkey(cipher
, key
, keylen
, DES3_CBC
);
333 static int cvm_ecb_des3_setkey(struct crypto_ablkcipher
*cipher
, const u8
*key
,
336 return cvm_setkey(cipher
, key
, keylen
, DES3_ECB
);
339 static int cvm_enc_dec_init(struct crypto_tfm
*tfm
)
341 struct cvm_enc_ctx
*ctx
= crypto_tfm_ctx(tfm
);
343 memset(ctx
, 0, sizeof(*ctx
));
344 tfm
->crt_ablkcipher
.reqsize
= sizeof(struct cvm_req_ctx
) +
345 sizeof(struct ablkcipher_request
);
346 /* Additional memory for ablkcipher_request is
347 * allocated since the cryptd daemon uses
348 * this memory for request_ctx information
354 static struct crypto_alg algs
[] = { {
355 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
356 .cra_blocksize
= AES_BLOCK_SIZE
,
357 .cra_ctxsize
= sizeof(struct cvm_enc_ctx
),
359 .cra_priority
= 4001,
360 .cra_name
= "xts(aes)",
361 .cra_driver_name
= "cavium-xts-aes",
362 .cra_type
= &crypto_ablkcipher_type
,
365 .ivsize
= AES_BLOCK_SIZE
,
366 .min_keysize
= 2 * AES_MIN_KEY_SIZE
,
367 .max_keysize
= 2 * AES_MAX_KEY_SIZE
,
368 .setkey
= cvm_xts_setkey
,
369 .encrypt
= cvm_encrypt
,
370 .decrypt
= cvm_decrypt
,
373 .cra_init
= cvm_enc_dec_init
,
374 .cra_module
= THIS_MODULE
,
376 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
377 .cra_blocksize
= AES_BLOCK_SIZE
,
378 .cra_ctxsize
= sizeof(struct cvm_enc_ctx
),
380 .cra_priority
= 4001,
381 .cra_name
= "cbc(aes)",
382 .cra_driver_name
= "cavium-cbc-aes",
383 .cra_type
= &crypto_ablkcipher_type
,
386 .ivsize
= AES_BLOCK_SIZE
,
387 .min_keysize
= AES_MIN_KEY_SIZE
,
388 .max_keysize
= AES_MAX_KEY_SIZE
,
389 .setkey
= cvm_cbc_aes_setkey
,
390 .encrypt
= cvm_encrypt
,
391 .decrypt
= cvm_decrypt
,
394 .cra_init
= cvm_enc_dec_init
,
395 .cra_module
= THIS_MODULE
,
397 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
398 .cra_blocksize
= AES_BLOCK_SIZE
,
399 .cra_ctxsize
= sizeof(struct cvm_enc_ctx
),
401 .cra_priority
= 4001,
402 .cra_name
= "ecb(aes)",
403 .cra_driver_name
= "cavium-ecb-aes",
404 .cra_type
= &crypto_ablkcipher_type
,
407 .ivsize
= AES_BLOCK_SIZE
,
408 .min_keysize
= AES_MIN_KEY_SIZE
,
409 .max_keysize
= AES_MAX_KEY_SIZE
,
410 .setkey
= cvm_ecb_aes_setkey
,
411 .encrypt
= cvm_encrypt
,
412 .decrypt
= cvm_decrypt
,
415 .cra_init
= cvm_enc_dec_init
,
416 .cra_module
= THIS_MODULE
,
418 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
419 .cra_blocksize
= AES_BLOCK_SIZE
,
420 .cra_ctxsize
= sizeof(struct cvm_enc_ctx
),
422 .cra_priority
= 4001,
423 .cra_name
= "cfb(aes)",
424 .cra_driver_name
= "cavium-cfb-aes",
425 .cra_type
= &crypto_ablkcipher_type
,
428 .ivsize
= AES_BLOCK_SIZE
,
429 .min_keysize
= AES_MIN_KEY_SIZE
,
430 .max_keysize
= AES_MAX_KEY_SIZE
,
431 .setkey
= cvm_cfb_aes_setkey
,
432 .encrypt
= cvm_encrypt
,
433 .decrypt
= cvm_decrypt
,
436 .cra_init
= cvm_enc_dec_init
,
437 .cra_module
= THIS_MODULE
,
439 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
440 .cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
441 .cra_ctxsize
= sizeof(struct cvm_des3_ctx
),
443 .cra_priority
= 4001,
444 .cra_name
= "cbc(des3_ede)",
445 .cra_driver_name
= "cavium-cbc-des3_ede",
446 .cra_type
= &crypto_ablkcipher_type
,
449 .min_keysize
= DES3_EDE_KEY_SIZE
,
450 .max_keysize
= DES3_EDE_KEY_SIZE
,
451 .ivsize
= DES_BLOCK_SIZE
,
452 .setkey
= cvm_cbc_des3_setkey
,
453 .encrypt
= cvm_encrypt
,
454 .decrypt
= cvm_decrypt
,
457 .cra_init
= cvm_enc_dec_init
,
458 .cra_module
= THIS_MODULE
,
460 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
461 .cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
462 .cra_ctxsize
= sizeof(struct cvm_des3_ctx
),
464 .cra_priority
= 4001,
465 .cra_name
= "ecb(des3_ede)",
466 .cra_driver_name
= "cavium-ecb-des3_ede",
467 .cra_type
= &crypto_ablkcipher_type
,
470 .min_keysize
= DES3_EDE_KEY_SIZE
,
471 .max_keysize
= DES3_EDE_KEY_SIZE
,
472 .ivsize
= DES_BLOCK_SIZE
,
473 .setkey
= cvm_ecb_des3_setkey
,
474 .encrypt
= cvm_encrypt
,
475 .decrypt
= cvm_decrypt
,
478 .cra_init
= cvm_enc_dec_init
,
479 .cra_module
= THIS_MODULE
,
482 static inline int cav_register_algs(void)
486 err
= crypto_register_algs(algs
, ARRAY_SIZE(algs
));
493 static inline void cav_unregister_algs(void)
495 crypto_unregister_algs(algs
, ARRAY_SIZE(algs
));
498 int cvm_crypto_init(struct cpt_vf
*cptvf
)
500 struct pci_dev
*pdev
= cptvf
->pdev
;
503 dev_count
= dev_handle
.dev_count
;
504 dev_handle
.cdev
[dev_count
] = cptvf
;
505 dev_handle
.dev_count
++;
507 if (dev_count
== 3) {
508 if (cav_register_algs()) {
509 dev_err(&pdev
->dev
, "Error in registering crypto algorithms\n");
517 void cvm_crypto_exit(void)
521 dev_count
= --dev_handle
.dev_count
;
523 cav_unregister_algs();