125763b3cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2c694b233SGeorge Cherian 3c694b233SGeorge Cherian /* 4c694b233SGeorge Cherian * Copyright (C) 2016 Cavium, Inc. 5c694b233SGeorge Cherian */ 6c694b233SGeorge Cherian 7c694b233SGeorge Cherian #include <crypto/aes.h> 8c694b233SGeorge Cherian #include <crypto/algapi.h> 9c694b233SGeorge Cherian #include <crypto/authenc.h> 100e1cbe97SArd Biesheuvel #include <crypto/internal/des.h> 11c694b233SGeorge Cherian #include <crypto/xts.h> 12c694b233SGeorge Cherian #include <linux/crypto.h> 13c694b233SGeorge Cherian #include <linux/err.h> 14c694b233SGeorge Cherian #include <linux/list.h> 15c694b233SGeorge Cherian #include <linux/scatterlist.h> 16c694b233SGeorge Cherian 17c694b233SGeorge Cherian #include "cptvf.h" 18c694b233SGeorge Cherian #include "cptvf_algs.h" 19c694b233SGeorge Cherian 20c694b233SGeorge Cherian struct cpt_device_handle { 21c694b233SGeorge Cherian void *cdev[MAX_DEVICES]; 22c694b233SGeorge Cherian u32 dev_count; 23c694b233SGeorge Cherian }; 24c694b233SGeorge Cherian 25c694b233SGeorge Cherian static struct cpt_device_handle dev_handle; 26c694b233SGeorge Cherian 27c694b233SGeorge Cherian static void cvm_callback(u32 status, void *arg) 28c694b233SGeorge Cherian { 29c694b233SGeorge Cherian struct crypto_async_request *req = (struct crypto_async_request *)arg; 30c694b233SGeorge Cherian 31c694b233SGeorge Cherian req->complete(req, !status); 32c694b233SGeorge Cherian } 33c694b233SGeorge Cherian 34c694b233SGeorge Cherian static inline void update_input_iv(struct cpt_request_info *req_info, 35c694b233SGeorge Cherian u8 *iv, u32 enc_iv_len, 36c694b233SGeorge Cherian u32 *argcnt) 37c694b233SGeorge Cherian { 38c694b233SGeorge Cherian /* Setting the iv information */ 39c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (void *)iv; 40c694b233SGeorge Cherian req_info->in[*argcnt].size = enc_iv_len; 41c694b233SGeorge Cherian req_info->req.dlen += enc_iv_len; 42c694b233SGeorge Cherian 43c694b233SGeorge Cherian ++(*argcnt); 44c694b233SGeorge Cherian } 45c694b233SGeorge Cherian 46c694b233SGeorge Cherian static inline void update_output_iv(struct cpt_request_info *req_info, 47c694b233SGeorge Cherian u8 *iv, u32 enc_iv_len, 48c694b233SGeorge Cherian u32 *argcnt) 49c694b233SGeorge Cherian { 50c694b233SGeorge Cherian /* Setting the iv information */ 51c694b233SGeorge Cherian req_info->out[*argcnt].vptr = (void *)iv; 52c694b233SGeorge Cherian req_info->out[*argcnt].size = enc_iv_len; 53c694b233SGeorge Cherian req_info->rlen += enc_iv_len; 54c694b233SGeorge Cherian 55c694b233SGeorge Cherian ++(*argcnt); 56c694b233SGeorge Cherian } 57c694b233SGeorge Cherian 58c694b233SGeorge Cherian static inline void update_input_data(struct cpt_request_info *req_info, 59c694b233SGeorge Cherian struct scatterlist *inp_sg, 60c694b233SGeorge Cherian u32 nbytes, u32 *argcnt) 61c694b233SGeorge Cherian { 62c694b233SGeorge Cherian req_info->req.dlen += nbytes; 63c694b233SGeorge Cherian 64c694b233SGeorge Cherian while (nbytes) { 65c694b233SGeorge Cherian u32 len = min(nbytes, inp_sg->length); 66c694b233SGeorge Cherian u8 *ptr = sg_virt(inp_sg); 67c694b233SGeorge Cherian 68c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (void *)ptr; 69c694b233SGeorge Cherian req_info->in[*argcnt].size = len; 70c694b233SGeorge Cherian nbytes -= len; 71c694b233SGeorge Cherian 72c694b233SGeorge Cherian ++(*argcnt); 73c694b233SGeorge Cherian ++inp_sg; 74c694b233SGeorge Cherian } 75c694b233SGeorge Cherian } 76c694b233SGeorge Cherian 77c694b233SGeorge Cherian static inline void update_output_data(struct cpt_request_info *req_info, 78c694b233SGeorge Cherian struct scatterlist *outp_sg, 79c694b233SGeorge Cherian u32 nbytes, u32 *argcnt) 80c694b233SGeorge Cherian { 81c694b233SGeorge Cherian req_info->rlen += nbytes; 82c694b233SGeorge Cherian 83c694b233SGeorge Cherian while (nbytes) { 84c694b233SGeorge Cherian u32 len = min(nbytes, outp_sg->length); 85c694b233SGeorge Cherian u8 *ptr = sg_virt(outp_sg); 86c694b233SGeorge Cherian 87c694b233SGeorge Cherian req_info->out[*argcnt].vptr = (void *)ptr; 88c694b233SGeorge Cherian req_info->out[*argcnt].size = len; 89c694b233SGeorge Cherian nbytes -= len; 90c694b233SGeorge Cherian ++(*argcnt); 91c694b233SGeorge Cherian ++outp_sg; 92c694b233SGeorge Cherian } 93c694b233SGeorge Cherian } 94c694b233SGeorge Cherian 95*ac0d3d13SArd Biesheuvel static inline u32 create_ctx_hdr(struct skcipher_request *req, u32 enc, 96c694b233SGeorge Cherian u32 *argcnt) 97c694b233SGeorge Cherian { 98*ac0d3d13SArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 99*ac0d3d13SArd Biesheuvel struct cvm_enc_ctx *ctx = crypto_skcipher_ctx(tfm); 100*ac0d3d13SArd Biesheuvel struct cvm_req_ctx *rctx = skcipher_request_ctx(req); 101c694b233SGeorge Cherian struct fc_context *fctx = &rctx->fctx; 102c694b233SGeorge Cherian u64 *offset_control = &rctx->control_word; 103*ac0d3d13SArd Biesheuvel u32 enc_iv_len = crypto_skcipher_ivsize(tfm); 104c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 105c694b233SGeorge Cherian u64 *ctrl_flags = NULL; 106c694b233SGeorge Cherian 107c694b233SGeorge Cherian req_info->ctrl.s.grp = 0; 108c694b233SGeorge Cherian req_info->ctrl.s.dma_mode = DMA_GATHER_SCATTER; 109c694b233SGeorge Cherian req_info->ctrl.s.se_req = SE_CORE_REQ; 110c694b233SGeorge Cherian 111c694b233SGeorge Cherian req_info->req.opcode.s.major = MAJOR_OP_FC | 112c694b233SGeorge Cherian DMA_MODE_FLAG(DMA_GATHER_SCATTER); 113c694b233SGeorge Cherian if (enc) 114c694b233SGeorge Cherian req_info->req.opcode.s.minor = 2; 115c694b233SGeorge Cherian else 116c694b233SGeorge Cherian req_info->req.opcode.s.minor = 3; 117c694b233SGeorge Cherian 118*ac0d3d13SArd Biesheuvel req_info->req.param1 = req->cryptlen; /* Encryption Data length */ 119c694b233SGeorge Cherian req_info->req.param2 = 0; /*Auth data length */ 120c694b233SGeorge Cherian 121e2eb769eSGeorge Cherian fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type; 122e2eb769eSGeorge Cherian fctx->enc.enc_ctrl.e.aes_key = ctx->key_type; 123c694b233SGeorge Cherian fctx->enc.enc_ctrl.e.iv_source = FROM_DPTR; 124c694b233SGeorge Cherian 125e2eb769eSGeorge Cherian if (ctx->cipher_type == AES_XTS) 126c694b233SGeorge Cherian memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2); 127c694b233SGeorge Cherian else 128c694b233SGeorge Cherian memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len); 129c694b233SGeorge Cherian ctrl_flags = (u64 *)&fctx->enc.enc_ctrl.flags; 130c694b233SGeorge Cherian *ctrl_flags = cpu_to_be64(*ctrl_flags); 131c694b233SGeorge Cherian 132c694b233SGeorge Cherian *offset_control = cpu_to_be64(((u64)(enc_iv_len) << 16)); 133c694b233SGeorge Cherian /* Storing Packet Data Information in offset 134c694b233SGeorge Cherian * Control Word First 8 bytes 135c694b233SGeorge Cherian */ 136c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (u8 *)offset_control; 137c694b233SGeorge Cherian req_info->in[*argcnt].size = CONTROL_WORD_LEN; 138c694b233SGeorge Cherian req_info->req.dlen += CONTROL_WORD_LEN; 139c694b233SGeorge Cherian ++(*argcnt); 140c694b233SGeorge Cherian 141c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (u8 *)fctx; 142c694b233SGeorge Cherian req_info->in[*argcnt].size = sizeof(struct fc_context); 143c694b233SGeorge Cherian req_info->req.dlen += sizeof(struct fc_context); 144c694b233SGeorge Cherian 145c694b233SGeorge Cherian ++(*argcnt); 146c694b233SGeorge Cherian 147c694b233SGeorge Cherian return 0; 148c694b233SGeorge Cherian } 149c694b233SGeorge Cherian 150*ac0d3d13SArd Biesheuvel static inline u32 create_input_list(struct skcipher_request *req, u32 enc, 151c694b233SGeorge Cherian u32 enc_iv_len) 152c694b233SGeorge Cherian { 153*ac0d3d13SArd Biesheuvel struct cvm_req_ctx *rctx = skcipher_request_ctx(req); 154c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 155c694b233SGeorge Cherian u32 argcnt = 0; 156c694b233SGeorge Cherian 157e2eb769eSGeorge Cherian create_ctx_hdr(req, enc, &argcnt); 158*ac0d3d13SArd Biesheuvel update_input_iv(req_info, req->iv, enc_iv_len, &argcnt); 159*ac0d3d13SArd Biesheuvel update_input_data(req_info, req->src, req->cryptlen, &argcnt); 160c694b233SGeorge Cherian req_info->incnt = argcnt; 161c694b233SGeorge Cherian 162c694b233SGeorge Cherian return 0; 163c694b233SGeorge Cherian } 164c694b233SGeorge Cherian 165*ac0d3d13SArd Biesheuvel static inline void store_cb_info(struct skcipher_request *req, 166c694b233SGeorge Cherian struct cpt_request_info *req_info) 167c694b233SGeorge Cherian { 168c694b233SGeorge Cherian req_info->callback = (void *)cvm_callback; 169c694b233SGeorge Cherian req_info->callback_arg = (void *)&req->base; 170c694b233SGeorge Cherian } 171c694b233SGeorge Cherian 172*ac0d3d13SArd Biesheuvel static inline void create_output_list(struct skcipher_request *req, 173c694b233SGeorge Cherian u32 enc_iv_len) 174c694b233SGeorge Cherian { 175*ac0d3d13SArd Biesheuvel struct cvm_req_ctx *rctx = skcipher_request_ctx(req); 176c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 177c694b233SGeorge Cherian u32 argcnt = 0; 178c694b233SGeorge Cherian 179c694b233SGeorge Cherian /* OUTPUT Buffer Processing 180c694b233SGeorge Cherian * AES encryption/decryption output would be 181c694b233SGeorge Cherian * received in the following format 182c694b233SGeorge Cherian * 183c694b233SGeorge Cherian * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----| 184c694b233SGeorge Cherian * [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ] 185c694b233SGeorge Cherian */ 186c694b233SGeorge Cherian /* Reading IV information */ 187*ac0d3d13SArd Biesheuvel update_output_iv(req_info, req->iv, enc_iv_len, &argcnt); 188*ac0d3d13SArd Biesheuvel update_output_data(req_info, req->dst, req->cryptlen, &argcnt); 189c694b233SGeorge Cherian req_info->outcnt = argcnt; 190c694b233SGeorge Cherian } 191c694b233SGeorge Cherian 192*ac0d3d13SArd Biesheuvel static inline int cvm_enc_dec(struct skcipher_request *req, u32 enc) 193c694b233SGeorge Cherian { 194*ac0d3d13SArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 195*ac0d3d13SArd Biesheuvel struct cvm_req_ctx *rctx = skcipher_request_ctx(req); 196*ac0d3d13SArd Biesheuvel u32 enc_iv_len = crypto_skcipher_ivsize(tfm); 197c694b233SGeorge Cherian struct fc_context *fctx = &rctx->fctx; 198c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 199c694b233SGeorge Cherian void *cdev = NULL; 200c694b233SGeorge Cherian int status; 201c694b233SGeorge Cherian 202c694b233SGeorge Cherian memset(req_info, 0, sizeof(struct cpt_request_info)); 203c694b233SGeorge Cherian memset(fctx, 0, sizeof(struct fc_context)); 204e2eb769eSGeorge Cherian create_input_list(req, enc, enc_iv_len); 205e2eb769eSGeorge Cherian create_output_list(req, enc_iv_len); 206c694b233SGeorge Cherian store_cb_info(req, req_info); 207c694b233SGeorge Cherian cdev = dev_handle.cdev[smp_processor_id()]; 208c694b233SGeorge Cherian status = cptvf_do_request(cdev, req_info); 209c694b233SGeorge Cherian /* We perform an asynchronous send and once 210c694b233SGeorge Cherian * the request is completed the driver would 211c694b233SGeorge Cherian * intimate through registered call back functions 212c694b233SGeorge Cherian */ 213c694b233SGeorge Cherian 214c694b233SGeorge Cherian if (status) 215c694b233SGeorge Cherian return status; 216c694b233SGeorge Cherian else 217c694b233SGeorge Cherian return -EINPROGRESS; 218c694b233SGeorge Cherian } 219c694b233SGeorge Cherian 220*ac0d3d13SArd Biesheuvel static int cvm_encrypt(struct skcipher_request *req) 221c694b233SGeorge Cherian { 222e2eb769eSGeorge Cherian return cvm_enc_dec(req, true); 223c694b233SGeorge Cherian } 224c694b233SGeorge Cherian 225*ac0d3d13SArd Biesheuvel static int cvm_decrypt(struct skcipher_request *req) 226c694b233SGeorge Cherian { 227e2eb769eSGeorge Cherian return cvm_enc_dec(req, false); 228c694b233SGeorge Cherian } 229c694b233SGeorge Cherian 230*ac0d3d13SArd Biesheuvel static int cvm_xts_setkey(struct crypto_skcipher *cipher, const u8 *key, 231c694b233SGeorge Cherian u32 keylen) 232c694b233SGeorge Cherian { 233*ac0d3d13SArd Biesheuvel struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); 234c694b233SGeorge Cherian struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm); 235c694b233SGeorge Cherian int err; 236c694b233SGeorge Cherian const u8 *key1 = key; 237c694b233SGeorge Cherian const u8 *key2 = key + (keylen / 2); 238c694b233SGeorge Cherian 239c694b233SGeorge Cherian err = xts_check_key(tfm, key, keylen); 240c694b233SGeorge Cherian if (err) 241c694b233SGeorge Cherian return err; 242c694b233SGeorge Cherian ctx->key_len = keylen; 243c694b233SGeorge Cherian memcpy(ctx->enc_key, key1, keylen / 2); 244c694b233SGeorge Cherian memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2); 245e2eb769eSGeorge Cherian ctx->cipher_type = AES_XTS; 246e2eb769eSGeorge Cherian switch (ctx->key_len) { 247e2eb769eSGeorge Cherian case 32: 248e2eb769eSGeorge Cherian ctx->key_type = AES_128_BIT; 249e2eb769eSGeorge Cherian break; 250e2eb769eSGeorge Cherian case 64: 251e2eb769eSGeorge Cherian ctx->key_type = AES_256_BIT; 252e2eb769eSGeorge Cherian break; 253e2eb769eSGeorge Cherian default: 254e2eb769eSGeorge Cherian return -EINVAL; 255e2eb769eSGeorge Cherian } 256c694b233SGeorge Cherian 257c694b233SGeorge Cherian return 0; 258c694b233SGeorge Cherian } 259c694b233SGeorge Cherian 260e2eb769eSGeorge Cherian static int cvm_validate_keylen(struct cvm_enc_ctx *ctx, u32 keylen) 261e2eb769eSGeorge Cherian { 262e2eb769eSGeorge Cherian if ((keylen == 16) || (keylen == 24) || (keylen == 32)) { 263e2eb769eSGeorge Cherian ctx->key_len = keylen; 264e2eb769eSGeorge Cherian switch (ctx->key_len) { 265e2eb769eSGeorge Cherian case 16: 266e2eb769eSGeorge Cherian ctx->key_type = AES_128_BIT; 267e2eb769eSGeorge Cherian break; 268e2eb769eSGeorge Cherian case 24: 269e2eb769eSGeorge Cherian ctx->key_type = AES_192_BIT; 270e2eb769eSGeorge Cherian break; 271e2eb769eSGeorge Cherian case 32: 272e2eb769eSGeorge Cherian ctx->key_type = AES_256_BIT; 273e2eb769eSGeorge Cherian break; 274e2eb769eSGeorge Cherian default: 275e2eb769eSGeorge Cherian return -EINVAL; 276e2eb769eSGeorge Cherian } 277e2eb769eSGeorge Cherian 278e2eb769eSGeorge Cherian if (ctx->cipher_type == DES3_CBC) 279e2eb769eSGeorge Cherian ctx->key_type = 0; 280e2eb769eSGeorge Cherian 281e2eb769eSGeorge Cherian return 0; 282e2eb769eSGeorge Cherian } 283e2eb769eSGeorge Cherian 284e2eb769eSGeorge Cherian return -EINVAL; 285e2eb769eSGeorge Cherian } 286e2eb769eSGeorge Cherian 287*ac0d3d13SArd Biesheuvel static int cvm_setkey(struct crypto_skcipher *cipher, const u8 *key, 288e2eb769eSGeorge Cherian u32 keylen, u8 cipher_type) 289c694b233SGeorge Cherian { 290*ac0d3d13SArd Biesheuvel struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); 291c694b233SGeorge Cherian struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm); 292c694b233SGeorge Cherian 293e2eb769eSGeorge Cherian ctx->cipher_type = cipher_type; 294e2eb769eSGeorge Cherian if (!cvm_validate_keylen(ctx, keylen)) { 295c694b233SGeorge Cherian memcpy(ctx->enc_key, key, keylen); 296c694b233SGeorge Cherian return 0; 297e2eb769eSGeorge Cherian } else { 298*ac0d3d13SArd Biesheuvel crypto_skcipher_set_flags(cipher, 299e2eb769eSGeorge Cherian CRYPTO_TFM_RES_BAD_KEY_LEN); 300c694b233SGeorge Cherian return -EINVAL; 301c694b233SGeorge Cherian } 302e2eb769eSGeorge Cherian } 303e2eb769eSGeorge Cherian 304*ac0d3d13SArd Biesheuvel static int cvm_cbc_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, 305e2eb769eSGeorge Cherian u32 keylen) 306e2eb769eSGeorge Cherian { 307e2eb769eSGeorge Cherian return cvm_setkey(cipher, key, keylen, AES_CBC); 308e2eb769eSGeorge Cherian } 309e2eb769eSGeorge Cherian 310*ac0d3d13SArd Biesheuvel static int cvm_ecb_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, 31110d82222SGeorge Cherian u32 keylen) 31210d82222SGeorge Cherian { 31310d82222SGeorge Cherian return cvm_setkey(cipher, key, keylen, AES_ECB); 31410d82222SGeorge Cherian } 31510d82222SGeorge Cherian 316*ac0d3d13SArd Biesheuvel static int cvm_cfb_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, 31710d82222SGeorge Cherian u32 keylen) 31810d82222SGeorge Cherian { 31910d82222SGeorge Cherian return cvm_setkey(cipher, key, keylen, AES_CFB); 32010d82222SGeorge Cherian } 32110d82222SGeorge Cherian 322*ac0d3d13SArd Biesheuvel static int cvm_cbc_des3_setkey(struct crypto_skcipher *cipher, const u8 *key, 323e2eb769eSGeorge Cherian u32 keylen) 324e2eb769eSGeorge Cherian { 325*ac0d3d13SArd Biesheuvel return verify_skcipher_des3_key(cipher, key) ?: 3260e1cbe97SArd Biesheuvel cvm_setkey(cipher, key, keylen, DES3_CBC); 327e2eb769eSGeorge Cherian } 328c694b233SGeorge Cherian 329*ac0d3d13SArd Biesheuvel static int cvm_ecb_des3_setkey(struct crypto_skcipher *cipher, const u8 *key, 33010d82222SGeorge Cherian u32 keylen) 33110d82222SGeorge Cherian { 332*ac0d3d13SArd Biesheuvel return verify_skcipher_des3_key(cipher, key) ?: 3330e1cbe97SArd Biesheuvel cvm_setkey(cipher, key, keylen, DES3_ECB); 33410d82222SGeorge Cherian } 33510d82222SGeorge Cherian 336*ac0d3d13SArd Biesheuvel static int cvm_enc_dec_init(struct crypto_skcipher *tfm) 337c694b233SGeorge Cherian { 338*ac0d3d13SArd Biesheuvel crypto_skcipher_set_reqsize(tfm, sizeof(struct cvm_req_ctx)); 339*ac0d3d13SArd Biesheuvel 340c694b233SGeorge Cherian return 0; 341c694b233SGeorge Cherian } 342c694b233SGeorge Cherian 343*ac0d3d13SArd Biesheuvel static struct skcipher_alg algs[] = { { 344*ac0d3d13SArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 345*ac0d3d13SArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE, 346*ac0d3d13SArd Biesheuvel .base.cra_ctxsize = sizeof(struct cvm_enc_ctx), 347*ac0d3d13SArd Biesheuvel .base.cra_alignmask = 7, 348*ac0d3d13SArd Biesheuvel .base.cra_priority = 4001, 349*ac0d3d13SArd Biesheuvel .base.cra_name = "xts(aes)", 350*ac0d3d13SArd Biesheuvel .base.cra_driver_name = "cavium-xts-aes", 351*ac0d3d13SArd Biesheuvel .base.cra_module = THIS_MODULE, 352*ac0d3d13SArd Biesheuvel 353c694b233SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 354c694b233SGeorge Cherian .min_keysize = 2 * AES_MIN_KEY_SIZE, 355c694b233SGeorge Cherian .max_keysize = 2 * AES_MAX_KEY_SIZE, 356c694b233SGeorge Cherian .setkey = cvm_xts_setkey, 357e2eb769eSGeorge Cherian .encrypt = cvm_encrypt, 358e2eb769eSGeorge Cherian .decrypt = cvm_decrypt, 359*ac0d3d13SArd Biesheuvel .init = cvm_enc_dec_init, 360c694b233SGeorge Cherian }, { 361*ac0d3d13SArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 362*ac0d3d13SArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE, 363*ac0d3d13SArd Biesheuvel .base.cra_ctxsize = sizeof(struct cvm_enc_ctx), 364*ac0d3d13SArd Biesheuvel .base.cra_alignmask = 7, 365*ac0d3d13SArd Biesheuvel .base.cra_priority = 4001, 366*ac0d3d13SArd Biesheuvel .base.cra_name = "cbc(aes)", 367*ac0d3d13SArd Biesheuvel .base.cra_driver_name = "cavium-cbc-aes", 368*ac0d3d13SArd Biesheuvel .base.cra_module = THIS_MODULE, 369*ac0d3d13SArd Biesheuvel 370c694b233SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 371c694b233SGeorge Cherian .min_keysize = AES_MIN_KEY_SIZE, 372c694b233SGeorge Cherian .max_keysize = AES_MAX_KEY_SIZE, 373e2eb769eSGeorge Cherian .setkey = cvm_cbc_aes_setkey, 374e2eb769eSGeorge Cherian .encrypt = cvm_encrypt, 375e2eb769eSGeorge Cherian .decrypt = cvm_decrypt, 376*ac0d3d13SArd Biesheuvel .init = cvm_enc_dec_init, 377c694b233SGeorge Cherian }, { 378*ac0d3d13SArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 379*ac0d3d13SArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE, 380*ac0d3d13SArd Biesheuvel .base.cra_ctxsize = sizeof(struct cvm_enc_ctx), 381*ac0d3d13SArd Biesheuvel .base.cra_alignmask = 7, 382*ac0d3d13SArd Biesheuvel .base.cra_priority = 4001, 383*ac0d3d13SArd Biesheuvel .base.cra_name = "ecb(aes)", 384*ac0d3d13SArd Biesheuvel .base.cra_driver_name = "cavium-ecb-aes", 385*ac0d3d13SArd Biesheuvel .base.cra_module = THIS_MODULE, 386*ac0d3d13SArd Biesheuvel 38710d82222SGeorge Cherian .min_keysize = AES_MIN_KEY_SIZE, 38810d82222SGeorge Cherian .max_keysize = AES_MAX_KEY_SIZE, 38910d82222SGeorge Cherian .setkey = cvm_ecb_aes_setkey, 39010d82222SGeorge Cherian .encrypt = cvm_encrypt, 39110d82222SGeorge Cherian .decrypt = cvm_decrypt, 392*ac0d3d13SArd Biesheuvel .init = cvm_enc_dec_init, 39310d82222SGeorge Cherian }, { 394*ac0d3d13SArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 395*ac0d3d13SArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE, 396*ac0d3d13SArd Biesheuvel .base.cra_ctxsize = sizeof(struct cvm_enc_ctx), 397*ac0d3d13SArd Biesheuvel .base.cra_alignmask = 7, 398*ac0d3d13SArd Biesheuvel .base.cra_priority = 4001, 399*ac0d3d13SArd Biesheuvel .base.cra_name = "cfb(aes)", 400*ac0d3d13SArd Biesheuvel .base.cra_driver_name = "cavium-cfb-aes", 401*ac0d3d13SArd Biesheuvel .base.cra_module = THIS_MODULE, 402*ac0d3d13SArd Biesheuvel 40310d82222SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 40410d82222SGeorge Cherian .min_keysize = AES_MIN_KEY_SIZE, 40510d82222SGeorge Cherian .max_keysize = AES_MAX_KEY_SIZE, 40610d82222SGeorge Cherian .setkey = cvm_cfb_aes_setkey, 40710d82222SGeorge Cherian .encrypt = cvm_encrypt, 40810d82222SGeorge Cherian .decrypt = cvm_decrypt, 409*ac0d3d13SArd Biesheuvel .init = cvm_enc_dec_init, 41010d82222SGeorge Cherian }, { 411*ac0d3d13SArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 412*ac0d3d13SArd Biesheuvel .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, 413*ac0d3d13SArd Biesheuvel .base.cra_ctxsize = sizeof(struct cvm_des3_ctx), 414*ac0d3d13SArd Biesheuvel .base.cra_alignmask = 7, 415*ac0d3d13SArd Biesheuvel .base.cra_priority = 4001, 416*ac0d3d13SArd Biesheuvel .base.cra_name = "cbc(des3_ede)", 417*ac0d3d13SArd Biesheuvel .base.cra_driver_name = "cavium-cbc-des3_ede", 418*ac0d3d13SArd Biesheuvel .base.cra_module = THIS_MODULE, 419*ac0d3d13SArd Biesheuvel 420c694b233SGeorge Cherian .min_keysize = DES3_EDE_KEY_SIZE, 421c694b233SGeorge Cherian .max_keysize = DES3_EDE_KEY_SIZE, 422c694b233SGeorge Cherian .ivsize = DES_BLOCK_SIZE, 423e2eb769eSGeorge Cherian .setkey = cvm_cbc_des3_setkey, 424e2eb769eSGeorge Cherian .encrypt = cvm_encrypt, 425e2eb769eSGeorge Cherian .decrypt = cvm_decrypt, 426*ac0d3d13SArd Biesheuvel .init = cvm_enc_dec_init, 42710d82222SGeorge Cherian }, { 428*ac0d3d13SArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 429*ac0d3d13SArd Biesheuvel .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, 430*ac0d3d13SArd Biesheuvel .base.cra_ctxsize = sizeof(struct cvm_des3_ctx), 431*ac0d3d13SArd Biesheuvel .base.cra_alignmask = 7, 432*ac0d3d13SArd Biesheuvel .base.cra_priority = 4001, 433*ac0d3d13SArd Biesheuvel .base.cra_name = "ecb(des3_ede)", 434*ac0d3d13SArd Biesheuvel .base.cra_driver_name = "cavium-ecb-des3_ede", 435*ac0d3d13SArd Biesheuvel .base.cra_module = THIS_MODULE, 436*ac0d3d13SArd Biesheuvel 43710d82222SGeorge Cherian .min_keysize = DES3_EDE_KEY_SIZE, 43810d82222SGeorge Cherian .max_keysize = DES3_EDE_KEY_SIZE, 43910d82222SGeorge Cherian .ivsize = DES_BLOCK_SIZE, 44010d82222SGeorge Cherian .setkey = cvm_ecb_des3_setkey, 44110d82222SGeorge Cherian .encrypt = cvm_encrypt, 44210d82222SGeorge Cherian .decrypt = cvm_decrypt, 443*ac0d3d13SArd Biesheuvel .init = cvm_enc_dec_init, 444c694b233SGeorge Cherian } }; 445c694b233SGeorge Cherian 446c694b233SGeorge Cherian static inline int cav_register_algs(void) 447c694b233SGeorge Cherian { 448c694b233SGeorge Cherian int err = 0; 449c694b233SGeorge Cherian 450*ac0d3d13SArd Biesheuvel err = crypto_register_skciphers(algs, ARRAY_SIZE(algs)); 451c694b233SGeorge Cherian if (err) 452c694b233SGeorge Cherian return err; 453c694b233SGeorge Cherian 454c694b233SGeorge Cherian return 0; 455c694b233SGeorge Cherian } 456c694b233SGeorge Cherian 457c694b233SGeorge Cherian static inline void cav_unregister_algs(void) 458c694b233SGeorge Cherian { 459*ac0d3d13SArd Biesheuvel crypto_unregister_skciphers(algs, ARRAY_SIZE(algs)); 460c694b233SGeorge Cherian } 461c694b233SGeorge Cherian 462c694b233SGeorge Cherian int cvm_crypto_init(struct cpt_vf *cptvf) 463c694b233SGeorge Cherian { 464c694b233SGeorge Cherian struct pci_dev *pdev = cptvf->pdev; 465c694b233SGeorge Cherian u32 dev_count; 466c694b233SGeorge Cherian 467c694b233SGeorge Cherian dev_count = dev_handle.dev_count; 468c694b233SGeorge Cherian dev_handle.cdev[dev_count] = cptvf; 469c694b233SGeorge Cherian dev_handle.dev_count++; 470c694b233SGeorge Cherian 471c694b233SGeorge Cherian if (dev_count == 3) { 472c694b233SGeorge Cherian if (cav_register_algs()) { 473c694b233SGeorge Cherian dev_err(&pdev->dev, "Error in registering crypto algorithms\n"); 474c694b233SGeorge Cherian return -EINVAL; 475c694b233SGeorge Cherian } 476c694b233SGeorge Cherian } 477c694b233SGeorge Cherian 478c694b233SGeorge Cherian return 0; 479c694b233SGeorge Cherian } 480c694b233SGeorge Cherian 481c694b233SGeorge Cherian void cvm_crypto_exit(void) 482c694b233SGeorge Cherian { 483c694b233SGeorge Cherian u32 dev_count; 484c694b233SGeorge Cherian 485c694b233SGeorge Cherian dev_count = --dev_handle.dev_count; 486c694b233SGeorge Cherian if (!dev_count) 487c694b233SGeorge Cherian cav_unregister_algs(); 488c694b233SGeorge Cherian } 489