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/des.h>
14 #include <crypto/xts.h>
15 #include <linux/crypto.h>
16 #include <linux/err.h>
17 #include <linux/list.h>
18 #include <linux/scatterlist.h>
21 #include "cptvf_algs.h"
23 struct cpt_device_handle {
24 void *cdev[MAX_DEVICES];
28 static struct cpt_device_handle dev_handle;
30 static void cvm_callback(u32 status, void *arg)
32 struct crypto_async_request *req = (struct crypto_async_request *)arg;
34 req->complete(req, !status);
37 static inline void update_input_iv(struct cpt_request_info *req_info,
38 u8 *iv, u32 enc_iv_len,
41 /* Setting the iv information */
42 req_info->in[*argcnt].vptr = (void *)iv;
43 req_info->in[*argcnt].size = enc_iv_len;
44 req_info->req.dlen += enc_iv_len;
49 static inline void update_output_iv(struct cpt_request_info *req_info,
50 u8 *iv, u32 enc_iv_len,
53 /* Setting the iv information */
54 req_info->out[*argcnt].vptr = (void *)iv;
55 req_info->out[*argcnt].size = enc_iv_len;
56 req_info->rlen += enc_iv_len;
61 static inline void update_input_data(struct cpt_request_info *req_info,
62 struct scatterlist *inp_sg,
63 u32 nbytes, u32 *argcnt)
65 req_info->req.dlen += nbytes;
68 u32 len = min(nbytes, inp_sg->length);
69 u8 *ptr = sg_virt(inp_sg);
71 req_info->in[*argcnt].vptr = (void *)ptr;
72 req_info->in[*argcnt].size = len;
80 static inline void update_output_data(struct cpt_request_info *req_info,
81 struct scatterlist *outp_sg,
82 u32 nbytes, u32 *argcnt)
84 req_info->rlen += nbytes;
87 u32 len = min(nbytes, outp_sg->length);
88 u8 *ptr = sg_virt(outp_sg);
90 req_info->out[*argcnt].vptr = (void *)ptr;
91 req_info->out[*argcnt].size = len;
98 static inline u32 create_ctx_hdr(struct ablkcipher_request *req, u32 enc,
101 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
102 struct cvm_enc_ctx *ctx = crypto_ablkcipher_ctx(tfm);
103 struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
104 struct fc_context *fctx = &rctx->fctx;
105 u64 *offset_control = &rctx->control_word;
106 u32 enc_iv_len = crypto_ablkcipher_ivsize(tfm);
107 struct cpt_request_info *req_info = &rctx->cpt_req;
108 u64 *ctrl_flags = NULL;
110 req_info->ctrl.s.grp = 0;
111 req_info->ctrl.s.dma_mode = DMA_GATHER_SCATTER;
112 req_info->ctrl.s.se_req = SE_CORE_REQ;
114 req_info->req.opcode.s.major = MAJOR_OP_FC |
115 DMA_MODE_FLAG(DMA_GATHER_SCATTER);
117 req_info->req.opcode.s.minor = 2;
119 req_info->req.opcode.s.minor = 3;
121 req_info->req.param1 = req->nbytes; /* Encryption Data length */
122 req_info->req.param2 = 0; /*Auth data length */
124 fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type;
125 fctx->enc.enc_ctrl.e.aes_key = ctx->key_type;
126 fctx->enc.enc_ctrl.e.iv_source = FROM_DPTR;
128 if (ctx->cipher_type == AES_XTS)
129 memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2);
131 memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len);
132 ctrl_flags = (u64 *)&fctx->enc.enc_ctrl.flags;
133 *ctrl_flags = cpu_to_be64(*ctrl_flags);
135 *offset_control = cpu_to_be64(((u64)(enc_iv_len) << 16));
136 /* Storing Packet Data Information in offset
137 * Control Word First 8 bytes
139 req_info->in[*argcnt].vptr = (u8 *)offset_control;
140 req_info->in[*argcnt].size = CONTROL_WORD_LEN;
141 req_info->req.dlen += CONTROL_WORD_LEN;
144 req_info->in[*argcnt].vptr = (u8 *)fctx;
145 req_info->in[*argcnt].size = sizeof(struct fc_context);
146 req_info->req.dlen += sizeof(struct fc_context);
153 static inline u32 create_input_list(struct ablkcipher_request *req, u32 enc,
156 struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
157 struct cpt_request_info *req_info = &rctx->cpt_req;
160 create_ctx_hdr(req, enc, &argcnt);
161 update_input_iv(req_info, req->info, enc_iv_len, &argcnt);
162 update_input_data(req_info, req->src, req->nbytes, &argcnt);
163 req_info->incnt = argcnt;
168 static inline void store_cb_info(struct ablkcipher_request *req,
169 struct cpt_request_info *req_info)
171 req_info->callback = (void *)cvm_callback;
172 req_info->callback_arg = (void *)&req->base;
175 static inline void create_output_list(struct ablkcipher_request *req,
178 struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
179 struct cpt_request_info *req_info = &rctx->cpt_req;
182 /* OUTPUT Buffer Processing
183 * AES encryption/decryption output would be
184 * received in the following format
186 * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----|
187 * [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ]
189 /* Reading IV information */
190 update_output_iv(req_info, req->info, enc_iv_len, &argcnt);
191 update_output_data(req_info, req->dst, req->nbytes, &argcnt);
192 req_info->outcnt = argcnt;
195 static inline int cvm_enc_dec(struct ablkcipher_request *req, u32 enc)
197 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
198 struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
199 u32 enc_iv_len = crypto_ablkcipher_ivsize(tfm);
200 struct fc_context *fctx = &rctx->fctx;
201 struct cpt_request_info *req_info = &rctx->cpt_req;
205 memset(req_info, 0, sizeof(struct cpt_request_info));
206 memset(fctx, 0, sizeof(struct fc_context));
207 create_input_list(req, enc, enc_iv_len);
208 create_output_list(req, enc_iv_len);
209 store_cb_info(req, req_info);
210 cdev = dev_handle.cdev[smp_processor_id()];
211 status = cptvf_do_request(cdev, req_info);
212 /* We perform an asynchronous send and once
213 * the request is completed the driver would
214 * intimate through registered call back functions
223 static int cvm_encrypt(struct ablkcipher_request *req)
225 return cvm_enc_dec(req, true);
228 static int cvm_decrypt(struct ablkcipher_request *req)
230 return cvm_enc_dec(req, false);
233 static int cvm_xts_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
236 struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
237 struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
239 const u8 *key1 = key;
240 const u8 *key2 = key + (keylen / 2);
242 err = xts_check_key(tfm, key, keylen);
245 ctx->key_len = keylen;
246 memcpy(ctx->enc_key, key1, keylen / 2);
247 memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2);
248 ctx->cipher_type = AES_XTS;
249 switch (ctx->key_len) {
251 ctx->key_type = AES_128_BIT;
254 ctx->key_type = AES_256_BIT;
263 static int cvm_validate_keylen(struct cvm_enc_ctx *ctx, u32 keylen)
265 if ((keylen == 16) || (keylen == 24) || (keylen == 32)) {
266 ctx->key_len = keylen;
267 switch (ctx->key_len) {
269 ctx->key_type = AES_128_BIT;
272 ctx->key_type = AES_192_BIT;
275 ctx->key_type = AES_256_BIT;
281 if (ctx->cipher_type == DES3_CBC)
290 static int cvm_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
291 u32 keylen, u8 cipher_type)
293 struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
294 struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
296 ctx->cipher_type = cipher_type;
297 if (!cvm_validate_keylen(ctx, keylen)) {
298 memcpy(ctx->enc_key, key, keylen);
301 crypto_ablkcipher_set_flags(cipher,
302 CRYPTO_TFM_RES_BAD_KEY_LEN);
307 static int cvm_cbc_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
310 return cvm_setkey(cipher, key, keylen, AES_CBC);
313 static int cvm_ecb_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
316 return cvm_setkey(cipher, key, keylen, AES_ECB);
319 static int cvm_cfb_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
322 return cvm_setkey(cipher, key, keylen, AES_CFB);
325 static int cvm_cbc_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
328 u32 flags = crypto_ablkcipher_get_flags(cipher);
331 err = __des3_verify_key(&flags, key);
333 crypto_ablkcipher_set_flags(cipher, flags);
337 return cvm_setkey(cipher, key, keylen, DES3_CBC);
340 static int cvm_ecb_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
343 u32 flags = crypto_ablkcipher_get_flags(cipher);
346 err = __des3_verify_key(&flags, key);
348 crypto_ablkcipher_set_flags(cipher, flags);
352 return cvm_setkey(cipher, key, keylen, DES3_ECB);
355 static int cvm_enc_dec_init(struct crypto_tfm *tfm)
357 tfm->crt_ablkcipher.reqsize = sizeof(struct cvm_req_ctx);
361 static struct crypto_alg algs[] = { {
362 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
363 .cra_blocksize = AES_BLOCK_SIZE,
364 .cra_ctxsize = sizeof(struct cvm_enc_ctx),
366 .cra_priority = 4001,
367 .cra_name = "xts(aes)",
368 .cra_driver_name = "cavium-xts-aes",
369 .cra_type = &crypto_ablkcipher_type,
372 .ivsize = AES_BLOCK_SIZE,
373 .min_keysize = 2 * AES_MIN_KEY_SIZE,
374 .max_keysize = 2 * AES_MAX_KEY_SIZE,
375 .setkey = cvm_xts_setkey,
376 .encrypt = cvm_encrypt,
377 .decrypt = cvm_decrypt,
380 .cra_init = cvm_enc_dec_init,
381 .cra_module = THIS_MODULE,
383 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
384 .cra_blocksize = AES_BLOCK_SIZE,
385 .cra_ctxsize = sizeof(struct cvm_enc_ctx),
387 .cra_priority = 4001,
388 .cra_name = "cbc(aes)",
389 .cra_driver_name = "cavium-cbc-aes",
390 .cra_type = &crypto_ablkcipher_type,
393 .ivsize = AES_BLOCK_SIZE,
394 .min_keysize = AES_MIN_KEY_SIZE,
395 .max_keysize = AES_MAX_KEY_SIZE,
396 .setkey = cvm_cbc_aes_setkey,
397 .encrypt = cvm_encrypt,
398 .decrypt = cvm_decrypt,
401 .cra_init = cvm_enc_dec_init,
402 .cra_module = THIS_MODULE,
404 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
405 .cra_blocksize = AES_BLOCK_SIZE,
406 .cra_ctxsize = sizeof(struct cvm_enc_ctx),
408 .cra_priority = 4001,
409 .cra_name = "ecb(aes)",
410 .cra_driver_name = "cavium-ecb-aes",
411 .cra_type = &crypto_ablkcipher_type,
414 .ivsize = AES_BLOCK_SIZE,
415 .min_keysize = AES_MIN_KEY_SIZE,
416 .max_keysize = AES_MAX_KEY_SIZE,
417 .setkey = cvm_ecb_aes_setkey,
418 .encrypt = cvm_encrypt,
419 .decrypt = cvm_decrypt,
422 .cra_init = cvm_enc_dec_init,
423 .cra_module = THIS_MODULE,
425 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
426 .cra_blocksize = AES_BLOCK_SIZE,
427 .cra_ctxsize = sizeof(struct cvm_enc_ctx),
429 .cra_priority = 4001,
430 .cra_name = "cfb(aes)",
431 .cra_driver_name = "cavium-cfb-aes",
432 .cra_type = &crypto_ablkcipher_type,
435 .ivsize = AES_BLOCK_SIZE,
436 .min_keysize = AES_MIN_KEY_SIZE,
437 .max_keysize = AES_MAX_KEY_SIZE,
438 .setkey = cvm_cfb_aes_setkey,
439 .encrypt = cvm_encrypt,
440 .decrypt = cvm_decrypt,
443 .cra_init = cvm_enc_dec_init,
444 .cra_module = THIS_MODULE,
446 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
447 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
448 .cra_ctxsize = sizeof(struct cvm_des3_ctx),
450 .cra_priority = 4001,
451 .cra_name = "cbc(des3_ede)",
452 .cra_driver_name = "cavium-cbc-des3_ede",
453 .cra_type = &crypto_ablkcipher_type,
456 .min_keysize = DES3_EDE_KEY_SIZE,
457 .max_keysize = DES3_EDE_KEY_SIZE,
458 .ivsize = DES_BLOCK_SIZE,
459 .setkey = cvm_cbc_des3_setkey,
460 .encrypt = cvm_encrypt,
461 .decrypt = cvm_decrypt,
464 .cra_init = cvm_enc_dec_init,
465 .cra_module = THIS_MODULE,
467 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
468 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
469 .cra_ctxsize = sizeof(struct cvm_des3_ctx),
471 .cra_priority = 4001,
472 .cra_name = "ecb(des3_ede)",
473 .cra_driver_name = "cavium-ecb-des3_ede",
474 .cra_type = &crypto_ablkcipher_type,
477 .min_keysize = DES3_EDE_KEY_SIZE,
478 .max_keysize = DES3_EDE_KEY_SIZE,
479 .ivsize = DES_BLOCK_SIZE,
480 .setkey = cvm_ecb_des3_setkey,
481 .encrypt = cvm_encrypt,
482 .decrypt = cvm_decrypt,
485 .cra_init = cvm_enc_dec_init,
486 .cra_module = THIS_MODULE,
489 static inline int cav_register_algs(void)
493 err = crypto_register_algs(algs, ARRAY_SIZE(algs));
500 static inline void cav_unregister_algs(void)
502 crypto_unregister_algs(algs, ARRAY_SIZE(algs));
505 int cvm_crypto_init(struct cpt_vf *cptvf)
507 struct pci_dev *pdev = cptvf->pdev;
510 dev_count = dev_handle.dev_count;
511 dev_handle.cdev[dev_count] = cptvf;
512 dev_handle.dev_count++;
514 if (dev_count == 3) {
515 if (cav_register_algs()) {
516 dev_err(&pdev->dev, "Error in registering crypto algorithms\n");
524 void cvm_crypto_exit(void)
528 dev_count = --dev_handle.dev_count;
530 cav_unregister_algs();