1*25763b3cSThomas 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> 10c694b233SGeorge Cherian #include <crypto/crypto_wq.h> 11c694b233SGeorge Cherian #include <crypto/des.h> 12c694b233SGeorge Cherian #include <crypto/xts.h> 13c694b233SGeorge Cherian #include <linux/crypto.h> 14c694b233SGeorge Cherian #include <linux/err.h> 15c694b233SGeorge Cherian #include <linux/list.h> 16c694b233SGeorge Cherian #include <linux/scatterlist.h> 17c694b233SGeorge Cherian 18c694b233SGeorge Cherian #include "cptvf.h" 19c694b233SGeorge Cherian #include "cptvf_algs.h" 20c694b233SGeorge Cherian 21c694b233SGeorge Cherian struct cpt_device_handle { 22c694b233SGeorge Cherian void *cdev[MAX_DEVICES]; 23c694b233SGeorge Cherian u32 dev_count; 24c694b233SGeorge Cherian }; 25c694b233SGeorge Cherian 26c694b233SGeorge Cherian static struct cpt_device_handle dev_handle; 27c694b233SGeorge Cherian 28c694b233SGeorge Cherian static void cvm_callback(u32 status, void *arg) 29c694b233SGeorge Cherian { 30c694b233SGeorge Cherian struct crypto_async_request *req = (struct crypto_async_request *)arg; 31c694b233SGeorge Cherian 32c694b233SGeorge Cherian req->complete(req, !status); 33c694b233SGeorge Cherian } 34c694b233SGeorge Cherian 35c694b233SGeorge Cherian static inline void update_input_iv(struct cpt_request_info *req_info, 36c694b233SGeorge Cherian u8 *iv, u32 enc_iv_len, 37c694b233SGeorge Cherian u32 *argcnt) 38c694b233SGeorge Cherian { 39c694b233SGeorge Cherian /* Setting the iv information */ 40c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (void *)iv; 41c694b233SGeorge Cherian req_info->in[*argcnt].size = enc_iv_len; 42c694b233SGeorge Cherian req_info->req.dlen += enc_iv_len; 43c694b233SGeorge Cherian 44c694b233SGeorge Cherian ++(*argcnt); 45c694b233SGeorge Cherian } 46c694b233SGeorge Cherian 47c694b233SGeorge Cherian static inline void update_output_iv(struct cpt_request_info *req_info, 48c694b233SGeorge Cherian u8 *iv, u32 enc_iv_len, 49c694b233SGeorge Cherian u32 *argcnt) 50c694b233SGeorge Cherian { 51c694b233SGeorge Cherian /* Setting the iv information */ 52c694b233SGeorge Cherian req_info->out[*argcnt].vptr = (void *)iv; 53c694b233SGeorge Cherian req_info->out[*argcnt].size = enc_iv_len; 54c694b233SGeorge Cherian req_info->rlen += enc_iv_len; 55c694b233SGeorge Cherian 56c694b233SGeorge Cherian ++(*argcnt); 57c694b233SGeorge Cherian } 58c694b233SGeorge Cherian 59c694b233SGeorge Cherian static inline void update_input_data(struct cpt_request_info *req_info, 60c694b233SGeorge Cherian struct scatterlist *inp_sg, 61c694b233SGeorge Cherian u32 nbytes, u32 *argcnt) 62c694b233SGeorge Cherian { 63c694b233SGeorge Cherian req_info->req.dlen += nbytes; 64c694b233SGeorge Cherian 65c694b233SGeorge Cherian while (nbytes) { 66c694b233SGeorge Cherian u32 len = min(nbytes, inp_sg->length); 67c694b233SGeorge Cherian u8 *ptr = sg_virt(inp_sg); 68c694b233SGeorge Cherian 69c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (void *)ptr; 70c694b233SGeorge Cherian req_info->in[*argcnt].size = len; 71c694b233SGeorge Cherian nbytes -= len; 72c694b233SGeorge Cherian 73c694b233SGeorge Cherian ++(*argcnt); 74c694b233SGeorge Cherian ++inp_sg; 75c694b233SGeorge Cherian } 76c694b233SGeorge Cherian } 77c694b233SGeorge Cherian 78c694b233SGeorge Cherian static inline void update_output_data(struct cpt_request_info *req_info, 79c694b233SGeorge Cherian struct scatterlist *outp_sg, 80c694b233SGeorge Cherian u32 nbytes, u32 *argcnt) 81c694b233SGeorge Cherian { 82c694b233SGeorge Cherian req_info->rlen += nbytes; 83c694b233SGeorge Cherian 84c694b233SGeorge Cherian while (nbytes) { 85c694b233SGeorge Cherian u32 len = min(nbytes, outp_sg->length); 86c694b233SGeorge Cherian u8 *ptr = sg_virt(outp_sg); 87c694b233SGeorge Cherian 88c694b233SGeorge Cherian req_info->out[*argcnt].vptr = (void *)ptr; 89c694b233SGeorge Cherian req_info->out[*argcnt].size = len; 90c694b233SGeorge Cherian nbytes -= len; 91c694b233SGeorge Cherian ++(*argcnt); 92c694b233SGeorge Cherian ++outp_sg; 93c694b233SGeorge Cherian } 94c694b233SGeorge Cherian } 95c694b233SGeorge Cherian 96c694b233SGeorge Cherian static inline u32 create_ctx_hdr(struct ablkcipher_request *req, u32 enc, 97c694b233SGeorge Cherian u32 *argcnt) 98c694b233SGeorge Cherian { 99c694b233SGeorge Cherian struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); 100c694b233SGeorge Cherian struct cvm_enc_ctx *ctx = crypto_ablkcipher_ctx(tfm); 101c694b233SGeorge Cherian struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req); 102c694b233SGeorge Cherian struct fc_context *fctx = &rctx->fctx; 103c694b233SGeorge Cherian u64 *offset_control = &rctx->control_word; 104c694b233SGeorge Cherian u32 enc_iv_len = crypto_ablkcipher_ivsize(tfm); 105c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 106c694b233SGeorge Cherian u64 *ctrl_flags = NULL; 107c694b233SGeorge Cherian 108c694b233SGeorge Cherian req_info->ctrl.s.grp = 0; 109c694b233SGeorge Cherian req_info->ctrl.s.dma_mode = DMA_GATHER_SCATTER; 110c694b233SGeorge Cherian req_info->ctrl.s.se_req = SE_CORE_REQ; 111c694b233SGeorge Cherian 112c694b233SGeorge Cherian req_info->req.opcode.s.major = MAJOR_OP_FC | 113c694b233SGeorge Cherian DMA_MODE_FLAG(DMA_GATHER_SCATTER); 114c694b233SGeorge Cherian if (enc) 115c694b233SGeorge Cherian req_info->req.opcode.s.minor = 2; 116c694b233SGeorge Cherian else 117c694b233SGeorge Cherian req_info->req.opcode.s.minor = 3; 118c694b233SGeorge Cherian 119c694b233SGeorge Cherian req_info->req.param1 = req->nbytes; /* Encryption Data length */ 120c694b233SGeorge Cherian req_info->req.param2 = 0; /*Auth data length */ 121c694b233SGeorge Cherian 122e2eb769eSGeorge Cherian fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type; 123e2eb769eSGeorge Cherian fctx->enc.enc_ctrl.e.aes_key = ctx->key_type; 124c694b233SGeorge Cherian fctx->enc.enc_ctrl.e.iv_source = FROM_DPTR; 125c694b233SGeorge Cherian 126e2eb769eSGeorge Cherian if (ctx->cipher_type == AES_XTS) 127c694b233SGeorge Cherian memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2); 128c694b233SGeorge Cherian else 129c694b233SGeorge Cherian memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len); 130c694b233SGeorge Cherian ctrl_flags = (u64 *)&fctx->enc.enc_ctrl.flags; 131c694b233SGeorge Cherian *ctrl_flags = cpu_to_be64(*ctrl_flags); 132c694b233SGeorge Cherian 133c694b233SGeorge Cherian *offset_control = cpu_to_be64(((u64)(enc_iv_len) << 16)); 134c694b233SGeorge Cherian /* Storing Packet Data Information in offset 135c694b233SGeorge Cherian * Control Word First 8 bytes 136c694b233SGeorge Cherian */ 137c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (u8 *)offset_control; 138c694b233SGeorge Cherian req_info->in[*argcnt].size = CONTROL_WORD_LEN; 139c694b233SGeorge Cherian req_info->req.dlen += CONTROL_WORD_LEN; 140c694b233SGeorge Cherian ++(*argcnt); 141c694b233SGeorge Cherian 142c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (u8 *)fctx; 143c694b233SGeorge Cherian req_info->in[*argcnt].size = sizeof(struct fc_context); 144c694b233SGeorge Cherian req_info->req.dlen += sizeof(struct fc_context); 145c694b233SGeorge Cherian 146c694b233SGeorge Cherian ++(*argcnt); 147c694b233SGeorge Cherian 148c694b233SGeorge Cherian return 0; 149c694b233SGeorge Cherian } 150c694b233SGeorge Cherian 151c694b233SGeorge Cherian static inline u32 create_input_list(struct ablkcipher_request *req, u32 enc, 152c694b233SGeorge Cherian u32 enc_iv_len) 153c694b233SGeorge Cherian { 154c694b233SGeorge Cherian struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req); 155c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 156c694b233SGeorge Cherian u32 argcnt = 0; 157c694b233SGeorge Cherian 158e2eb769eSGeorge Cherian create_ctx_hdr(req, enc, &argcnt); 159c694b233SGeorge Cherian update_input_iv(req_info, req->info, enc_iv_len, &argcnt); 160c694b233SGeorge Cherian update_input_data(req_info, req->src, req->nbytes, &argcnt); 161c694b233SGeorge Cherian req_info->incnt = argcnt; 162c694b233SGeorge Cherian 163c694b233SGeorge Cherian return 0; 164c694b233SGeorge Cherian } 165c694b233SGeorge Cherian 166c694b233SGeorge Cherian static inline void store_cb_info(struct ablkcipher_request *req, 167c694b233SGeorge Cherian struct cpt_request_info *req_info) 168c694b233SGeorge Cherian { 169c694b233SGeorge Cherian req_info->callback = (void *)cvm_callback; 170c694b233SGeorge Cherian req_info->callback_arg = (void *)&req->base; 171c694b233SGeorge Cherian } 172c694b233SGeorge Cherian 173c694b233SGeorge Cherian static inline void create_output_list(struct ablkcipher_request *req, 174c694b233SGeorge Cherian u32 enc_iv_len) 175c694b233SGeorge Cherian { 176c694b233SGeorge Cherian struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req); 177c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 178c694b233SGeorge Cherian u32 argcnt = 0; 179c694b233SGeorge Cherian 180c694b233SGeorge Cherian /* OUTPUT Buffer Processing 181c694b233SGeorge Cherian * AES encryption/decryption output would be 182c694b233SGeorge Cherian * received in the following format 183c694b233SGeorge Cherian * 184c694b233SGeorge Cherian * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----| 185c694b233SGeorge Cherian * [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ] 186c694b233SGeorge Cherian */ 187c694b233SGeorge Cherian /* Reading IV information */ 188c694b233SGeorge Cherian update_output_iv(req_info, req->info, enc_iv_len, &argcnt); 189c694b233SGeorge Cherian update_output_data(req_info, req->dst, req->nbytes, &argcnt); 190c694b233SGeorge Cherian req_info->outcnt = argcnt; 191c694b233SGeorge Cherian } 192c694b233SGeorge Cherian 193e2eb769eSGeorge Cherian static inline int cvm_enc_dec(struct ablkcipher_request *req, u32 enc) 194c694b233SGeorge Cherian { 195c694b233SGeorge Cherian struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); 196c694b233SGeorge Cherian struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req); 197c694b233SGeorge Cherian u32 enc_iv_len = crypto_ablkcipher_ivsize(tfm); 198c694b233SGeorge Cherian struct fc_context *fctx = &rctx->fctx; 199c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 200c694b233SGeorge Cherian void *cdev = NULL; 201c694b233SGeorge Cherian int status; 202c694b233SGeorge Cherian 203c694b233SGeorge Cherian memset(req_info, 0, sizeof(struct cpt_request_info)); 204c694b233SGeorge Cherian memset(fctx, 0, sizeof(struct fc_context)); 205e2eb769eSGeorge Cherian create_input_list(req, enc, enc_iv_len); 206e2eb769eSGeorge Cherian create_output_list(req, enc_iv_len); 207c694b233SGeorge Cherian store_cb_info(req, req_info); 208c694b233SGeorge Cherian cdev = dev_handle.cdev[smp_processor_id()]; 209c694b233SGeorge Cherian status = cptvf_do_request(cdev, req_info); 210c694b233SGeorge Cherian /* We perform an asynchronous send and once 211c694b233SGeorge Cherian * the request is completed the driver would 212c694b233SGeorge Cherian * intimate through registered call back functions 213c694b233SGeorge Cherian */ 214c694b233SGeorge Cherian 215c694b233SGeorge Cherian if (status) 216c694b233SGeorge Cherian return status; 217c694b233SGeorge Cherian else 218c694b233SGeorge Cherian return -EINPROGRESS; 219c694b233SGeorge Cherian } 220c694b233SGeorge Cherian 221b8fc3397SColin Ian King static int cvm_encrypt(struct ablkcipher_request *req) 222c694b233SGeorge Cherian { 223e2eb769eSGeorge Cherian return cvm_enc_dec(req, true); 224c694b233SGeorge Cherian } 225c694b233SGeorge Cherian 226b8fc3397SColin Ian King static int cvm_decrypt(struct ablkcipher_request *req) 227c694b233SGeorge Cherian { 228e2eb769eSGeorge Cherian return cvm_enc_dec(req, false); 229c694b233SGeorge Cherian } 230c694b233SGeorge Cherian 231b8fc3397SColin Ian King static int cvm_xts_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 232c694b233SGeorge Cherian u32 keylen) 233c694b233SGeorge Cherian { 234c694b233SGeorge Cherian struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); 235c694b233SGeorge Cherian struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm); 236c694b233SGeorge Cherian int err; 237c694b233SGeorge Cherian const u8 *key1 = key; 238c694b233SGeorge Cherian const u8 *key2 = key + (keylen / 2); 239c694b233SGeorge Cherian 240c694b233SGeorge Cherian err = xts_check_key(tfm, key, keylen); 241c694b233SGeorge Cherian if (err) 242c694b233SGeorge Cherian return err; 243c694b233SGeorge Cherian ctx->key_len = keylen; 244c694b233SGeorge Cherian memcpy(ctx->enc_key, key1, keylen / 2); 245c694b233SGeorge Cherian memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2); 246e2eb769eSGeorge Cherian ctx->cipher_type = AES_XTS; 247e2eb769eSGeorge Cherian switch (ctx->key_len) { 248e2eb769eSGeorge Cherian case 32: 249e2eb769eSGeorge Cherian ctx->key_type = AES_128_BIT; 250e2eb769eSGeorge Cherian break; 251e2eb769eSGeorge Cherian case 64: 252e2eb769eSGeorge Cherian ctx->key_type = AES_256_BIT; 253e2eb769eSGeorge Cherian break; 254e2eb769eSGeorge Cherian default: 255e2eb769eSGeorge Cherian return -EINVAL; 256e2eb769eSGeorge Cherian } 257c694b233SGeorge Cherian 258c694b233SGeorge Cherian return 0; 259c694b233SGeorge Cherian } 260c694b233SGeorge Cherian 261e2eb769eSGeorge Cherian static int cvm_validate_keylen(struct cvm_enc_ctx *ctx, u32 keylen) 262e2eb769eSGeorge Cherian { 263e2eb769eSGeorge Cherian if ((keylen == 16) || (keylen == 24) || (keylen == 32)) { 264e2eb769eSGeorge Cherian ctx->key_len = keylen; 265e2eb769eSGeorge Cherian switch (ctx->key_len) { 266e2eb769eSGeorge Cherian case 16: 267e2eb769eSGeorge Cherian ctx->key_type = AES_128_BIT; 268e2eb769eSGeorge Cherian break; 269e2eb769eSGeorge Cherian case 24: 270e2eb769eSGeorge Cherian ctx->key_type = AES_192_BIT; 271e2eb769eSGeorge Cherian break; 272e2eb769eSGeorge Cherian case 32: 273e2eb769eSGeorge Cherian ctx->key_type = AES_256_BIT; 274e2eb769eSGeorge Cherian break; 275e2eb769eSGeorge Cherian default: 276e2eb769eSGeorge Cherian return -EINVAL; 277e2eb769eSGeorge Cherian } 278e2eb769eSGeorge Cherian 279e2eb769eSGeorge Cherian if (ctx->cipher_type == DES3_CBC) 280e2eb769eSGeorge Cherian ctx->key_type = 0; 281e2eb769eSGeorge Cherian 282e2eb769eSGeorge Cherian return 0; 283e2eb769eSGeorge Cherian } 284e2eb769eSGeorge Cherian 285e2eb769eSGeorge Cherian return -EINVAL; 286e2eb769eSGeorge Cherian } 287e2eb769eSGeorge Cherian 288e2eb769eSGeorge Cherian static int cvm_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 289e2eb769eSGeorge Cherian u32 keylen, u8 cipher_type) 290c694b233SGeorge Cherian { 291c694b233SGeorge Cherian struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); 292c694b233SGeorge Cherian struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm); 293c694b233SGeorge Cherian 294e2eb769eSGeorge Cherian ctx->cipher_type = cipher_type; 295e2eb769eSGeorge Cherian if (!cvm_validate_keylen(ctx, keylen)) { 296c694b233SGeorge Cherian memcpy(ctx->enc_key, key, keylen); 297c694b233SGeorge Cherian return 0; 298e2eb769eSGeorge Cherian } else { 299e2eb769eSGeorge Cherian crypto_ablkcipher_set_flags(cipher, 300e2eb769eSGeorge Cherian CRYPTO_TFM_RES_BAD_KEY_LEN); 301c694b233SGeorge Cherian return -EINVAL; 302c694b233SGeorge Cherian } 303e2eb769eSGeorge Cherian } 304e2eb769eSGeorge Cherian 305e2eb769eSGeorge Cherian static int cvm_cbc_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 306e2eb769eSGeorge Cherian u32 keylen) 307e2eb769eSGeorge Cherian { 308e2eb769eSGeorge Cherian return cvm_setkey(cipher, key, keylen, AES_CBC); 309e2eb769eSGeorge Cherian } 310e2eb769eSGeorge Cherian 31110d82222SGeorge Cherian static int cvm_ecb_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 31210d82222SGeorge Cherian u32 keylen) 31310d82222SGeorge Cherian { 31410d82222SGeorge Cherian return cvm_setkey(cipher, key, keylen, AES_ECB); 31510d82222SGeorge Cherian } 31610d82222SGeorge Cherian 31710d82222SGeorge Cherian static int cvm_cfb_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 31810d82222SGeorge Cherian u32 keylen) 31910d82222SGeorge Cherian { 32010d82222SGeorge Cherian return cvm_setkey(cipher, key, keylen, AES_CFB); 32110d82222SGeorge Cherian } 32210d82222SGeorge Cherian 323e2eb769eSGeorge Cherian static int cvm_cbc_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 324e2eb769eSGeorge Cherian u32 keylen) 325e2eb769eSGeorge Cherian { 3263b2de724SHerbert Xu u32 flags = crypto_ablkcipher_get_flags(cipher); 3273b2de724SHerbert Xu int err; 3283b2de724SHerbert Xu 3293b2de724SHerbert Xu err = __des3_verify_key(&flags, key); 3303b2de724SHerbert Xu if (unlikely(err)) { 3313b2de724SHerbert Xu crypto_ablkcipher_set_flags(cipher, flags); 3323b2de724SHerbert Xu return err; 3333b2de724SHerbert Xu } 3343b2de724SHerbert Xu 335e2eb769eSGeorge Cherian return cvm_setkey(cipher, key, keylen, DES3_CBC); 336e2eb769eSGeorge Cherian } 337c694b233SGeorge Cherian 33810d82222SGeorge Cherian static int cvm_ecb_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 33910d82222SGeorge Cherian u32 keylen) 34010d82222SGeorge Cherian { 3413b2de724SHerbert Xu u32 flags = crypto_ablkcipher_get_flags(cipher); 3423b2de724SHerbert Xu int err; 3433b2de724SHerbert Xu 3443b2de724SHerbert Xu err = __des3_verify_key(&flags, key); 3453b2de724SHerbert Xu if (unlikely(err)) { 3463b2de724SHerbert Xu crypto_ablkcipher_set_flags(cipher, flags); 3473b2de724SHerbert Xu return err; 3483b2de724SHerbert Xu } 3493b2de724SHerbert Xu 35010d82222SGeorge Cherian return cvm_setkey(cipher, key, keylen, DES3_ECB); 35110d82222SGeorge Cherian } 35210d82222SGeorge Cherian 353b8fc3397SColin Ian King static int cvm_enc_dec_init(struct crypto_tfm *tfm) 354c694b233SGeorge Cherian { 3550edf8593SEric Biggers tfm->crt_ablkcipher.reqsize = sizeof(struct cvm_req_ctx); 356c694b233SGeorge Cherian return 0; 357c694b233SGeorge Cherian } 358c694b233SGeorge Cherian 3592a2b9461SColin Ian King static struct crypto_alg algs[] = { { 360c694b233SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 361c694b233SGeorge Cherian .cra_blocksize = AES_BLOCK_SIZE, 362c694b233SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_enc_ctx), 363c694b233SGeorge Cherian .cra_alignmask = 7, 364c694b233SGeorge Cherian .cra_priority = 4001, 365c694b233SGeorge Cherian .cra_name = "xts(aes)", 366c694b233SGeorge Cherian .cra_driver_name = "cavium-xts-aes", 367c694b233SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 368c694b233SGeorge Cherian .cra_u = { 369c694b233SGeorge Cherian .ablkcipher = { 370c694b233SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 371c694b233SGeorge Cherian .min_keysize = 2 * AES_MIN_KEY_SIZE, 372c694b233SGeorge Cherian .max_keysize = 2 * AES_MAX_KEY_SIZE, 373c694b233SGeorge Cherian .setkey = cvm_xts_setkey, 374e2eb769eSGeorge Cherian .encrypt = cvm_encrypt, 375e2eb769eSGeorge Cherian .decrypt = cvm_decrypt, 376c694b233SGeorge Cherian }, 377c694b233SGeorge Cherian }, 378c694b233SGeorge Cherian .cra_init = cvm_enc_dec_init, 379c694b233SGeorge Cherian .cra_module = THIS_MODULE, 380c694b233SGeorge Cherian }, { 381c694b233SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 382c694b233SGeorge Cherian .cra_blocksize = AES_BLOCK_SIZE, 383c694b233SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_enc_ctx), 384c694b233SGeorge Cherian .cra_alignmask = 7, 385c694b233SGeorge Cherian .cra_priority = 4001, 386c694b233SGeorge Cherian .cra_name = "cbc(aes)", 387c694b233SGeorge Cherian .cra_driver_name = "cavium-cbc-aes", 388c694b233SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 389c694b233SGeorge Cherian .cra_u = { 390c694b233SGeorge Cherian .ablkcipher = { 391c694b233SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 392c694b233SGeorge Cherian .min_keysize = AES_MIN_KEY_SIZE, 393c694b233SGeorge Cherian .max_keysize = AES_MAX_KEY_SIZE, 394e2eb769eSGeorge Cherian .setkey = cvm_cbc_aes_setkey, 395e2eb769eSGeorge Cherian .encrypt = cvm_encrypt, 396e2eb769eSGeorge Cherian .decrypt = cvm_decrypt, 397c694b233SGeorge Cherian }, 398c694b233SGeorge Cherian }, 399c694b233SGeorge Cherian .cra_init = cvm_enc_dec_init, 400c694b233SGeorge Cherian .cra_module = THIS_MODULE, 401c694b233SGeorge Cherian }, { 402c694b233SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 40310d82222SGeorge Cherian .cra_blocksize = AES_BLOCK_SIZE, 40410d82222SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_enc_ctx), 40510d82222SGeorge Cherian .cra_alignmask = 7, 40610d82222SGeorge Cherian .cra_priority = 4001, 40710d82222SGeorge Cherian .cra_name = "ecb(aes)", 40810d82222SGeorge Cherian .cra_driver_name = "cavium-ecb-aes", 40910d82222SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 41010d82222SGeorge Cherian .cra_u = { 41110d82222SGeorge Cherian .ablkcipher = { 41210d82222SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 41310d82222SGeorge Cherian .min_keysize = AES_MIN_KEY_SIZE, 41410d82222SGeorge Cherian .max_keysize = AES_MAX_KEY_SIZE, 41510d82222SGeorge Cherian .setkey = cvm_ecb_aes_setkey, 41610d82222SGeorge Cherian .encrypt = cvm_encrypt, 41710d82222SGeorge Cherian .decrypt = cvm_decrypt, 41810d82222SGeorge Cherian }, 41910d82222SGeorge Cherian }, 42010d82222SGeorge Cherian .cra_init = cvm_enc_dec_init, 42110d82222SGeorge Cherian .cra_module = THIS_MODULE, 42210d82222SGeorge Cherian }, { 42310d82222SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 42410d82222SGeorge Cherian .cra_blocksize = AES_BLOCK_SIZE, 42510d82222SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_enc_ctx), 42610d82222SGeorge Cherian .cra_alignmask = 7, 42710d82222SGeorge Cherian .cra_priority = 4001, 42810d82222SGeorge Cherian .cra_name = "cfb(aes)", 42910d82222SGeorge Cherian .cra_driver_name = "cavium-cfb-aes", 43010d82222SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 43110d82222SGeorge Cherian .cra_u = { 43210d82222SGeorge Cherian .ablkcipher = { 43310d82222SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 43410d82222SGeorge Cherian .min_keysize = AES_MIN_KEY_SIZE, 43510d82222SGeorge Cherian .max_keysize = AES_MAX_KEY_SIZE, 43610d82222SGeorge Cherian .setkey = cvm_cfb_aes_setkey, 43710d82222SGeorge Cherian .encrypt = cvm_encrypt, 43810d82222SGeorge Cherian .decrypt = cvm_decrypt, 43910d82222SGeorge Cherian }, 44010d82222SGeorge Cherian }, 44110d82222SGeorge Cherian .cra_init = cvm_enc_dec_init, 44210d82222SGeorge Cherian .cra_module = THIS_MODULE, 44310d82222SGeorge Cherian }, { 44410d82222SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 445c694b233SGeorge Cherian .cra_blocksize = DES3_EDE_BLOCK_SIZE, 446c694b233SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_des3_ctx), 447c694b233SGeorge Cherian .cra_alignmask = 7, 448c694b233SGeorge Cherian .cra_priority = 4001, 449c694b233SGeorge Cherian .cra_name = "cbc(des3_ede)", 450c694b233SGeorge Cherian .cra_driver_name = "cavium-cbc-des3_ede", 451c694b233SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 452c694b233SGeorge Cherian .cra_u = { 453c694b233SGeorge Cherian .ablkcipher = { 454c694b233SGeorge Cherian .min_keysize = DES3_EDE_KEY_SIZE, 455c694b233SGeorge Cherian .max_keysize = DES3_EDE_KEY_SIZE, 456c694b233SGeorge Cherian .ivsize = DES_BLOCK_SIZE, 457e2eb769eSGeorge Cherian .setkey = cvm_cbc_des3_setkey, 458e2eb769eSGeorge Cherian .encrypt = cvm_encrypt, 459e2eb769eSGeorge Cherian .decrypt = cvm_decrypt, 460c694b233SGeorge Cherian }, 461c694b233SGeorge Cherian }, 462c694b233SGeorge Cherian .cra_init = cvm_enc_dec_init, 463c694b233SGeorge Cherian .cra_module = THIS_MODULE, 46410d82222SGeorge Cherian }, { 46510d82222SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 46610d82222SGeorge Cherian .cra_blocksize = DES3_EDE_BLOCK_SIZE, 46710d82222SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_des3_ctx), 46810d82222SGeorge Cherian .cra_alignmask = 7, 46910d82222SGeorge Cherian .cra_priority = 4001, 47010d82222SGeorge Cherian .cra_name = "ecb(des3_ede)", 47110d82222SGeorge Cherian .cra_driver_name = "cavium-ecb-des3_ede", 47210d82222SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 47310d82222SGeorge Cherian .cra_u = { 47410d82222SGeorge Cherian .ablkcipher = { 47510d82222SGeorge Cherian .min_keysize = DES3_EDE_KEY_SIZE, 47610d82222SGeorge Cherian .max_keysize = DES3_EDE_KEY_SIZE, 47710d82222SGeorge Cherian .ivsize = DES_BLOCK_SIZE, 47810d82222SGeorge Cherian .setkey = cvm_ecb_des3_setkey, 47910d82222SGeorge Cherian .encrypt = cvm_encrypt, 48010d82222SGeorge Cherian .decrypt = cvm_decrypt, 48110d82222SGeorge Cherian }, 48210d82222SGeorge Cherian }, 48310d82222SGeorge Cherian .cra_init = cvm_enc_dec_init, 48410d82222SGeorge Cherian .cra_module = THIS_MODULE, 485c694b233SGeorge Cherian } }; 486c694b233SGeorge Cherian 487c694b233SGeorge Cherian static inline int cav_register_algs(void) 488c694b233SGeorge Cherian { 489c694b233SGeorge Cherian int err = 0; 490c694b233SGeorge Cherian 491c694b233SGeorge Cherian err = crypto_register_algs(algs, ARRAY_SIZE(algs)); 492c694b233SGeorge Cherian if (err) 493c694b233SGeorge Cherian return err; 494c694b233SGeorge Cherian 495c694b233SGeorge Cherian return 0; 496c694b233SGeorge Cherian } 497c694b233SGeorge Cherian 498c694b233SGeorge Cherian static inline void cav_unregister_algs(void) 499c694b233SGeorge Cherian { 500c694b233SGeorge Cherian crypto_unregister_algs(algs, ARRAY_SIZE(algs)); 501c694b233SGeorge Cherian } 502c694b233SGeorge Cherian 503c694b233SGeorge Cherian int cvm_crypto_init(struct cpt_vf *cptvf) 504c694b233SGeorge Cherian { 505c694b233SGeorge Cherian struct pci_dev *pdev = cptvf->pdev; 506c694b233SGeorge Cherian u32 dev_count; 507c694b233SGeorge Cherian 508c694b233SGeorge Cherian dev_count = dev_handle.dev_count; 509c694b233SGeorge Cherian dev_handle.cdev[dev_count] = cptvf; 510c694b233SGeorge Cherian dev_handle.dev_count++; 511c694b233SGeorge Cherian 512c694b233SGeorge Cherian if (dev_count == 3) { 513c694b233SGeorge Cherian if (cav_register_algs()) { 514c694b233SGeorge Cherian dev_err(&pdev->dev, "Error in registering crypto algorithms\n"); 515c694b233SGeorge Cherian return -EINVAL; 516c694b233SGeorge Cherian } 517c694b233SGeorge Cherian } 518c694b233SGeorge Cherian 519c694b233SGeorge Cherian return 0; 520c694b233SGeorge Cherian } 521c694b233SGeorge Cherian 522c694b233SGeorge Cherian void cvm_crypto_exit(void) 523c694b233SGeorge Cherian { 524c694b233SGeorge Cherian u32 dev_count; 525c694b233SGeorge Cherian 526c694b233SGeorge Cherian dev_count = --dev_handle.dev_count; 527c694b233SGeorge Cherian if (!dev_count) 528c694b233SGeorge Cherian cav_unregister_algs(); 529c694b233SGeorge Cherian } 530