1c694b233SGeorge Cherian 2c694b233SGeorge Cherian /* 3c694b233SGeorge Cherian * Copyright (C) 2016 Cavium, Inc. 4c694b233SGeorge Cherian * 5c694b233SGeorge Cherian * This program is free software; you can redistribute it and/or modify it 6c694b233SGeorge Cherian * under the terms of version 2 of the GNU General Public License 7c694b233SGeorge Cherian * as published by the Free Software Foundation. 8c694b233SGeorge Cherian */ 9c694b233SGeorge Cherian 10c694b233SGeorge Cherian #include <crypto/aes.h> 11c694b233SGeorge Cherian #include <crypto/algapi.h> 12c694b233SGeorge Cherian #include <crypto/authenc.h> 13c694b233SGeorge Cherian #include <crypto/cryptd.h> 14c694b233SGeorge Cherian #include <crypto/crypto_wq.h> 15c694b233SGeorge Cherian #include <crypto/des.h> 16c694b233SGeorge Cherian #include <crypto/xts.h> 17c694b233SGeorge Cherian #include <linux/crypto.h> 18c694b233SGeorge Cherian #include <linux/err.h> 19c694b233SGeorge Cherian #include <linux/list.h> 20c694b233SGeorge Cherian #include <linux/scatterlist.h> 21c694b233SGeorge Cherian 22c694b233SGeorge Cherian #include "cptvf.h" 23c694b233SGeorge Cherian #include "cptvf_algs.h" 24c694b233SGeorge Cherian 25c694b233SGeorge Cherian struct cpt_device_handle { 26c694b233SGeorge Cherian void *cdev[MAX_DEVICES]; 27c694b233SGeorge Cherian u32 dev_count; 28c694b233SGeorge Cherian }; 29c694b233SGeorge Cherian 30c694b233SGeorge Cherian static struct cpt_device_handle dev_handle; 31c694b233SGeorge Cherian 32c694b233SGeorge Cherian static void cvm_callback(u32 status, void *arg) 33c694b233SGeorge Cherian { 34c694b233SGeorge Cherian struct crypto_async_request *req = (struct crypto_async_request *)arg; 35c694b233SGeorge Cherian 36c694b233SGeorge Cherian req->complete(req, !status); 37c694b233SGeorge Cherian } 38c694b233SGeorge Cherian 39c694b233SGeorge Cherian static inline void update_input_iv(struct cpt_request_info *req_info, 40c694b233SGeorge Cherian u8 *iv, u32 enc_iv_len, 41c694b233SGeorge Cherian u32 *argcnt) 42c694b233SGeorge Cherian { 43c694b233SGeorge Cherian /* Setting the iv information */ 44c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (void *)iv; 45c694b233SGeorge Cherian req_info->in[*argcnt].size = enc_iv_len; 46c694b233SGeorge Cherian req_info->req.dlen += enc_iv_len; 47c694b233SGeorge Cherian 48c694b233SGeorge Cherian ++(*argcnt); 49c694b233SGeorge Cherian } 50c694b233SGeorge Cherian 51c694b233SGeorge Cherian static inline void update_output_iv(struct cpt_request_info *req_info, 52c694b233SGeorge Cherian u8 *iv, u32 enc_iv_len, 53c694b233SGeorge Cherian u32 *argcnt) 54c694b233SGeorge Cherian { 55c694b233SGeorge Cherian /* Setting the iv information */ 56c694b233SGeorge Cherian req_info->out[*argcnt].vptr = (void *)iv; 57c694b233SGeorge Cherian req_info->out[*argcnt].size = enc_iv_len; 58c694b233SGeorge Cherian req_info->rlen += enc_iv_len; 59c694b233SGeorge Cherian 60c694b233SGeorge Cherian ++(*argcnt); 61c694b233SGeorge Cherian } 62c694b233SGeorge Cherian 63c694b233SGeorge Cherian static inline void update_input_data(struct cpt_request_info *req_info, 64c694b233SGeorge Cherian struct scatterlist *inp_sg, 65c694b233SGeorge Cherian u32 nbytes, u32 *argcnt) 66c694b233SGeorge Cherian { 67c694b233SGeorge Cherian req_info->req.dlen += nbytes; 68c694b233SGeorge Cherian 69c694b233SGeorge Cherian while (nbytes) { 70c694b233SGeorge Cherian u32 len = min(nbytes, inp_sg->length); 71c694b233SGeorge Cherian u8 *ptr = sg_virt(inp_sg); 72c694b233SGeorge Cherian 73c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (void *)ptr; 74c694b233SGeorge Cherian req_info->in[*argcnt].size = len; 75c694b233SGeorge Cherian nbytes -= len; 76c694b233SGeorge Cherian 77c694b233SGeorge Cherian ++(*argcnt); 78c694b233SGeorge Cherian ++inp_sg; 79c694b233SGeorge Cherian } 80c694b233SGeorge Cherian } 81c694b233SGeorge Cherian 82c694b233SGeorge Cherian static inline void update_output_data(struct cpt_request_info *req_info, 83c694b233SGeorge Cherian struct scatterlist *outp_sg, 84c694b233SGeorge Cherian u32 nbytes, u32 *argcnt) 85c694b233SGeorge Cherian { 86c694b233SGeorge Cherian req_info->rlen += nbytes; 87c694b233SGeorge Cherian 88c694b233SGeorge Cherian while (nbytes) { 89c694b233SGeorge Cherian u32 len = min(nbytes, outp_sg->length); 90c694b233SGeorge Cherian u8 *ptr = sg_virt(outp_sg); 91c694b233SGeorge Cherian 92c694b233SGeorge Cherian req_info->out[*argcnt].vptr = (void *)ptr; 93c694b233SGeorge Cherian req_info->out[*argcnt].size = len; 94c694b233SGeorge Cherian nbytes -= len; 95c694b233SGeorge Cherian ++(*argcnt); 96c694b233SGeorge Cherian ++outp_sg; 97c694b233SGeorge Cherian } 98c694b233SGeorge Cherian } 99c694b233SGeorge Cherian 100c694b233SGeorge Cherian static inline u32 create_ctx_hdr(struct ablkcipher_request *req, u32 enc, 101c694b233SGeorge Cherian u32 *argcnt) 102c694b233SGeorge Cherian { 103c694b233SGeorge Cherian struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); 104c694b233SGeorge Cherian struct cvm_enc_ctx *ctx = crypto_ablkcipher_ctx(tfm); 105c694b233SGeorge Cherian struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req); 106c694b233SGeorge Cherian struct fc_context *fctx = &rctx->fctx; 107c694b233SGeorge Cherian u64 *offset_control = &rctx->control_word; 108c694b233SGeorge Cherian u32 enc_iv_len = crypto_ablkcipher_ivsize(tfm); 109c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 110c694b233SGeorge Cherian u64 *ctrl_flags = NULL; 111c694b233SGeorge Cherian 112c694b233SGeorge Cherian req_info->ctrl.s.grp = 0; 113c694b233SGeorge Cherian req_info->ctrl.s.dma_mode = DMA_GATHER_SCATTER; 114c694b233SGeorge Cherian req_info->ctrl.s.se_req = SE_CORE_REQ; 115c694b233SGeorge Cherian 116c694b233SGeorge Cherian req_info->req.opcode.s.major = MAJOR_OP_FC | 117c694b233SGeorge Cherian DMA_MODE_FLAG(DMA_GATHER_SCATTER); 118c694b233SGeorge Cherian if (enc) 119c694b233SGeorge Cherian req_info->req.opcode.s.minor = 2; 120c694b233SGeorge Cherian else 121c694b233SGeorge Cherian req_info->req.opcode.s.minor = 3; 122c694b233SGeorge Cherian 123c694b233SGeorge Cherian req_info->req.param1 = req->nbytes; /* Encryption Data length */ 124c694b233SGeorge Cherian req_info->req.param2 = 0; /*Auth data length */ 125c694b233SGeorge Cherian 126e2eb769eSGeorge Cherian fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type; 127e2eb769eSGeorge Cherian fctx->enc.enc_ctrl.e.aes_key = ctx->key_type; 128c694b233SGeorge Cherian fctx->enc.enc_ctrl.e.iv_source = FROM_DPTR; 129c694b233SGeorge Cherian 130e2eb769eSGeorge Cherian if (ctx->cipher_type == AES_XTS) 131c694b233SGeorge Cherian memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2); 132c694b233SGeorge Cherian else 133c694b233SGeorge Cherian memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len); 134c694b233SGeorge Cherian ctrl_flags = (u64 *)&fctx->enc.enc_ctrl.flags; 135c694b233SGeorge Cherian *ctrl_flags = cpu_to_be64(*ctrl_flags); 136c694b233SGeorge Cherian 137c694b233SGeorge Cherian *offset_control = cpu_to_be64(((u64)(enc_iv_len) << 16)); 138c694b233SGeorge Cherian /* Storing Packet Data Information in offset 139c694b233SGeorge Cherian * Control Word First 8 bytes 140c694b233SGeorge Cherian */ 141c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (u8 *)offset_control; 142c694b233SGeorge Cherian req_info->in[*argcnt].size = CONTROL_WORD_LEN; 143c694b233SGeorge Cherian req_info->req.dlen += CONTROL_WORD_LEN; 144c694b233SGeorge Cherian ++(*argcnt); 145c694b233SGeorge Cherian 146c694b233SGeorge Cherian req_info->in[*argcnt].vptr = (u8 *)fctx; 147c694b233SGeorge Cherian req_info->in[*argcnt].size = sizeof(struct fc_context); 148c694b233SGeorge Cherian req_info->req.dlen += sizeof(struct fc_context); 149c694b233SGeorge Cherian 150c694b233SGeorge Cherian ++(*argcnt); 151c694b233SGeorge Cherian 152c694b233SGeorge Cherian return 0; 153c694b233SGeorge Cherian } 154c694b233SGeorge Cherian 155c694b233SGeorge Cherian static inline u32 create_input_list(struct ablkcipher_request *req, u32 enc, 156c694b233SGeorge Cherian u32 enc_iv_len) 157c694b233SGeorge Cherian { 158c694b233SGeorge Cherian struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req); 159c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 160c694b233SGeorge Cherian u32 argcnt = 0; 161c694b233SGeorge Cherian 162e2eb769eSGeorge Cherian create_ctx_hdr(req, enc, &argcnt); 163c694b233SGeorge Cherian update_input_iv(req_info, req->info, enc_iv_len, &argcnt); 164c694b233SGeorge Cherian update_input_data(req_info, req->src, req->nbytes, &argcnt); 165c694b233SGeorge Cherian req_info->incnt = argcnt; 166c694b233SGeorge Cherian 167c694b233SGeorge Cherian return 0; 168c694b233SGeorge Cherian } 169c694b233SGeorge Cherian 170c694b233SGeorge Cherian static inline void store_cb_info(struct ablkcipher_request *req, 171c694b233SGeorge Cherian struct cpt_request_info *req_info) 172c694b233SGeorge Cherian { 173c694b233SGeorge Cherian req_info->callback = (void *)cvm_callback; 174c694b233SGeorge Cherian req_info->callback_arg = (void *)&req->base; 175c694b233SGeorge Cherian } 176c694b233SGeorge Cherian 177c694b233SGeorge Cherian static inline void create_output_list(struct ablkcipher_request *req, 178c694b233SGeorge Cherian u32 enc_iv_len) 179c694b233SGeorge Cherian { 180c694b233SGeorge Cherian struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req); 181c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 182c694b233SGeorge Cherian u32 argcnt = 0; 183c694b233SGeorge Cherian 184c694b233SGeorge Cherian /* OUTPUT Buffer Processing 185c694b233SGeorge Cherian * AES encryption/decryption output would be 186c694b233SGeorge Cherian * received in the following format 187c694b233SGeorge Cherian * 188c694b233SGeorge Cherian * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----| 189c694b233SGeorge Cherian * [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ] 190c694b233SGeorge Cherian */ 191c694b233SGeorge Cherian /* Reading IV information */ 192c694b233SGeorge Cherian update_output_iv(req_info, req->info, enc_iv_len, &argcnt); 193c694b233SGeorge Cherian update_output_data(req_info, req->dst, req->nbytes, &argcnt); 194c694b233SGeorge Cherian req_info->outcnt = argcnt; 195c694b233SGeorge Cherian } 196c694b233SGeorge Cherian 197e2eb769eSGeorge Cherian static inline int cvm_enc_dec(struct ablkcipher_request *req, u32 enc) 198c694b233SGeorge Cherian { 199c694b233SGeorge Cherian struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); 200c694b233SGeorge Cherian struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req); 201c694b233SGeorge Cherian u32 enc_iv_len = crypto_ablkcipher_ivsize(tfm); 202c694b233SGeorge Cherian struct fc_context *fctx = &rctx->fctx; 203c694b233SGeorge Cherian struct cpt_request_info *req_info = &rctx->cpt_req; 204c694b233SGeorge Cherian void *cdev = NULL; 205c694b233SGeorge Cherian int status; 206c694b233SGeorge Cherian 207c694b233SGeorge Cherian memset(req_info, 0, sizeof(struct cpt_request_info)); 208c694b233SGeorge Cherian memset(fctx, 0, sizeof(struct fc_context)); 209e2eb769eSGeorge Cherian create_input_list(req, enc, enc_iv_len); 210e2eb769eSGeorge Cherian create_output_list(req, enc_iv_len); 211c694b233SGeorge Cherian store_cb_info(req, req_info); 212c694b233SGeorge Cherian cdev = dev_handle.cdev[smp_processor_id()]; 213c694b233SGeorge Cherian status = cptvf_do_request(cdev, req_info); 214c694b233SGeorge Cherian /* We perform an asynchronous send and once 215c694b233SGeorge Cherian * the request is completed the driver would 216c694b233SGeorge Cherian * intimate through registered call back functions 217c694b233SGeorge Cherian */ 218c694b233SGeorge Cherian 219c694b233SGeorge Cherian if (status) 220c694b233SGeorge Cherian return status; 221c694b233SGeorge Cherian else 222c694b233SGeorge Cherian return -EINPROGRESS; 223c694b233SGeorge Cherian } 224c694b233SGeorge Cherian 225e2eb769eSGeorge Cherian int cvm_encrypt(struct ablkcipher_request *req) 226c694b233SGeorge Cherian { 227e2eb769eSGeorge Cherian return cvm_enc_dec(req, true); 228c694b233SGeorge Cherian } 229c694b233SGeorge Cherian 230e2eb769eSGeorge Cherian int cvm_decrypt(struct ablkcipher_request *req) 231c694b233SGeorge Cherian { 232e2eb769eSGeorge Cherian return cvm_enc_dec(req, false); 233c694b233SGeorge Cherian } 234c694b233SGeorge Cherian 235c694b233SGeorge Cherian int cvm_xts_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 236c694b233SGeorge Cherian u32 keylen) 237c694b233SGeorge Cherian { 238c694b233SGeorge Cherian struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); 239c694b233SGeorge Cherian struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm); 240c694b233SGeorge Cherian int err; 241c694b233SGeorge Cherian const u8 *key1 = key; 242c694b233SGeorge Cherian const u8 *key2 = key + (keylen / 2); 243c694b233SGeorge Cherian 244c694b233SGeorge Cherian err = xts_check_key(tfm, key, keylen); 245c694b233SGeorge Cherian if (err) 246c694b233SGeorge Cherian return err; 247c694b233SGeorge Cherian ctx->key_len = keylen; 248c694b233SGeorge Cherian memcpy(ctx->enc_key, key1, keylen / 2); 249c694b233SGeorge Cherian memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2); 250e2eb769eSGeorge Cherian ctx->cipher_type = AES_XTS; 251e2eb769eSGeorge Cherian switch (ctx->key_len) { 252e2eb769eSGeorge Cherian case 32: 253e2eb769eSGeorge Cherian ctx->key_type = AES_128_BIT; 254e2eb769eSGeorge Cherian break; 255e2eb769eSGeorge Cherian case 64: 256e2eb769eSGeorge Cherian ctx->key_type = AES_256_BIT; 257e2eb769eSGeorge Cherian break; 258e2eb769eSGeorge Cherian default: 259e2eb769eSGeorge Cherian return -EINVAL; 260e2eb769eSGeorge Cherian } 261c694b233SGeorge Cherian 262c694b233SGeorge Cherian return 0; 263c694b233SGeorge Cherian } 264c694b233SGeorge Cherian 265e2eb769eSGeorge Cherian static int cvm_validate_keylen(struct cvm_enc_ctx *ctx, u32 keylen) 266e2eb769eSGeorge Cherian { 267e2eb769eSGeorge Cherian if ((keylen == 16) || (keylen == 24) || (keylen == 32)) { 268e2eb769eSGeorge Cherian ctx->key_len = keylen; 269e2eb769eSGeorge Cherian switch (ctx->key_len) { 270e2eb769eSGeorge Cherian case 16: 271e2eb769eSGeorge Cherian ctx->key_type = AES_128_BIT; 272e2eb769eSGeorge Cherian break; 273e2eb769eSGeorge Cherian case 24: 274e2eb769eSGeorge Cherian ctx->key_type = AES_192_BIT; 275e2eb769eSGeorge Cherian break; 276e2eb769eSGeorge Cherian case 32: 277e2eb769eSGeorge Cherian ctx->key_type = AES_256_BIT; 278e2eb769eSGeorge Cherian break; 279e2eb769eSGeorge Cherian default: 280e2eb769eSGeorge Cherian return -EINVAL; 281e2eb769eSGeorge Cherian } 282e2eb769eSGeorge Cherian 283e2eb769eSGeorge Cherian if (ctx->cipher_type == DES3_CBC) 284e2eb769eSGeorge Cherian ctx->key_type = 0; 285e2eb769eSGeorge Cherian 286e2eb769eSGeorge Cherian return 0; 287e2eb769eSGeorge Cherian } 288e2eb769eSGeorge Cherian 289e2eb769eSGeorge Cherian return -EINVAL; 290e2eb769eSGeorge Cherian } 291e2eb769eSGeorge Cherian 292e2eb769eSGeorge Cherian static int cvm_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 293e2eb769eSGeorge Cherian u32 keylen, u8 cipher_type) 294c694b233SGeorge Cherian { 295c694b233SGeorge Cherian struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); 296c694b233SGeorge Cherian struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm); 297c694b233SGeorge Cherian 298e2eb769eSGeorge Cherian ctx->cipher_type = cipher_type; 299e2eb769eSGeorge Cherian if (!cvm_validate_keylen(ctx, keylen)) { 300c694b233SGeorge Cherian memcpy(ctx->enc_key, key, keylen); 301c694b233SGeorge Cherian return 0; 302e2eb769eSGeorge Cherian } else { 303e2eb769eSGeorge Cherian crypto_ablkcipher_set_flags(cipher, 304e2eb769eSGeorge Cherian CRYPTO_TFM_RES_BAD_KEY_LEN); 305c694b233SGeorge Cherian return -EINVAL; 306c694b233SGeorge Cherian } 307e2eb769eSGeorge Cherian } 308e2eb769eSGeorge Cherian 309e2eb769eSGeorge Cherian static int cvm_cbc_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 310e2eb769eSGeorge Cherian u32 keylen) 311e2eb769eSGeorge Cherian { 312e2eb769eSGeorge Cherian return cvm_setkey(cipher, key, keylen, AES_CBC); 313e2eb769eSGeorge Cherian } 314e2eb769eSGeorge Cherian 315*10d82222SGeorge Cherian static int cvm_ecb_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 316*10d82222SGeorge Cherian u32 keylen) 317*10d82222SGeorge Cherian { 318*10d82222SGeorge Cherian return cvm_setkey(cipher, key, keylen, AES_ECB); 319*10d82222SGeorge Cherian } 320*10d82222SGeorge Cherian 321*10d82222SGeorge Cherian static int cvm_cfb_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 322*10d82222SGeorge Cherian u32 keylen) 323*10d82222SGeorge Cherian { 324*10d82222SGeorge Cherian return cvm_setkey(cipher, key, keylen, AES_CFB); 325*10d82222SGeorge Cherian } 326*10d82222SGeorge Cherian 327e2eb769eSGeorge Cherian static int cvm_cbc_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 328e2eb769eSGeorge Cherian u32 keylen) 329e2eb769eSGeorge Cherian { 330e2eb769eSGeorge Cherian return cvm_setkey(cipher, key, keylen, DES3_CBC); 331e2eb769eSGeorge Cherian } 332c694b233SGeorge Cherian 333*10d82222SGeorge Cherian static int cvm_ecb_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key, 334*10d82222SGeorge Cherian u32 keylen) 335*10d82222SGeorge Cherian { 336*10d82222SGeorge Cherian return cvm_setkey(cipher, key, keylen, DES3_ECB); 337*10d82222SGeorge Cherian } 338*10d82222SGeorge Cherian 339c694b233SGeorge Cherian int cvm_enc_dec_init(struct crypto_tfm *tfm) 340c694b233SGeorge Cherian { 341c694b233SGeorge Cherian struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm); 342c694b233SGeorge Cherian 343c694b233SGeorge Cherian memset(ctx, 0, sizeof(*ctx)); 344c694b233SGeorge Cherian tfm->crt_ablkcipher.reqsize = sizeof(struct cvm_req_ctx) + 345c694b233SGeorge Cherian sizeof(struct ablkcipher_request); 346c694b233SGeorge Cherian /* Additional memory for ablkcipher_request is 347c694b233SGeorge Cherian * allocated since the cryptd daemon uses 348c694b233SGeorge Cherian * this memory for request_ctx information 349c694b233SGeorge Cherian */ 350c694b233SGeorge Cherian 351c694b233SGeorge Cherian return 0; 352c694b233SGeorge Cherian } 353c694b233SGeorge Cherian 354c694b233SGeorge Cherian struct crypto_alg algs[] = { { 355c694b233SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 356c694b233SGeorge Cherian .cra_blocksize = AES_BLOCK_SIZE, 357c694b233SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_enc_ctx), 358c694b233SGeorge Cherian .cra_alignmask = 7, 359c694b233SGeorge Cherian .cra_priority = 4001, 360c694b233SGeorge Cherian .cra_name = "xts(aes)", 361c694b233SGeorge Cherian .cra_driver_name = "cavium-xts-aes", 362c694b233SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 363c694b233SGeorge Cherian .cra_u = { 364c694b233SGeorge Cherian .ablkcipher = { 365c694b233SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 366c694b233SGeorge Cherian .min_keysize = 2 * AES_MIN_KEY_SIZE, 367c694b233SGeorge Cherian .max_keysize = 2 * AES_MAX_KEY_SIZE, 368c694b233SGeorge Cherian .setkey = cvm_xts_setkey, 369e2eb769eSGeorge Cherian .encrypt = cvm_encrypt, 370e2eb769eSGeorge Cherian .decrypt = cvm_decrypt, 371c694b233SGeorge Cherian }, 372c694b233SGeorge Cherian }, 373c694b233SGeorge Cherian .cra_init = cvm_enc_dec_init, 374c694b233SGeorge Cherian .cra_module = THIS_MODULE, 375c694b233SGeorge Cherian }, { 376c694b233SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 377c694b233SGeorge Cherian .cra_blocksize = AES_BLOCK_SIZE, 378c694b233SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_enc_ctx), 379c694b233SGeorge Cherian .cra_alignmask = 7, 380c694b233SGeorge Cherian .cra_priority = 4001, 381c694b233SGeorge Cherian .cra_name = "cbc(aes)", 382c694b233SGeorge Cherian .cra_driver_name = "cavium-cbc-aes", 383c694b233SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 384c694b233SGeorge Cherian .cra_u = { 385c694b233SGeorge Cherian .ablkcipher = { 386c694b233SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 387c694b233SGeorge Cherian .min_keysize = AES_MIN_KEY_SIZE, 388c694b233SGeorge Cherian .max_keysize = AES_MAX_KEY_SIZE, 389e2eb769eSGeorge Cherian .setkey = cvm_cbc_aes_setkey, 390e2eb769eSGeorge Cherian .encrypt = cvm_encrypt, 391e2eb769eSGeorge Cherian .decrypt = cvm_decrypt, 392c694b233SGeorge Cherian }, 393c694b233SGeorge Cherian }, 394c694b233SGeorge Cherian .cra_init = cvm_enc_dec_init, 395c694b233SGeorge Cherian .cra_module = THIS_MODULE, 396c694b233SGeorge Cherian }, { 397c694b233SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 398*10d82222SGeorge Cherian .cra_blocksize = AES_BLOCK_SIZE, 399*10d82222SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_enc_ctx), 400*10d82222SGeorge Cherian .cra_alignmask = 7, 401*10d82222SGeorge Cherian .cra_priority = 4001, 402*10d82222SGeorge Cherian .cra_name = "ecb(aes)", 403*10d82222SGeorge Cherian .cra_driver_name = "cavium-ecb-aes", 404*10d82222SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 405*10d82222SGeorge Cherian .cra_u = { 406*10d82222SGeorge Cherian .ablkcipher = { 407*10d82222SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 408*10d82222SGeorge Cherian .min_keysize = AES_MIN_KEY_SIZE, 409*10d82222SGeorge Cherian .max_keysize = AES_MAX_KEY_SIZE, 410*10d82222SGeorge Cherian .setkey = cvm_ecb_aes_setkey, 411*10d82222SGeorge Cherian .encrypt = cvm_encrypt, 412*10d82222SGeorge Cherian .decrypt = cvm_decrypt, 413*10d82222SGeorge Cherian }, 414*10d82222SGeorge Cherian }, 415*10d82222SGeorge Cherian .cra_init = cvm_enc_dec_init, 416*10d82222SGeorge Cherian .cra_module = THIS_MODULE, 417*10d82222SGeorge Cherian }, { 418*10d82222SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 419*10d82222SGeorge Cherian .cra_blocksize = AES_BLOCK_SIZE, 420*10d82222SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_enc_ctx), 421*10d82222SGeorge Cherian .cra_alignmask = 7, 422*10d82222SGeorge Cherian .cra_priority = 4001, 423*10d82222SGeorge Cherian .cra_name = "cfb(aes)", 424*10d82222SGeorge Cherian .cra_driver_name = "cavium-cfb-aes", 425*10d82222SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 426*10d82222SGeorge Cherian .cra_u = { 427*10d82222SGeorge Cherian .ablkcipher = { 428*10d82222SGeorge Cherian .ivsize = AES_BLOCK_SIZE, 429*10d82222SGeorge Cherian .min_keysize = AES_MIN_KEY_SIZE, 430*10d82222SGeorge Cherian .max_keysize = AES_MAX_KEY_SIZE, 431*10d82222SGeorge Cherian .setkey = cvm_cfb_aes_setkey, 432*10d82222SGeorge Cherian .encrypt = cvm_encrypt, 433*10d82222SGeorge Cherian .decrypt = cvm_decrypt, 434*10d82222SGeorge Cherian }, 435*10d82222SGeorge Cherian }, 436*10d82222SGeorge Cherian .cra_init = cvm_enc_dec_init, 437*10d82222SGeorge Cherian .cra_module = THIS_MODULE, 438*10d82222SGeorge Cherian }, { 439*10d82222SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 440c694b233SGeorge Cherian .cra_blocksize = DES3_EDE_BLOCK_SIZE, 441c694b233SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_des3_ctx), 442c694b233SGeorge Cherian .cra_alignmask = 7, 443c694b233SGeorge Cherian .cra_priority = 4001, 444c694b233SGeorge Cherian .cra_name = "cbc(des3_ede)", 445c694b233SGeorge Cherian .cra_driver_name = "cavium-cbc-des3_ede", 446c694b233SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 447c694b233SGeorge Cherian .cra_u = { 448c694b233SGeorge Cherian .ablkcipher = { 449c694b233SGeorge Cherian .min_keysize = DES3_EDE_KEY_SIZE, 450c694b233SGeorge Cherian .max_keysize = DES3_EDE_KEY_SIZE, 451c694b233SGeorge Cherian .ivsize = DES_BLOCK_SIZE, 452e2eb769eSGeorge Cherian .setkey = cvm_cbc_des3_setkey, 453e2eb769eSGeorge Cherian .encrypt = cvm_encrypt, 454e2eb769eSGeorge Cherian .decrypt = cvm_decrypt, 455c694b233SGeorge Cherian }, 456c694b233SGeorge Cherian }, 457c694b233SGeorge Cherian .cra_init = cvm_enc_dec_init, 458c694b233SGeorge Cherian .cra_module = THIS_MODULE, 459*10d82222SGeorge Cherian }, { 460*10d82222SGeorge Cherian .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 461*10d82222SGeorge Cherian .cra_blocksize = DES3_EDE_BLOCK_SIZE, 462*10d82222SGeorge Cherian .cra_ctxsize = sizeof(struct cvm_des3_ctx), 463*10d82222SGeorge Cherian .cra_alignmask = 7, 464*10d82222SGeorge Cherian .cra_priority = 4001, 465*10d82222SGeorge Cherian .cra_name = "ecb(des3_ede)", 466*10d82222SGeorge Cherian .cra_driver_name = "cavium-ecb-des3_ede", 467*10d82222SGeorge Cherian .cra_type = &crypto_ablkcipher_type, 468*10d82222SGeorge Cherian .cra_u = { 469*10d82222SGeorge Cherian .ablkcipher = { 470*10d82222SGeorge Cherian .min_keysize = DES3_EDE_KEY_SIZE, 471*10d82222SGeorge Cherian .max_keysize = DES3_EDE_KEY_SIZE, 472*10d82222SGeorge Cherian .ivsize = DES_BLOCK_SIZE, 473*10d82222SGeorge Cherian .setkey = cvm_ecb_des3_setkey, 474*10d82222SGeorge Cherian .encrypt = cvm_encrypt, 475*10d82222SGeorge Cherian .decrypt = cvm_decrypt, 476*10d82222SGeorge Cherian }, 477*10d82222SGeorge Cherian }, 478*10d82222SGeorge Cherian .cra_init = cvm_enc_dec_init, 479*10d82222SGeorge Cherian .cra_module = THIS_MODULE, 480c694b233SGeorge Cherian } }; 481c694b233SGeorge Cherian 482c694b233SGeorge Cherian static inline int cav_register_algs(void) 483c694b233SGeorge Cherian { 484c694b233SGeorge Cherian int err = 0; 485c694b233SGeorge Cherian 486c694b233SGeorge Cherian err = crypto_register_algs(algs, ARRAY_SIZE(algs)); 487c694b233SGeorge Cherian if (err) 488c694b233SGeorge Cherian return err; 489c694b233SGeorge Cherian 490c694b233SGeorge Cherian return 0; 491c694b233SGeorge Cherian } 492c694b233SGeorge Cherian 493c694b233SGeorge Cherian static inline void cav_unregister_algs(void) 494c694b233SGeorge Cherian { 495c694b233SGeorge Cherian crypto_unregister_algs(algs, ARRAY_SIZE(algs)); 496c694b233SGeorge Cherian } 497c694b233SGeorge Cherian 498c694b233SGeorge Cherian int cvm_crypto_init(struct cpt_vf *cptvf) 499c694b233SGeorge Cherian { 500c694b233SGeorge Cherian struct pci_dev *pdev = cptvf->pdev; 501c694b233SGeorge Cherian u32 dev_count; 502c694b233SGeorge Cherian 503c694b233SGeorge Cherian dev_count = dev_handle.dev_count; 504c694b233SGeorge Cherian dev_handle.cdev[dev_count] = cptvf; 505c694b233SGeorge Cherian dev_handle.dev_count++; 506c694b233SGeorge Cherian 507c694b233SGeorge Cherian if (dev_count == 3) { 508c694b233SGeorge Cherian if (cav_register_algs()) { 509c694b233SGeorge Cherian dev_err(&pdev->dev, "Error in registering crypto algorithms\n"); 510c694b233SGeorge Cherian return -EINVAL; 511c694b233SGeorge Cherian } 512c694b233SGeorge Cherian } 513c694b233SGeorge Cherian 514c694b233SGeorge Cherian return 0; 515c694b233SGeorge Cherian } 516c694b233SGeorge Cherian 517c694b233SGeorge Cherian void cvm_crypto_exit(void) 518c694b233SGeorge Cherian { 519c694b233SGeorge Cherian u32 dev_count; 520c694b233SGeorge Cherian 521c694b233SGeorge Cherian dev_count = --dev_handle.dev_count; 522c694b233SGeorge Cherian if (!dev_count) 523c694b233SGeorge Cherian cav_unregister_algs(); 524c694b233SGeorge Cherian } 525