1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2016 Cavium, Inc.
7 #include <crypto/aes.h>
8 #include <crypto/algapi.h>
9 #include <crypto/authenc.h>
10 #include <crypto/internal/des.h>
11 #include <crypto/xts.h>
12 #include <linux/crypto.h>
13 #include <linux/err.h>
14 #include <linux/list.h>
15 #include <linux/scatterlist.h>
18 #include "cptvf_algs.h"
20 struct cpt_device_handle
{
21 void *cdev
[MAX_DEVICES
];
25 static struct cpt_device_handle dev_handle
;
27 static void cvm_callback(u32 status
, void *arg
)
29 struct crypto_async_request
*req
= (struct crypto_async_request
*)arg
;
31 req
->complete(req
, !status
);
34 static inline void update_input_iv(struct cpt_request_info
*req_info
,
35 u8
*iv
, u32 enc_iv_len
,
38 /* Setting the iv information */
39 req_info
->in
[*argcnt
].vptr
= (void *)iv
;
40 req_info
->in
[*argcnt
].size
= enc_iv_len
;
41 req_info
->req
.dlen
+= enc_iv_len
;
46 static inline void update_output_iv(struct cpt_request_info
*req_info
,
47 u8
*iv
, u32 enc_iv_len
,
50 /* Setting the iv information */
51 req_info
->out
[*argcnt
].vptr
= (void *)iv
;
52 req_info
->out
[*argcnt
].size
= enc_iv_len
;
53 req_info
->rlen
+= enc_iv_len
;
58 static inline void update_input_data(struct cpt_request_info
*req_info
,
59 struct scatterlist
*inp_sg
,
60 u32 nbytes
, u32
*argcnt
)
62 req_info
->req
.dlen
+= nbytes
;
65 u32 len
= min(nbytes
, inp_sg
->length
);
66 u8
*ptr
= sg_virt(inp_sg
);
68 req_info
->in
[*argcnt
].vptr
= (void *)ptr
;
69 req_info
->in
[*argcnt
].size
= len
;
77 static inline void update_output_data(struct cpt_request_info
*req_info
,
78 struct scatterlist
*outp_sg
,
79 u32 nbytes
, u32
*argcnt
)
81 req_info
->rlen
+= nbytes
;
84 u32 len
= min(nbytes
, outp_sg
->length
);
85 u8
*ptr
= sg_virt(outp_sg
);
87 req_info
->out
[*argcnt
].vptr
= (void *)ptr
;
88 req_info
->out
[*argcnt
].size
= len
;
95 static inline u32
create_ctx_hdr(struct skcipher_request
*req
, u32 enc
,
98 struct crypto_skcipher
*tfm
= crypto_skcipher_reqtfm(req
);
99 struct cvm_enc_ctx
*ctx
= crypto_skcipher_ctx(tfm
);
100 struct cvm_req_ctx
*rctx
= skcipher_request_ctx(req
);
101 struct fc_context
*fctx
= &rctx
->fctx
;
102 u64
*offset_control
= &rctx
->control_word
;
103 u32 enc_iv_len
= crypto_skcipher_ivsize(tfm
);
104 struct cpt_request_info
*req_info
= &rctx
->cpt_req
;
105 u64
*ctrl_flags
= NULL
;
107 req_info
->ctrl
.s
.grp
= 0;
108 req_info
->ctrl
.s
.dma_mode
= DMA_GATHER_SCATTER
;
109 req_info
->ctrl
.s
.se_req
= SE_CORE_REQ
;
111 req_info
->req
.opcode
.s
.major
= MAJOR_OP_FC
|
112 DMA_MODE_FLAG(DMA_GATHER_SCATTER
);
114 req_info
->req
.opcode
.s
.minor
= 2;
116 req_info
->req
.opcode
.s
.minor
= 3;
118 req_info
->req
.param1
= req
->cryptlen
; /* Encryption Data length */
119 req_info
->req
.param2
= 0; /*Auth data length */
121 fctx
->enc
.enc_ctrl
.e
.enc_cipher
= ctx
->cipher_type
;
122 fctx
->enc
.enc_ctrl
.e
.aes_key
= ctx
->key_type
;
123 fctx
->enc
.enc_ctrl
.e
.iv_source
= FROM_DPTR
;
125 if (ctx
->cipher_type
== AES_XTS
)
126 memcpy(fctx
->enc
.encr_key
, ctx
->enc_key
, ctx
->key_len
* 2);
128 memcpy(fctx
->enc
.encr_key
, ctx
->enc_key
, ctx
->key_len
);
129 ctrl_flags
= (u64
*)&fctx
->enc
.enc_ctrl
.flags
;
130 *ctrl_flags
= cpu_to_be64(*ctrl_flags
);
132 *offset_control
= cpu_to_be64(((u64
)(enc_iv_len
) << 16));
133 /* Storing Packet Data Information in offset
134 * Control Word First 8 bytes
136 req_info
->in
[*argcnt
].vptr
= (u8
*)offset_control
;
137 req_info
->in
[*argcnt
].size
= CONTROL_WORD_LEN
;
138 req_info
->req
.dlen
+= CONTROL_WORD_LEN
;
141 req_info
->in
[*argcnt
].vptr
= (u8
*)fctx
;
142 req_info
->in
[*argcnt
].size
= sizeof(struct fc_context
);
143 req_info
->req
.dlen
+= sizeof(struct fc_context
);
150 static inline u32
create_input_list(struct skcipher_request
*req
, u32 enc
,
153 struct cvm_req_ctx
*rctx
= skcipher_request_ctx(req
);
154 struct cpt_request_info
*req_info
= &rctx
->cpt_req
;
157 create_ctx_hdr(req
, enc
, &argcnt
);
158 update_input_iv(req_info
, req
->iv
, enc_iv_len
, &argcnt
);
159 update_input_data(req_info
, req
->src
, req
->cryptlen
, &argcnt
);
160 req_info
->incnt
= argcnt
;
165 static inline void store_cb_info(struct skcipher_request
*req
,
166 struct cpt_request_info
*req_info
)
168 req_info
->callback
= (void *)cvm_callback
;
169 req_info
->callback_arg
= (void *)&req
->base
;
172 static inline void create_output_list(struct skcipher_request
*req
,
175 struct cvm_req_ctx
*rctx
= skcipher_request_ctx(req
);
176 struct cpt_request_info
*req_info
= &rctx
->cpt_req
;
179 /* OUTPUT Buffer Processing
180 * AES encryption/decryption output would be
181 * received in the following format
183 * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----|
184 * [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ]
186 /* Reading IV information */
187 update_output_iv(req_info
, req
->iv
, enc_iv_len
, &argcnt
);
188 update_output_data(req_info
, req
->dst
, req
->cryptlen
, &argcnt
);
189 req_info
->outcnt
= argcnt
;
192 static inline int cvm_enc_dec(struct skcipher_request
*req
, u32 enc
)
194 struct crypto_skcipher
*tfm
= crypto_skcipher_reqtfm(req
);
195 struct cvm_req_ctx
*rctx
= skcipher_request_ctx(req
);
196 u32 enc_iv_len
= crypto_skcipher_ivsize(tfm
);
197 struct fc_context
*fctx
= &rctx
->fctx
;
198 struct cpt_request_info
*req_info
= &rctx
->cpt_req
;
202 memset(req_info
, 0, sizeof(struct cpt_request_info
));
203 memset(fctx
, 0, sizeof(struct fc_context
));
204 create_input_list(req
, enc
, enc_iv_len
);
205 create_output_list(req
, enc_iv_len
);
206 store_cb_info(req
, req_info
);
207 cdev
= dev_handle
.cdev
[smp_processor_id()];
208 status
= cptvf_do_request(cdev
, req_info
);
209 /* We perform an asynchronous send and once
210 * the request is completed the driver would
211 * intimate through registered call back functions
220 static int cvm_encrypt(struct skcipher_request
*req
)
222 return cvm_enc_dec(req
, true);
225 static int cvm_decrypt(struct skcipher_request
*req
)
227 return cvm_enc_dec(req
, false);
230 static int cvm_xts_setkey(struct crypto_skcipher
*cipher
, const u8
*key
,
233 struct crypto_tfm
*tfm
= crypto_skcipher_tfm(cipher
);
234 struct cvm_enc_ctx
*ctx
= crypto_tfm_ctx(tfm
);
236 const u8
*key1
= key
;
237 const u8
*key2
= key
+ (keylen
/ 2);
239 err
= xts_check_key(tfm
, key
, keylen
);
242 ctx
->key_len
= keylen
;
243 memcpy(ctx
->enc_key
, key1
, keylen
/ 2);
244 memcpy(ctx
->enc_key
+ KEY2_OFFSET
, key2
, keylen
/ 2);
245 ctx
->cipher_type
= AES_XTS
;
246 switch (ctx
->key_len
) {
248 ctx
->key_type
= AES_128_BIT
;
251 ctx
->key_type
= AES_256_BIT
;
260 static int cvm_validate_keylen(struct cvm_enc_ctx
*ctx
, u32 keylen
)
262 if ((keylen
== 16) || (keylen
== 24) || (keylen
== 32)) {
263 ctx
->key_len
= keylen
;
264 switch (ctx
->key_len
) {
266 ctx
->key_type
= AES_128_BIT
;
269 ctx
->key_type
= AES_192_BIT
;
272 ctx
->key_type
= AES_256_BIT
;
278 if (ctx
->cipher_type
== DES3_CBC
)
287 static int cvm_setkey(struct crypto_skcipher
*cipher
, const u8
*key
,
288 u32 keylen
, u8 cipher_type
)
290 struct crypto_tfm
*tfm
= crypto_skcipher_tfm(cipher
);
291 struct cvm_enc_ctx
*ctx
= crypto_tfm_ctx(tfm
);
293 ctx
->cipher_type
= cipher_type
;
294 if (!cvm_validate_keylen(ctx
, keylen
)) {
295 memcpy(ctx
->enc_key
, key
, keylen
);
302 static int cvm_cbc_aes_setkey(struct crypto_skcipher
*cipher
, const u8
*key
,
305 return cvm_setkey(cipher
, key
, keylen
, AES_CBC
);
308 static int cvm_ecb_aes_setkey(struct crypto_skcipher
*cipher
, const u8
*key
,
311 return cvm_setkey(cipher
, key
, keylen
, AES_ECB
);
314 static int cvm_cfb_aes_setkey(struct crypto_skcipher
*cipher
, const u8
*key
,
317 return cvm_setkey(cipher
, key
, keylen
, AES_CFB
);
320 static int cvm_cbc_des3_setkey(struct crypto_skcipher
*cipher
, const u8
*key
,
323 return verify_skcipher_des3_key(cipher
, key
) ?:
324 cvm_setkey(cipher
, key
, keylen
, DES3_CBC
);
327 static int cvm_ecb_des3_setkey(struct crypto_skcipher
*cipher
, const u8
*key
,
330 return verify_skcipher_des3_key(cipher
, key
) ?:
331 cvm_setkey(cipher
, key
, keylen
, DES3_ECB
);
334 static int cvm_enc_dec_init(struct crypto_skcipher
*tfm
)
336 crypto_skcipher_set_reqsize(tfm
, sizeof(struct cvm_req_ctx
));
341 static struct skcipher_alg algs
[] = { {
342 .base
.cra_flags
= CRYPTO_ALG_ASYNC
,
343 .base
.cra_blocksize
= AES_BLOCK_SIZE
,
344 .base
.cra_ctxsize
= sizeof(struct cvm_enc_ctx
),
345 .base
.cra_alignmask
= 7,
346 .base
.cra_priority
= 4001,
347 .base
.cra_name
= "xts(aes)",
348 .base
.cra_driver_name
= "cavium-xts-aes",
349 .base
.cra_module
= THIS_MODULE
,
351 .ivsize
= AES_BLOCK_SIZE
,
352 .min_keysize
= 2 * AES_MIN_KEY_SIZE
,
353 .max_keysize
= 2 * AES_MAX_KEY_SIZE
,
354 .setkey
= cvm_xts_setkey
,
355 .encrypt
= cvm_encrypt
,
356 .decrypt
= cvm_decrypt
,
357 .init
= cvm_enc_dec_init
,
359 .base
.cra_flags
= CRYPTO_ALG_ASYNC
,
360 .base
.cra_blocksize
= AES_BLOCK_SIZE
,
361 .base
.cra_ctxsize
= sizeof(struct cvm_enc_ctx
),
362 .base
.cra_alignmask
= 7,
363 .base
.cra_priority
= 4001,
364 .base
.cra_name
= "cbc(aes)",
365 .base
.cra_driver_name
= "cavium-cbc-aes",
366 .base
.cra_module
= THIS_MODULE
,
368 .ivsize
= AES_BLOCK_SIZE
,
369 .min_keysize
= AES_MIN_KEY_SIZE
,
370 .max_keysize
= AES_MAX_KEY_SIZE
,
371 .setkey
= cvm_cbc_aes_setkey
,
372 .encrypt
= cvm_encrypt
,
373 .decrypt
= cvm_decrypt
,
374 .init
= cvm_enc_dec_init
,
376 .base
.cra_flags
= CRYPTO_ALG_ASYNC
,
377 .base
.cra_blocksize
= AES_BLOCK_SIZE
,
378 .base
.cra_ctxsize
= sizeof(struct cvm_enc_ctx
),
379 .base
.cra_alignmask
= 7,
380 .base
.cra_priority
= 4001,
381 .base
.cra_name
= "ecb(aes)",
382 .base
.cra_driver_name
= "cavium-ecb-aes",
383 .base
.cra_module
= THIS_MODULE
,
385 .min_keysize
= AES_MIN_KEY_SIZE
,
386 .max_keysize
= AES_MAX_KEY_SIZE
,
387 .setkey
= cvm_ecb_aes_setkey
,
388 .encrypt
= cvm_encrypt
,
389 .decrypt
= cvm_decrypt
,
390 .init
= cvm_enc_dec_init
,
392 .base
.cra_flags
= CRYPTO_ALG_ASYNC
,
393 .base
.cra_blocksize
= AES_BLOCK_SIZE
,
394 .base
.cra_ctxsize
= sizeof(struct cvm_enc_ctx
),
395 .base
.cra_alignmask
= 7,
396 .base
.cra_priority
= 4001,
397 .base
.cra_name
= "cfb(aes)",
398 .base
.cra_driver_name
= "cavium-cfb-aes",
399 .base
.cra_module
= THIS_MODULE
,
401 .ivsize
= AES_BLOCK_SIZE
,
402 .min_keysize
= AES_MIN_KEY_SIZE
,
403 .max_keysize
= AES_MAX_KEY_SIZE
,
404 .setkey
= cvm_cfb_aes_setkey
,
405 .encrypt
= cvm_encrypt
,
406 .decrypt
= cvm_decrypt
,
407 .init
= cvm_enc_dec_init
,
409 .base
.cra_flags
= CRYPTO_ALG_ASYNC
,
410 .base
.cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
411 .base
.cra_ctxsize
= sizeof(struct cvm_des3_ctx
),
412 .base
.cra_alignmask
= 7,
413 .base
.cra_priority
= 4001,
414 .base
.cra_name
= "cbc(des3_ede)",
415 .base
.cra_driver_name
= "cavium-cbc-des3_ede",
416 .base
.cra_module
= THIS_MODULE
,
418 .min_keysize
= DES3_EDE_KEY_SIZE
,
419 .max_keysize
= DES3_EDE_KEY_SIZE
,
420 .ivsize
= DES_BLOCK_SIZE
,
421 .setkey
= cvm_cbc_des3_setkey
,
422 .encrypt
= cvm_encrypt
,
423 .decrypt
= cvm_decrypt
,
424 .init
= cvm_enc_dec_init
,
426 .base
.cra_flags
= CRYPTO_ALG_ASYNC
,
427 .base
.cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
428 .base
.cra_ctxsize
= sizeof(struct cvm_des3_ctx
),
429 .base
.cra_alignmask
= 7,
430 .base
.cra_priority
= 4001,
431 .base
.cra_name
= "ecb(des3_ede)",
432 .base
.cra_driver_name
= "cavium-ecb-des3_ede",
433 .base
.cra_module
= THIS_MODULE
,
435 .min_keysize
= DES3_EDE_KEY_SIZE
,
436 .max_keysize
= DES3_EDE_KEY_SIZE
,
437 .ivsize
= DES_BLOCK_SIZE
,
438 .setkey
= cvm_ecb_des3_setkey
,
439 .encrypt
= cvm_encrypt
,
440 .decrypt
= cvm_decrypt
,
441 .init
= cvm_enc_dec_init
,
444 static inline int cav_register_algs(void)
448 err
= crypto_register_skciphers(algs
, ARRAY_SIZE(algs
));
455 static inline void cav_unregister_algs(void)
457 crypto_unregister_skciphers(algs
, ARRAY_SIZE(algs
));
460 int cvm_crypto_init(struct cpt_vf
*cptvf
)
462 struct pci_dev
*pdev
= cptvf
->pdev
;
465 dev_count
= dev_handle
.dev_count
;
466 dev_handle
.cdev
[dev_count
] = cptvf
;
467 dev_handle
.dev_count
++;
469 if (dev_count
== 3) {
470 if (cav_register_algs()) {
471 dev_err(&pdev
->dev
, "Error in registering crypto algorithms\n");
479 void cvm_crypto_exit(void)
483 dev_count
= --dev_handle
.dev_count
;
485 cav_unregister_algs();