18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci/* 48c2ecf20Sopenharmony_ci * Copyright (C) 2016 Cavium, Inc. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <crypto/aes.h> 88c2ecf20Sopenharmony_ci#include <crypto/algapi.h> 98c2ecf20Sopenharmony_ci#include <crypto/authenc.h> 108c2ecf20Sopenharmony_ci#include <crypto/internal/des.h> 118c2ecf20Sopenharmony_ci#include <crypto/xts.h> 128c2ecf20Sopenharmony_ci#include <linux/crypto.h> 138c2ecf20Sopenharmony_ci#include <linux/err.h> 148c2ecf20Sopenharmony_ci#include <linux/list.h> 158c2ecf20Sopenharmony_ci#include <linux/scatterlist.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include "cptvf.h" 188c2ecf20Sopenharmony_ci#include "cptvf_algs.h" 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistruct cpt_device_handle { 218c2ecf20Sopenharmony_ci void *cdev[MAX_DEVICES]; 228c2ecf20Sopenharmony_ci u32 dev_count; 238c2ecf20Sopenharmony_ci}; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic struct cpt_device_handle dev_handle; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic void cvm_callback(u32 status, void *arg) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci struct crypto_async_request *req = (struct crypto_async_request *)arg; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci req->complete(req, !status); 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic inline void update_input_iv(struct cpt_request_info *req_info, 358c2ecf20Sopenharmony_ci u8 *iv, u32 enc_iv_len, 368c2ecf20Sopenharmony_ci u32 *argcnt) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci /* Setting the iv information */ 398c2ecf20Sopenharmony_ci req_info->in[*argcnt].vptr = (void *)iv; 408c2ecf20Sopenharmony_ci req_info->in[*argcnt].size = enc_iv_len; 418c2ecf20Sopenharmony_ci req_info->req.dlen += enc_iv_len; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci ++(*argcnt); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic inline void update_output_iv(struct cpt_request_info *req_info, 478c2ecf20Sopenharmony_ci u8 *iv, u32 enc_iv_len, 488c2ecf20Sopenharmony_ci u32 *argcnt) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci /* Setting the iv information */ 518c2ecf20Sopenharmony_ci req_info->out[*argcnt].vptr = (void *)iv; 528c2ecf20Sopenharmony_ci req_info->out[*argcnt].size = enc_iv_len; 538c2ecf20Sopenharmony_ci req_info->rlen += enc_iv_len; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci ++(*argcnt); 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistatic inline void update_input_data(struct cpt_request_info *req_info, 598c2ecf20Sopenharmony_ci struct scatterlist *inp_sg, 608c2ecf20Sopenharmony_ci u32 nbytes, u32 *argcnt) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci req_info->req.dlen += nbytes; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci while (nbytes) { 658c2ecf20Sopenharmony_ci u32 len = min(nbytes, inp_sg->length); 668c2ecf20Sopenharmony_ci u8 *ptr = sg_virt(inp_sg); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci req_info->in[*argcnt].vptr = (void *)ptr; 698c2ecf20Sopenharmony_ci req_info->in[*argcnt].size = len; 708c2ecf20Sopenharmony_ci nbytes -= len; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci ++(*argcnt); 738c2ecf20Sopenharmony_ci ++inp_sg; 748c2ecf20Sopenharmony_ci } 758c2ecf20Sopenharmony_ci} 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic inline void update_output_data(struct cpt_request_info *req_info, 788c2ecf20Sopenharmony_ci struct scatterlist *outp_sg, 798c2ecf20Sopenharmony_ci u32 nbytes, u32 *argcnt) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci req_info->rlen += nbytes; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci while (nbytes) { 848c2ecf20Sopenharmony_ci u32 len = min(nbytes, outp_sg->length); 858c2ecf20Sopenharmony_ci u8 *ptr = sg_virt(outp_sg); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci req_info->out[*argcnt].vptr = (void *)ptr; 888c2ecf20Sopenharmony_ci req_info->out[*argcnt].size = len; 898c2ecf20Sopenharmony_ci nbytes -= len; 908c2ecf20Sopenharmony_ci ++(*argcnt); 918c2ecf20Sopenharmony_ci ++outp_sg; 928c2ecf20Sopenharmony_ci } 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistatic inline u32 create_ctx_hdr(struct skcipher_request *req, u32 enc, 968c2ecf20Sopenharmony_ci u32 *argcnt) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 998c2ecf20Sopenharmony_ci struct cvm_enc_ctx *ctx = crypto_skcipher_ctx(tfm); 1008c2ecf20Sopenharmony_ci struct cvm_req_ctx *rctx = skcipher_request_ctx(req); 1018c2ecf20Sopenharmony_ci struct fc_context *fctx = &rctx->fctx; 1028c2ecf20Sopenharmony_ci u32 enc_iv_len = crypto_skcipher_ivsize(tfm); 1038c2ecf20Sopenharmony_ci struct cpt_request_info *req_info = &rctx->cpt_req; 1048c2ecf20Sopenharmony_ci __be64 *ctrl_flags = NULL; 1058c2ecf20Sopenharmony_ci __be64 *offset_control; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci req_info->ctrl.s.grp = 0; 1088c2ecf20Sopenharmony_ci req_info->ctrl.s.dma_mode = DMA_GATHER_SCATTER; 1098c2ecf20Sopenharmony_ci req_info->ctrl.s.se_req = SE_CORE_REQ; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci req_info->req.opcode.s.major = MAJOR_OP_FC | 1128c2ecf20Sopenharmony_ci DMA_MODE_FLAG(DMA_GATHER_SCATTER); 1138c2ecf20Sopenharmony_ci if (enc) 1148c2ecf20Sopenharmony_ci req_info->req.opcode.s.minor = 2; 1158c2ecf20Sopenharmony_ci else 1168c2ecf20Sopenharmony_ci req_info->req.opcode.s.minor = 3; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci req_info->req.param1 = req->cryptlen; /* Encryption Data length */ 1198c2ecf20Sopenharmony_ci req_info->req.param2 = 0; /*Auth data length */ 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.enc_cipher = ctx->cipher_type; 1228c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.aes_key = ctx->key_type; 1238c2ecf20Sopenharmony_ci fctx->enc.enc_ctrl.e.iv_source = FROM_DPTR; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci if (ctx->cipher_type == AES_XTS) 1268c2ecf20Sopenharmony_ci memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2); 1278c2ecf20Sopenharmony_ci else 1288c2ecf20Sopenharmony_ci memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len); 1298c2ecf20Sopenharmony_ci ctrl_flags = (__be64 *)&fctx->enc.enc_ctrl.flags; 1308c2ecf20Sopenharmony_ci *ctrl_flags = cpu_to_be64(fctx->enc.enc_ctrl.flags); 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci offset_control = (__be64 *)&rctx->control_word; 1338c2ecf20Sopenharmony_ci *offset_control = cpu_to_be64(((u64)(enc_iv_len) << 16)); 1348c2ecf20Sopenharmony_ci /* Storing Packet Data Information in offset 1358c2ecf20Sopenharmony_ci * Control Word First 8 bytes 1368c2ecf20Sopenharmony_ci */ 1378c2ecf20Sopenharmony_ci req_info->in[*argcnt].vptr = (u8 *)offset_control; 1388c2ecf20Sopenharmony_ci req_info->in[*argcnt].size = CONTROL_WORD_LEN; 1398c2ecf20Sopenharmony_ci req_info->req.dlen += CONTROL_WORD_LEN; 1408c2ecf20Sopenharmony_ci ++(*argcnt); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci req_info->in[*argcnt].vptr = (u8 *)fctx; 1438c2ecf20Sopenharmony_ci req_info->in[*argcnt].size = sizeof(struct fc_context); 1448c2ecf20Sopenharmony_ci req_info->req.dlen += sizeof(struct fc_context); 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci ++(*argcnt); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci return 0; 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_cistatic inline u32 create_input_list(struct skcipher_request *req, u32 enc, 1528c2ecf20Sopenharmony_ci u32 enc_iv_len) 1538c2ecf20Sopenharmony_ci{ 1548c2ecf20Sopenharmony_ci struct cvm_req_ctx *rctx = skcipher_request_ctx(req); 1558c2ecf20Sopenharmony_ci struct cpt_request_info *req_info = &rctx->cpt_req; 1568c2ecf20Sopenharmony_ci u32 argcnt = 0; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci create_ctx_hdr(req, enc, &argcnt); 1598c2ecf20Sopenharmony_ci update_input_iv(req_info, req->iv, enc_iv_len, &argcnt); 1608c2ecf20Sopenharmony_ci update_input_data(req_info, req->src, req->cryptlen, &argcnt); 1618c2ecf20Sopenharmony_ci req_info->incnt = argcnt; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci return 0; 1648c2ecf20Sopenharmony_ci} 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_cistatic inline void store_cb_info(struct skcipher_request *req, 1678c2ecf20Sopenharmony_ci struct cpt_request_info *req_info) 1688c2ecf20Sopenharmony_ci{ 1698c2ecf20Sopenharmony_ci req_info->callback = (void *)cvm_callback; 1708c2ecf20Sopenharmony_ci req_info->callback_arg = (void *)&req->base; 1718c2ecf20Sopenharmony_ci} 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_cistatic inline void create_output_list(struct skcipher_request *req, 1748c2ecf20Sopenharmony_ci u32 enc_iv_len) 1758c2ecf20Sopenharmony_ci{ 1768c2ecf20Sopenharmony_ci struct cvm_req_ctx *rctx = skcipher_request_ctx(req); 1778c2ecf20Sopenharmony_ci struct cpt_request_info *req_info = &rctx->cpt_req; 1788c2ecf20Sopenharmony_ci u32 argcnt = 0; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci /* OUTPUT Buffer Processing 1818c2ecf20Sopenharmony_ci * AES encryption/decryption output would be 1828c2ecf20Sopenharmony_ci * received in the following format 1838c2ecf20Sopenharmony_ci * 1848c2ecf20Sopenharmony_ci * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----| 1858c2ecf20Sopenharmony_ci * [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ] 1868c2ecf20Sopenharmony_ci */ 1878c2ecf20Sopenharmony_ci /* Reading IV information */ 1888c2ecf20Sopenharmony_ci update_output_iv(req_info, req->iv, enc_iv_len, &argcnt); 1898c2ecf20Sopenharmony_ci update_output_data(req_info, req->dst, req->cryptlen, &argcnt); 1908c2ecf20Sopenharmony_ci req_info->outcnt = argcnt; 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic inline int cvm_enc_dec(struct skcipher_request *req, u32 enc) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 1968c2ecf20Sopenharmony_ci struct cvm_req_ctx *rctx = skcipher_request_ctx(req); 1978c2ecf20Sopenharmony_ci u32 enc_iv_len = crypto_skcipher_ivsize(tfm); 1988c2ecf20Sopenharmony_ci struct fc_context *fctx = &rctx->fctx; 1998c2ecf20Sopenharmony_ci struct cpt_request_info *req_info = &rctx->cpt_req; 2008c2ecf20Sopenharmony_ci void *cdev = NULL; 2018c2ecf20Sopenharmony_ci int status; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci memset(req_info, 0, sizeof(struct cpt_request_info)); 2048c2ecf20Sopenharmony_ci req_info->may_sleep = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) != 0; 2058c2ecf20Sopenharmony_ci memset(fctx, 0, sizeof(struct fc_context)); 2068c2ecf20Sopenharmony_ci create_input_list(req, enc, enc_iv_len); 2078c2ecf20Sopenharmony_ci create_output_list(req, enc_iv_len); 2088c2ecf20Sopenharmony_ci store_cb_info(req, req_info); 2098c2ecf20Sopenharmony_ci cdev = dev_handle.cdev[smp_processor_id()]; 2108c2ecf20Sopenharmony_ci status = cptvf_do_request(cdev, req_info); 2118c2ecf20Sopenharmony_ci /* We perform an asynchronous send and once 2128c2ecf20Sopenharmony_ci * the request is completed the driver would 2138c2ecf20Sopenharmony_ci * intimate through registered call back functions 2148c2ecf20Sopenharmony_ci */ 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci if (status) 2178c2ecf20Sopenharmony_ci return status; 2188c2ecf20Sopenharmony_ci else 2198c2ecf20Sopenharmony_ci return -EINPROGRESS; 2208c2ecf20Sopenharmony_ci} 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_cistatic int cvm_encrypt(struct skcipher_request *req) 2238c2ecf20Sopenharmony_ci{ 2248c2ecf20Sopenharmony_ci return cvm_enc_dec(req, true); 2258c2ecf20Sopenharmony_ci} 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic int cvm_decrypt(struct skcipher_request *req) 2288c2ecf20Sopenharmony_ci{ 2298c2ecf20Sopenharmony_ci return cvm_enc_dec(req, false); 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic int cvm_xts_setkey(struct crypto_skcipher *cipher, const u8 *key, 2338c2ecf20Sopenharmony_ci u32 keylen) 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); 2368c2ecf20Sopenharmony_ci struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm); 2378c2ecf20Sopenharmony_ci int err; 2388c2ecf20Sopenharmony_ci const u8 *key1 = key; 2398c2ecf20Sopenharmony_ci const u8 *key2 = key + (keylen / 2); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci err = xts_check_key(tfm, key, keylen); 2428c2ecf20Sopenharmony_ci if (err) 2438c2ecf20Sopenharmony_ci return err; 2448c2ecf20Sopenharmony_ci ctx->key_len = keylen; 2458c2ecf20Sopenharmony_ci memcpy(ctx->enc_key, key1, keylen / 2); 2468c2ecf20Sopenharmony_ci memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2); 2478c2ecf20Sopenharmony_ci ctx->cipher_type = AES_XTS; 2488c2ecf20Sopenharmony_ci switch (ctx->key_len) { 2498c2ecf20Sopenharmony_ci case 32: 2508c2ecf20Sopenharmony_ci ctx->key_type = AES_128_BIT; 2518c2ecf20Sopenharmony_ci break; 2528c2ecf20Sopenharmony_ci case 64: 2538c2ecf20Sopenharmony_ci ctx->key_type = AES_256_BIT; 2548c2ecf20Sopenharmony_ci break; 2558c2ecf20Sopenharmony_ci default: 2568c2ecf20Sopenharmony_ci return -EINVAL; 2578c2ecf20Sopenharmony_ci } 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci return 0; 2608c2ecf20Sopenharmony_ci} 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_cistatic int cvm_validate_keylen(struct cvm_enc_ctx *ctx, u32 keylen) 2638c2ecf20Sopenharmony_ci{ 2648c2ecf20Sopenharmony_ci if ((keylen == 16) || (keylen == 24) || (keylen == 32)) { 2658c2ecf20Sopenharmony_ci ctx->key_len = keylen; 2668c2ecf20Sopenharmony_ci switch (ctx->key_len) { 2678c2ecf20Sopenharmony_ci case 16: 2688c2ecf20Sopenharmony_ci ctx->key_type = AES_128_BIT; 2698c2ecf20Sopenharmony_ci break; 2708c2ecf20Sopenharmony_ci case 24: 2718c2ecf20Sopenharmony_ci ctx->key_type = AES_192_BIT; 2728c2ecf20Sopenharmony_ci break; 2738c2ecf20Sopenharmony_ci case 32: 2748c2ecf20Sopenharmony_ci ctx->key_type = AES_256_BIT; 2758c2ecf20Sopenharmony_ci break; 2768c2ecf20Sopenharmony_ci default: 2778c2ecf20Sopenharmony_ci return -EINVAL; 2788c2ecf20Sopenharmony_ci } 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci if (ctx->cipher_type == DES3_CBC) 2818c2ecf20Sopenharmony_ci ctx->key_type = 0; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci return 0; 2848c2ecf20Sopenharmony_ci } 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci return -EINVAL; 2878c2ecf20Sopenharmony_ci} 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cistatic int cvm_setkey(struct crypto_skcipher *cipher, const u8 *key, 2908c2ecf20Sopenharmony_ci u32 keylen, u8 cipher_type) 2918c2ecf20Sopenharmony_ci{ 2928c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); 2938c2ecf20Sopenharmony_ci struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm); 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci ctx->cipher_type = cipher_type; 2968c2ecf20Sopenharmony_ci if (!cvm_validate_keylen(ctx, keylen)) { 2978c2ecf20Sopenharmony_ci memcpy(ctx->enc_key, key, keylen); 2988c2ecf20Sopenharmony_ci return 0; 2998c2ecf20Sopenharmony_ci } else { 3008c2ecf20Sopenharmony_ci return -EINVAL; 3018c2ecf20Sopenharmony_ci } 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cistatic int cvm_cbc_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, 3058c2ecf20Sopenharmony_ci u32 keylen) 3068c2ecf20Sopenharmony_ci{ 3078c2ecf20Sopenharmony_ci return cvm_setkey(cipher, key, keylen, AES_CBC); 3088c2ecf20Sopenharmony_ci} 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_cistatic int cvm_ecb_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, 3118c2ecf20Sopenharmony_ci u32 keylen) 3128c2ecf20Sopenharmony_ci{ 3138c2ecf20Sopenharmony_ci return cvm_setkey(cipher, key, keylen, AES_ECB); 3148c2ecf20Sopenharmony_ci} 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_cistatic int cvm_cfb_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, 3178c2ecf20Sopenharmony_ci u32 keylen) 3188c2ecf20Sopenharmony_ci{ 3198c2ecf20Sopenharmony_ci return cvm_setkey(cipher, key, keylen, AES_CFB); 3208c2ecf20Sopenharmony_ci} 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_cistatic int cvm_cbc_des3_setkey(struct crypto_skcipher *cipher, const u8 *key, 3238c2ecf20Sopenharmony_ci u32 keylen) 3248c2ecf20Sopenharmony_ci{ 3258c2ecf20Sopenharmony_ci return verify_skcipher_des3_key(cipher, key) ?: 3268c2ecf20Sopenharmony_ci cvm_setkey(cipher, key, keylen, DES3_CBC); 3278c2ecf20Sopenharmony_ci} 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_cistatic int cvm_ecb_des3_setkey(struct crypto_skcipher *cipher, const u8 *key, 3308c2ecf20Sopenharmony_ci u32 keylen) 3318c2ecf20Sopenharmony_ci{ 3328c2ecf20Sopenharmony_ci return verify_skcipher_des3_key(cipher, key) ?: 3338c2ecf20Sopenharmony_ci cvm_setkey(cipher, key, keylen, DES3_ECB); 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_cistatic int cvm_enc_dec_init(struct crypto_skcipher *tfm) 3378c2ecf20Sopenharmony_ci{ 3388c2ecf20Sopenharmony_ci crypto_skcipher_set_reqsize(tfm, sizeof(struct cvm_req_ctx)); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci return 0; 3418c2ecf20Sopenharmony_ci} 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_cistatic struct skcipher_alg algs[] = { { 3448c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | 3458c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 3468c2ecf20Sopenharmony_ci .base.cra_blocksize = AES_BLOCK_SIZE, 3478c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct cvm_enc_ctx), 3488c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 3498c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 3508c2ecf20Sopenharmony_ci .base.cra_name = "xts(aes)", 3518c2ecf20Sopenharmony_ci .base.cra_driver_name = "cavium-xts-aes", 3528c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 3558c2ecf20Sopenharmony_ci .min_keysize = 2 * AES_MIN_KEY_SIZE, 3568c2ecf20Sopenharmony_ci .max_keysize = 2 * AES_MAX_KEY_SIZE, 3578c2ecf20Sopenharmony_ci .setkey = cvm_xts_setkey, 3588c2ecf20Sopenharmony_ci .encrypt = cvm_encrypt, 3598c2ecf20Sopenharmony_ci .decrypt = cvm_decrypt, 3608c2ecf20Sopenharmony_ci .init = cvm_enc_dec_init, 3618c2ecf20Sopenharmony_ci}, { 3628c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | 3638c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 3648c2ecf20Sopenharmony_ci .base.cra_blocksize = AES_BLOCK_SIZE, 3658c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct cvm_enc_ctx), 3668c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 3678c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 3688c2ecf20Sopenharmony_ci .base.cra_name = "cbc(aes)", 3698c2ecf20Sopenharmony_ci .base.cra_driver_name = "cavium-cbc-aes", 3708c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 3738c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 3748c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 3758c2ecf20Sopenharmony_ci .setkey = cvm_cbc_aes_setkey, 3768c2ecf20Sopenharmony_ci .encrypt = cvm_encrypt, 3778c2ecf20Sopenharmony_ci .decrypt = cvm_decrypt, 3788c2ecf20Sopenharmony_ci .init = cvm_enc_dec_init, 3798c2ecf20Sopenharmony_ci}, { 3808c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | 3818c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 3828c2ecf20Sopenharmony_ci .base.cra_blocksize = AES_BLOCK_SIZE, 3838c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct cvm_enc_ctx), 3848c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 3858c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 3868c2ecf20Sopenharmony_ci .base.cra_name = "ecb(aes)", 3878c2ecf20Sopenharmony_ci .base.cra_driver_name = "cavium-ecb-aes", 3888c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 3918c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 3928c2ecf20Sopenharmony_ci .setkey = cvm_ecb_aes_setkey, 3938c2ecf20Sopenharmony_ci .encrypt = cvm_encrypt, 3948c2ecf20Sopenharmony_ci .decrypt = cvm_decrypt, 3958c2ecf20Sopenharmony_ci .init = cvm_enc_dec_init, 3968c2ecf20Sopenharmony_ci}, { 3978c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | 3988c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 3998c2ecf20Sopenharmony_ci .base.cra_blocksize = AES_BLOCK_SIZE, 4008c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct cvm_enc_ctx), 4018c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 4028c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 4038c2ecf20Sopenharmony_ci .base.cra_name = "cfb(aes)", 4048c2ecf20Sopenharmony_ci .base.cra_driver_name = "cavium-cfb-aes", 4058c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 4088c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 4098c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 4108c2ecf20Sopenharmony_ci .setkey = cvm_cfb_aes_setkey, 4118c2ecf20Sopenharmony_ci .encrypt = cvm_encrypt, 4128c2ecf20Sopenharmony_ci .decrypt = cvm_decrypt, 4138c2ecf20Sopenharmony_ci .init = cvm_enc_dec_init, 4148c2ecf20Sopenharmony_ci}, { 4158c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | 4168c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 4178c2ecf20Sopenharmony_ci .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, 4188c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct cvm_des3_ctx), 4198c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 4208c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 4218c2ecf20Sopenharmony_ci .base.cra_name = "cbc(des3_ede)", 4228c2ecf20Sopenharmony_ci .base.cra_driver_name = "cavium-cbc-des3_ede", 4238c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 4268c2ecf20Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 4278c2ecf20Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 4288c2ecf20Sopenharmony_ci .setkey = cvm_cbc_des3_setkey, 4298c2ecf20Sopenharmony_ci .encrypt = cvm_encrypt, 4308c2ecf20Sopenharmony_ci .decrypt = cvm_decrypt, 4318c2ecf20Sopenharmony_ci .init = cvm_enc_dec_init, 4328c2ecf20Sopenharmony_ci}, { 4338c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_ASYNC | 4348c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY, 4358c2ecf20Sopenharmony_ci .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, 4368c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct cvm_des3_ctx), 4378c2ecf20Sopenharmony_ci .base.cra_alignmask = 7, 4388c2ecf20Sopenharmony_ci .base.cra_priority = 4001, 4398c2ecf20Sopenharmony_ci .base.cra_name = "ecb(des3_ede)", 4408c2ecf20Sopenharmony_ci .base.cra_driver_name = "cavium-ecb-des3_ede", 4418c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 4448c2ecf20Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 4458c2ecf20Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 4468c2ecf20Sopenharmony_ci .setkey = cvm_ecb_des3_setkey, 4478c2ecf20Sopenharmony_ci .encrypt = cvm_encrypt, 4488c2ecf20Sopenharmony_ci .decrypt = cvm_decrypt, 4498c2ecf20Sopenharmony_ci .init = cvm_enc_dec_init, 4508c2ecf20Sopenharmony_ci} }; 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_cistatic inline int cav_register_algs(void) 4538c2ecf20Sopenharmony_ci{ 4548c2ecf20Sopenharmony_ci return crypto_register_skciphers(algs, ARRAY_SIZE(algs)); 4558c2ecf20Sopenharmony_ci} 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_cistatic inline void cav_unregister_algs(void) 4588c2ecf20Sopenharmony_ci{ 4598c2ecf20Sopenharmony_ci crypto_unregister_skciphers(algs, ARRAY_SIZE(algs)); 4608c2ecf20Sopenharmony_ci} 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_ciint cvm_crypto_init(struct cpt_vf *cptvf) 4638c2ecf20Sopenharmony_ci{ 4648c2ecf20Sopenharmony_ci struct pci_dev *pdev = cptvf->pdev; 4658c2ecf20Sopenharmony_ci u32 dev_count; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci dev_count = dev_handle.dev_count; 4688c2ecf20Sopenharmony_ci dev_handle.cdev[dev_count] = cptvf; 4698c2ecf20Sopenharmony_ci dev_handle.dev_count++; 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci if (dev_count == 3) { 4728c2ecf20Sopenharmony_ci if (cav_register_algs()) { 4738c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Error in registering crypto algorithms\n"); 4748c2ecf20Sopenharmony_ci return -EINVAL; 4758c2ecf20Sopenharmony_ci } 4768c2ecf20Sopenharmony_ci } 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci return 0; 4798c2ecf20Sopenharmony_ci} 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_civoid cvm_crypto_exit(void) 4828c2ecf20Sopenharmony_ci{ 4838c2ecf20Sopenharmony_ci u32 dev_count; 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci dev_count = --dev_handle.dev_count; 4868c2ecf20Sopenharmony_ci if (!dev_count) 4878c2ecf20Sopenharmony_ci cav_unregister_algs(); 4888c2ecf20Sopenharmony_ci} 489