crypto: eip93 - Add Inside Secure SafeXcel EIP-93 crypto engine support

Add support for the Inside Secure SafeXcel EIP-93 Crypto Engine used on
Mediatek MT7621 SoC and new Airoha SoC.

EIP-93 IP supports AES/DES/3DES ciphers in ECB/CBC and CTR modes as well as
authenc(HMAC(x), cipher(y)) using HMAC MD5, SHA1, SHA224 and SHA256.

EIP-93 provide regs to signal support for specific chipers and the
driver dynamically register only the supported one by the chip.

Signed-off-by: Richard van Schagen <vschagen@icloud.com>
Co-developed-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Christian Marangi
2025-02-09 18:08:11 +08:00
committed by Herbert Xu
parent bbbbd1d149
commit 9739f5f93b
18 changed files with 4056 additions and 0 deletions
+7
View File
@@ -11466,6 +11466,13 @@ L: linux-crypto@vger.kernel.org
S: Maintained
F: drivers/crypto/inside-secure/
INSIDE SECURE EIP93 CRYPTO DRIVER
M: Christian Marangi <ansuelsmth@gmail.com>
L: linux-crypto@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/crypto/inside-secure,safexcel-eip93.yaml
F: drivers/crypto/inside-secure/eip93/
INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
M: Mimi Zohar <zohar@linux.ibm.com>
M: Roberto Sassu <roberto.sassu@huawei.com>
+1
View File
@@ -855,5 +855,6 @@ config CRYPTO_DEV_SA2UL
source "drivers/crypto/aspeed/Kconfig"
source "drivers/crypto/starfive/Kconfig"
source "drivers/crypto/inside-secure/eip93/Kconfig"
endif # CRYPTO_HW
+1
View File
@@ -50,3 +50,4 @@ obj-y += hisilicon/
obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
obj-y += intel/
obj-y += starfive/
obj-y += inside-secure/eip93/
@@ -0,0 +1,20 @@
# SPDX-License-Identifier: GPL-2.0
config CRYPTO_DEV_EIP93
tristate "Support for EIP93 crypto HW accelerators"
depends on SOC_MT7621 || ARCH_AIROHA ||COMPILE_TEST
select CRYPTO_LIB_AES
select CRYPTO_LIB_DES
select CRYPTO_SKCIPHER
select CRYPTO_AEAD
select CRYPTO_AUTHENC
select CRYPTO_MD5
select CRYPTO_SHA1
select CRYPTO_SHA256
help
EIP93 have various crypto HW accelerators. Select this if
you want to use the EIP93 modules for any of the crypto algorithms.
If the IP supports it, this provide offload for AES - ECB, CBC and
CTR crypto. Also provide DES and 3DES ECB and CBC.
Also provide AEAD authenc(hmac(x), cipher(y)) for supported algo.
@@ -0,0 +1,5 @@
obj-$(CONFIG_CRYPTO_DEV_EIP93) += crypto-hw-eip93.o
crypto-hw-eip93-y += eip93-main.o eip93-common.o
crypto-hw-eip93-y += eip93-cipher.o eip93-aead.o
crypto-hw-eip93-y += eip93-hash.o
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2019 - 2021
*
* Richard van Schagen <vschagen@icloud.com>
* Christian Marangi <ansuelsmth@gmail.com
*/
#ifndef _EIP93_AEAD_H_
#define _EIP93_AEAD_H_
extern struct eip93_alg_template eip93_alg_authenc_hmac_md5_cbc_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha1_cbc_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha224_cbc_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha256_cbc_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_md5_ctr_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha1_ctr_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha224_ctr_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha256_ctr_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_md5_rfc3686_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha1_rfc3686_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha224_rfc3686_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha256_rfc3686_aes;
extern struct eip93_alg_template eip93_alg_authenc_hmac_md5_cbc_des;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha1_cbc_des;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha224_cbc_des;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha256_cbc_des;
extern struct eip93_alg_template eip93_alg_authenc_hmac_md5_cbc_des3_ede;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha1_cbc_des3_ede;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha224_cbc_des3_ede;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha256_cbc_des3_ede;
extern struct eip93_alg_template eip93_alg_authenc_hmac_md5_ecb_null;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha1_ecb_null;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha224_ecb_null;
extern struct eip93_alg_template eip93_alg_authenc_hmac_sha256_ecb_null;
void eip93_aead_handle_result(struct crypto_async_request *async, int err);
#endif /* _EIP93_AEAD_H_ */
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2019 - 2021
*
* Richard van Schagen <vschagen@icloud.com>
* Christian Marangi <ansuelsmth@gmail.com
*/
#ifndef _EIP93_AES_H_
#define _EIP93_AES_H_
extern struct eip93_alg_template eip93_alg_ecb_aes;
extern struct eip93_alg_template eip93_alg_cbc_aes;
extern struct eip93_alg_template eip93_alg_ctr_aes;
extern struct eip93_alg_template eip93_alg_rfc3686_aes;
#endif /* _EIP93_AES_H_ */
@@ -0,0 +1,413 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 - 2021
*
* Richard van Schagen <vschagen@icloud.com>
* Christian Marangi <ansuelsmth@gmail.com
*/
#include <crypto/aes.h>
#include <crypto/ctr.h>
#include <crypto/internal/des.h>
#include <linux/dma-mapping.h>
#include "eip93-aes.h"
#include "eip93-cipher.h"
#include "eip93-common.h"
#include "eip93-des.h"
#include "eip93-regs.h"
void eip93_skcipher_handle_result(struct crypto_async_request *async, int err)
{
struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(async->tfm);
struct eip93_device *eip93 = ctx->eip93;
struct skcipher_request *req = skcipher_request_cast(async);
struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req);
eip93_unmap_dma(eip93, rctx, req->src, req->dst);
eip93_handle_result(eip93, rctx, req->iv);
skcipher_request_complete(req, err);
}
static int eip93_skcipher_send_req(struct crypto_async_request *async)
{
struct skcipher_request *req = skcipher_request_cast(async);
struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req);
int err;
err = check_valid_request(rctx);
if (err) {
skcipher_request_complete(req, err);
return err;
}
return eip93_send_req(async, req->iv, rctx);
}
/* Crypto skcipher API functions */
static int eip93_skcipher_cra_init(struct crypto_tfm *tfm)
{
struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
struct eip93_alg_template *tmpl = container_of(tfm->__crt_alg,
struct eip93_alg_template, alg.skcipher.base);
crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm),
sizeof(struct eip93_cipher_reqctx));
memset(ctx, 0, sizeof(*ctx));
ctx->eip93 = tmpl->eip93;
ctx->type = tmpl->type;
ctx->sa_record = kzalloc(sizeof(*ctx->sa_record), GFP_KERNEL);
if (!ctx->sa_record)
return -ENOMEM;
return 0;
}
static void eip93_skcipher_cra_exit(struct crypto_tfm *tfm)
{
struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
dma_unmap_single(ctx->eip93->dev, ctx->sa_record_base,
sizeof(*ctx->sa_record), DMA_TO_DEVICE);
kfree(ctx->sa_record);
}
static int eip93_skcipher_setkey(struct crypto_skcipher *ctfm, const u8 *key,
unsigned int len)
{
struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
struct eip93_alg_template *tmpl = container_of(tfm->__crt_alg,
struct eip93_alg_template,
alg.skcipher.base);
struct sa_record *sa_record = ctx->sa_record;
unsigned int keylen = len;
u32 flags = tmpl->flags;
u32 nonce = 0;
int ret;
if (!key || !keylen)
return -EINVAL;
if (IS_RFC3686(flags)) {
if (len < CTR_RFC3686_NONCE_SIZE)
return -EINVAL;
keylen = len - CTR_RFC3686_NONCE_SIZE;
memcpy(&nonce, key + keylen, CTR_RFC3686_NONCE_SIZE);
}
if (flags & EIP93_ALG_DES) {
ctx->blksize = DES_BLOCK_SIZE;
ret = verify_skcipher_des_key(ctfm, key);
if (ret)
return ret;
}
if (flags & EIP93_ALG_3DES) {
ctx->blksize = DES3_EDE_BLOCK_SIZE;
ret = verify_skcipher_des3_key(ctfm, key);
if (ret)
return ret;
}
if (flags & EIP93_ALG_AES) {
struct crypto_aes_ctx aes;
ctx->blksize = AES_BLOCK_SIZE;
ret = aes_expandkey(&aes, key, keylen);
if (ret)
return ret;
}
eip93_set_sa_record(sa_record, keylen, flags);
memcpy(sa_record->sa_key, key, keylen);
ctx->sa_nonce = nonce;
sa_record->sa_nonce = nonce;
return 0;
}
static int eip93_skcipher_crypt(struct skcipher_request *req)
{
struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req);
struct crypto_async_request *async = &req->base;
struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
int ret;
if (!req->cryptlen)
return 0;
/*
* ECB and CBC algorithms require message lengths to be
* multiples of block size.
*/
if (IS_ECB(rctx->flags) || IS_CBC(rctx->flags))
if (!IS_ALIGNED(req->cryptlen,
crypto_skcipher_blocksize(skcipher)))
return -EINVAL;
ctx->sa_record_base = dma_map_single(ctx->eip93->dev, ctx->sa_record,
sizeof(*ctx->sa_record), DMA_TO_DEVICE);
ret = dma_mapping_error(ctx->eip93->dev, ctx->sa_record_base);
if (ret)
return ret;
rctx->assoclen = 0;
rctx->textsize = req->cryptlen;
rctx->authsize = 0;
rctx->sg_src = req->src;
rctx->sg_dst = req->dst;
rctx->ivsize = crypto_skcipher_ivsize(skcipher);
rctx->blksize = ctx->blksize;
rctx->desc_flags = EIP93_DESC_SKCIPHER;
rctx->sa_record_base = ctx->sa_record_base;
return eip93_skcipher_send_req(async);
}
static int eip93_skcipher_encrypt(struct skcipher_request *req)
{
struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req);
struct eip93_alg_template *tmpl = container_of(req->base.tfm->__crt_alg,
struct eip93_alg_template, alg.skcipher.base);
rctx->flags = tmpl->flags;
rctx->flags |= EIP93_ENCRYPT;
return eip93_skcipher_crypt(req);
}
static int eip93_skcipher_decrypt(struct skcipher_request *req)
{
struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req);
struct eip93_alg_template *tmpl = container_of(req->base.tfm->__crt_alg,
struct eip93_alg_template, alg.skcipher.base);
ctx->sa_record->sa_cmd0_word |= EIP93_SA_CMD_DIRECTION_IN;
rctx->flags = tmpl->flags;
rctx->flags |= EIP93_DECRYPT;
return eip93_skcipher_crypt(req);
}
/* Available algorithms in this module */
struct eip93_alg_template eip93_alg_ecb_aes = {
.type = EIP93_ALG_TYPE_SKCIPHER,
.flags = EIP93_MODE_ECB | EIP93_ALG_AES,
.alg.skcipher = {
.setkey = eip93_skcipher_setkey,
.encrypt = eip93_skcipher_encrypt,
.decrypt = eip93_skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.ivsize = 0,
.base = {
.cra_name = "ecb(aes)",
.cra_driver_name = "ecb(aes-eip93)",
.cra_priority = EIP93_CRA_PRIORITY,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK |
CRYPTO_ALG_KERN_DRIVER_ONLY,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct eip93_crypto_ctx),
.cra_alignmask = 0xf,
.cra_init = eip93_skcipher_cra_init,
.cra_exit = eip93_skcipher_cra_exit,
.cra_module = THIS_MODULE,
},
},
};
struct eip93_alg_template eip93_alg_cbc_aes = {
.type = EIP93_ALG_TYPE_SKCIPHER,
.flags = EIP93_MODE_CBC | EIP93_ALG_AES,
.alg.skcipher = {
.setkey = eip93_skcipher_setkey,
.encrypt = eip93_skcipher_encrypt,
.decrypt = eip93_skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE,
.base = {
.cra_name = "cbc(aes)",
.cra_driver_name = "cbc(aes-eip93)",
.cra_priority = EIP93_CRA_PRIORITY,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK |
CRYPTO_ALG_KERN_DRIVER_ONLY,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct eip93_crypto_ctx),
.cra_alignmask = 0xf,
.cra_init = eip93_skcipher_cra_init,
.cra_exit = eip93_skcipher_cra_exit,
.cra_module = THIS_MODULE,
},
},
};
struct eip93_alg_template eip93_alg_ctr_aes = {
.type = EIP93_ALG_TYPE_SKCIPHER,
.flags = EIP93_MODE_CTR | EIP93_ALG_AES,
.alg.skcipher = {
.setkey = eip93_skcipher_setkey,
.encrypt = eip93_skcipher_encrypt,
.decrypt = eip93_skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE,
.base = {
.cra_name = "ctr(aes)",
.cra_driver_name = "ctr(aes-eip93)",
.cra_priority = EIP93_CRA_PRIORITY,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK |
CRYPTO_ALG_KERN_DRIVER_ONLY,
.cra_blocksize = 1,
.cra_ctxsize = sizeof(struct eip93_crypto_ctx),
.cra_alignmask = 0xf,
.cra_init = eip93_skcipher_cra_init,
.cra_exit = eip93_skcipher_cra_exit,
.cra_module = THIS_MODULE,
},
},
};
struct eip93_alg_template eip93_alg_rfc3686_aes = {
.type = EIP93_ALG_TYPE_SKCIPHER,
.flags = EIP93_MODE_CTR | EIP93_MODE_RFC3686 | EIP93_ALG_AES,
.alg.skcipher = {
.setkey = eip93_skcipher_setkey,
.encrypt = eip93_skcipher_encrypt,
.decrypt = eip93_skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
.max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
.ivsize = CTR_RFC3686_IV_SIZE,
.base = {
.cra_name = "rfc3686(ctr(aes))",
.cra_driver_name = "rfc3686(ctr(aes-eip93))",
.cra_priority = EIP93_CRA_PRIORITY,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK |
CRYPTO_ALG_KERN_DRIVER_ONLY,
.cra_blocksize = 1,
.cra_ctxsize = sizeof(struct eip93_crypto_ctx),
.cra_alignmask = 0xf,
.cra_init = eip93_skcipher_cra_init,
.cra_exit = eip93_skcipher_cra_exit,
.cra_module = THIS_MODULE,
},
},
};
struct eip93_alg_template eip93_alg_ecb_des = {
.type = EIP93_ALG_TYPE_SKCIPHER,
.flags = EIP93_MODE_ECB | EIP93_ALG_DES,
.alg.skcipher = {
.setkey = eip93_skcipher_setkey,
.encrypt = eip93_skcipher_encrypt,
.decrypt = eip93_skcipher_decrypt,
.min_keysize = DES_KEY_SIZE,
.max_keysize = DES_KEY_SIZE,
.ivsize = 0,
.base = {
.cra_name = "ecb(des)",
.cra_driver_name = "ebc(des-eip93)",
.cra_priority = EIP93_CRA_PRIORITY,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_KERN_DRIVER_ONLY,
.cra_blocksize = DES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct eip93_crypto_ctx),
.cra_alignmask = 0,
.cra_init = eip93_skcipher_cra_init,
.cra_exit = eip93_skcipher_cra_exit,
.cra_module = THIS_MODULE,
},
},
};
struct eip93_alg_template eip93_alg_cbc_des = {
.type = EIP93_ALG_TYPE_SKCIPHER,
.flags = EIP93_MODE_CBC | EIP93_ALG_DES,
.alg.skcipher = {
.setkey = eip93_skcipher_setkey,
.encrypt = eip93_skcipher_encrypt,
.decrypt = eip93_skcipher_decrypt,
.min_keysize = DES_KEY_SIZE,
.max_keysize = DES_KEY_SIZE,
.ivsize = DES_BLOCK_SIZE,
.base = {
.cra_name = "cbc(des)",
.cra_driver_name = "cbc(des-eip93)",
.cra_priority = EIP93_CRA_PRIORITY,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_KERN_DRIVER_ONLY,
.cra_blocksize = DES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct eip93_crypto_ctx),
.cra_alignmask = 0,
.cra_init = eip93_skcipher_cra_init,
.cra_exit = eip93_skcipher_cra_exit,
.cra_module = THIS_MODULE,
},
},
};
struct eip93_alg_template eip93_alg_ecb_des3_ede = {
.type = EIP93_ALG_TYPE_SKCIPHER,
.flags = EIP93_MODE_ECB | EIP93_ALG_3DES,
.alg.skcipher = {
.setkey = eip93_skcipher_setkey,
.encrypt = eip93_skcipher_encrypt,
.decrypt = eip93_skcipher_decrypt,
.min_keysize = DES3_EDE_KEY_SIZE,
.max_keysize = DES3_EDE_KEY_SIZE,
.ivsize = 0,
.base = {
.cra_name = "ecb(des3_ede)",
.cra_driver_name = "ecb(des3_ede-eip93)",
.cra_priority = EIP93_CRA_PRIORITY,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_KERN_DRIVER_ONLY,
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct eip93_crypto_ctx),
.cra_alignmask = 0,
.cra_init = eip93_skcipher_cra_init,
.cra_exit = eip93_skcipher_cra_exit,
.cra_module = THIS_MODULE,
},
},
};
struct eip93_alg_template eip93_alg_cbc_des3_ede = {
.type = EIP93_ALG_TYPE_SKCIPHER,
.flags = EIP93_MODE_CBC | EIP93_ALG_3DES,
.alg.skcipher = {
.setkey = eip93_skcipher_setkey,
.encrypt = eip93_skcipher_encrypt,
.decrypt = eip93_skcipher_decrypt,
.min_keysize = DES3_EDE_KEY_SIZE,
.max_keysize = DES3_EDE_KEY_SIZE,
.ivsize = DES3_EDE_BLOCK_SIZE,
.base = {
.cra_name = "cbc(des3_ede)",
.cra_driver_name = "cbc(des3_ede-eip93)",
.cra_priority = EIP93_CRA_PRIORITY,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_KERN_DRIVER_ONLY,
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct eip93_crypto_ctx),
.cra_alignmask = 0,
.cra_init = eip93_skcipher_cra_init,
.cra_exit = eip93_skcipher_cra_exit,
.cra_module = THIS_MODULE,
},
},
};
@@ -0,0 +1,60 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2019 - 2021
*
* Richard van Schagen <vschagen@icloud.com>
* Christian Marangi <ansuelsmth@gmail.com
*/
#ifndef _EIP93_CIPHER_H_
#define _EIP93_CIPHER_H_
#include "eip93-main.h"
struct eip93_crypto_ctx {
struct eip93_device *eip93;
u32 flags;
struct sa_record *sa_record;
u32 sa_nonce;
int blksize;
dma_addr_t sa_record_base;
/* AEAD specific */
unsigned int authsize;
unsigned int assoclen;
bool set_assoc;
enum eip93_alg_type type;
};
struct eip93_cipher_reqctx {
u16 desc_flags;
u16 flags;
unsigned int blksize;
unsigned int ivsize;
unsigned int textsize;
unsigned int assoclen;
unsigned int authsize;
dma_addr_t sa_record_base;
struct sa_state *sa_state;
dma_addr_t sa_state_base;
struct eip93_descriptor *cdesc;
struct scatterlist *sg_src;
struct scatterlist *sg_dst;
int src_nents;
int dst_nents;
struct sa_state *sa_state_ctr;
dma_addr_t sa_state_ctr_base;
};
int check_valid_request(struct eip93_cipher_reqctx *rctx);
void eip93_unmap_dma(struct eip93_device *eip93, struct eip93_cipher_reqctx *rctx,
struct scatterlist *reqsrc, struct scatterlist *reqdst);
void eip93_skcipher_handle_result(struct crypto_async_request *async, int err);
int eip93_send_req(struct crypto_async_request *async,
const u8 *reqiv, struct eip93_cipher_reqctx *rctx);
void eip93_handle_result(struct eip93_device *eip93, struct eip93_cipher_reqctx *rctx,
u8 *reqiv);
#endif /* _EIP93_CIPHER_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2019 - 2021
*
* Richard van Schagen <vschagen@icloud.com>
* Christian Marangi <ansuelsmth@gmail.com
*/
#ifndef _EIP93_COMMON_H_
#define _EIP93_COMMON_H_
void *eip93_get_descriptor(struct eip93_device *eip93);
int eip93_put_descriptor(struct eip93_device *eip93, struct eip93_descriptor *desc);
void eip93_set_sa_record(struct sa_record *sa_record, const unsigned int keylen,
const u32 flags);
int eip93_parse_ctrl_stat_err(struct eip93_device *eip93, int err);
int eip93_hmac_setkey(u32 ctx_flags, const u8 *key, unsigned int keylen,
unsigned int hashlen, u8 *ipad, u8 *opad,
bool skip_ipad);
#endif /* _EIP93_COMMON_H_ */
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2019 - 2021
*
* Richard van Schagen <vschagen@icloud.com>
* Christian Marangi <ansuelsmth@gmail.com
*/
#ifndef _EIP93_DES_H_
#define _EIP93_DES_H_
extern struct eip93_alg_template eip93_alg_ecb_des;
extern struct eip93_alg_template eip93_alg_cbc_des;
extern struct eip93_alg_template eip93_alg_ecb_des3_ede;
extern struct eip93_alg_template eip93_alg_cbc_des3_ede;
#endif /* _EIP93_DES_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,82 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2019 - 2021
*
* Richard van Schagen <vschagen@icloud.com>
* Christian Marangi <ansuelsmth@gmail.com
*/
#ifndef _EIP93_HASH_H_
#define _EIP93_HASH_H_
#include <crypto/sha2.h>
#include "eip93-main.h"
#include "eip93-regs.h"
struct eip93_hash_ctx {
struct eip93_device *eip93;
u32 flags;
u8 ipad[SHA256_BLOCK_SIZE] __aligned(sizeof(u32));
u8 opad[SHA256_DIGEST_SIZE] __aligned(sizeof(u32));
};
struct eip93_hash_reqctx {
/* Placement is important for DMA align */
struct {
struct sa_record sa_record;
struct sa_record sa_record_hmac;
struct sa_state sa_state;
} __aligned(CRYPTO_DMA_ALIGN);
dma_addr_t sa_record_base;
dma_addr_t sa_record_hmac_base;
dma_addr_t sa_state_base;
/* Don't enable HASH_FINALIZE when last block is sent */
bool partial_hash;
/* Set to signal interrupt is for final packet */
bool finalize;
/*
* EIP93 requires data to be accumulated in block of 64 bytes
* for intermediate hash calculation.
*/
u64 len;
u32 data_used;
u8 data[SHA256_BLOCK_SIZE] __aligned(sizeof(u32));
dma_addr_t data_dma;
struct list_head blocks;
};
struct mkt_hash_block {
struct list_head list;
u8 data[SHA256_BLOCK_SIZE] __aligned(sizeof(u32));
dma_addr_t data_dma;
};
struct eip93_hash_export_state {
u64 len;
u32 data_used;
u32 state_len[2];
u8 state_hash[SHA256_DIGEST_SIZE] __aligned(sizeof(u32));
u8 data[SHA256_BLOCK_SIZE] __aligned(sizeof(u32));
};
void eip93_hash_handle_result(struct crypto_async_request *async, int err);
extern struct eip93_alg_template eip93_alg_md5;
extern struct eip93_alg_template eip93_alg_sha1;
extern struct eip93_alg_template eip93_alg_sha224;
extern struct eip93_alg_template eip93_alg_sha256;
extern struct eip93_alg_template eip93_alg_hmac_md5;
extern struct eip93_alg_template eip93_alg_hmac_sha1;
extern struct eip93_alg_template eip93_alg_hmac_sha224;
extern struct eip93_alg_template eip93_alg_hmac_sha256;
#endif /* _EIP93_HASH_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,151 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2019 - 2021
*
* Richard van Schagen <vschagen@icloud.com>
* Christian Marangi <ansuelsmth@gmail.com
*/
#ifndef _EIP93_MAIN_H_
#define _EIP93_MAIN_H_
#include <crypto/internal/aead.h>
#include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h>
#include <linux/bitfield.h>
#include <linux/interrupt.h>
#define EIP93_RING_BUSY_DELAY 500
#define EIP93_RING_NUM 512
#define EIP93_RING_BUSY 32
#define EIP93_CRA_PRIORITY 1500
#define EIP93_RING_SA_STATE_ADDR(base, idx) ((base) + (idx))
#define EIP93_RING_SA_STATE_DMA(dma_base, idx) ((u32 __force)(dma_base) + \
((idx) * sizeof(struct sa_state)))
/* cipher algorithms */
#define EIP93_ALG_DES BIT(0)
#define EIP93_ALG_3DES BIT(1)
#define EIP93_ALG_AES BIT(2)
#define EIP93_ALG_MASK GENMASK(2, 0)
/* hash and hmac algorithms */
#define EIP93_HASH_MD5 BIT(3)
#define EIP93_HASH_SHA1 BIT(4)
#define EIP93_HASH_SHA224 BIT(5)
#define EIP93_HASH_SHA256 BIT(6)
#define EIP93_HASH_HMAC BIT(7)
#define EIP93_HASH_MASK GENMASK(6, 3)
/* cipher modes */
#define EIP93_MODE_CBC BIT(8)
#define EIP93_MODE_ECB BIT(9)
#define EIP93_MODE_CTR BIT(10)
#define EIP93_MODE_RFC3686 BIT(11)
#define EIP93_MODE_MASK GENMASK(10, 8)
/* cipher encryption/decryption operations */
#define EIP93_ENCRYPT BIT(12)
#define EIP93_DECRYPT BIT(13)
#define EIP93_BUSY BIT(14)
/* descriptor flags */
#define EIP93_DESC_DMA_IV BIT(0)
#define EIP93_DESC_IPSEC BIT(1)
#define EIP93_DESC_FINISH BIT(2)
#define EIP93_DESC_LAST BIT(3)
#define EIP93_DESC_FAKE_HMAC BIT(4)
#define EIP93_DESC_PRNG BIT(5)
#define EIP93_DESC_HASH BIT(6)
#define EIP93_DESC_AEAD BIT(7)
#define EIP93_DESC_SKCIPHER BIT(8)
#define EIP93_DESC_ASYNC BIT(9)
#define IS_DMA_IV(desc_flags) ((desc_flags) & EIP93_DESC_DMA_IV)
#define IS_DES(flags) ((flags) & EIP93_ALG_DES)
#define IS_3DES(flags) ((flags) & EIP93_ALG_3DES)
#define IS_AES(flags) ((flags) & EIP93_ALG_AES)
#define IS_HASH_MD5(flags) ((flags) & EIP93_HASH_MD5)
#define IS_HASH_SHA1(flags) ((flags) & EIP93_HASH_SHA1)
#define IS_HASH_SHA224(flags) ((flags) & EIP93_HASH_SHA224)
#define IS_HASH_SHA256(flags) ((flags) & EIP93_HASH_SHA256)
#define IS_HMAC(flags) ((flags) & EIP93_HASH_HMAC)
#define IS_CBC(mode) ((mode) & EIP93_MODE_CBC)
#define IS_ECB(mode) ((mode) & EIP93_MODE_ECB)
#define IS_CTR(mode) ((mode) & EIP93_MODE_CTR)
#define IS_RFC3686(mode) ((mode) & EIP93_MODE_RFC3686)
#define IS_BUSY(flags) ((flags) & EIP93_BUSY)
#define IS_ENCRYPT(dir) ((dir) & EIP93_ENCRYPT)
#define IS_DECRYPT(dir) ((dir) & EIP93_DECRYPT)
#define IS_CIPHER(flags) ((flags) & (EIP93_ALG_DES | \
EIP93_ALG_3DES | \
EIP93_ALG_AES))
#define IS_HASH(flags) ((flags) & (EIP93_HASH_MD5 | \
EIP93_HASH_SHA1 | \
EIP93_HASH_SHA224 | \
EIP93_HASH_SHA256))
/**
* struct eip93_device - crypto engine device structure
*/
struct eip93_device {
void __iomem *base;
struct device *dev;
struct clk *clk;
int irq;
struct eip93_ring *ring;
};
struct eip93_desc_ring {
void *base;
void *base_end;
dma_addr_t base_dma;
/* write and read pointers */
void *read;
void *write;
/* descriptor element offset */
u32 offset;
};
struct eip93_state_pool {
void *base;
dma_addr_t base_dma;
};
struct eip93_ring {
struct tasklet_struct done_task;
/* command/result rings */
struct eip93_desc_ring cdr;
struct eip93_desc_ring rdr;
spinlock_t write_lock;
spinlock_t read_lock;
/* aync idr */
spinlock_t idr_lock;
struct idr crypto_async_idr;
};
enum eip93_alg_type {
EIP93_ALG_TYPE_AEAD,
EIP93_ALG_TYPE_SKCIPHER,
EIP93_ALG_TYPE_HASH,
};
struct eip93_alg_template {
struct eip93_device *eip93;
enum eip93_alg_type type;
u32 flags;
union {
struct aead_alg aead;
struct skcipher_alg skcipher;
struct ahash_alg ahash;
} alg;
};
#endif /* _EIP93_MAIN_H_ */
@@ -0,0 +1,335 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2019 - 2021
*
* Richard van Schagen <vschagen@icloud.com>
* Christian Marangi <ansuelsmth@gmail.com
*/
#ifndef REG_EIP93_H
#define REG_EIP93_H
#define EIP93_REG_PE_CTRL_STAT 0x0
#define EIP93_PE_CTRL_PE_PAD_CTRL_STAT GENMASK(31, 24)
#define EIP93_PE_CTRL_PE_EXT_ERR_CODE GENMASK(23, 20)
#define EIP93_PE_CTRL_PE_EXT_ERR_PROCESSING 0x8
#define EIP93_PE_CTRL_PE_EXT_ERR_BLOCK_SIZE_ERR 0x7
#define EIP93_PE_CTRL_PE_EXT_ERR_INVALID_PK_LENGTH 0x6
#define EIP93_PE_CTRL_PE_EXT_ERR_ZERO_LENGTH 0x5
#define EIP93_PE_CTRL_PE_EXT_ERR_SPI 0x4
#define EIP93_PE_CTRL_PE_EXT_ERR_INVALID_CRYPTO_ALGO 0x3
#define EIP93_PE_CTRL_PE_EXT_ERR_INVALID_CRYPTO_OP 0x2
#define EIP93_PE_CTRL_PE_EXT_ERR_DESC_OWNER 0x1
#define EIP93_PE_CTRL_PE_EXT_ERR_BUS 0x0
#define EIP93_PE_CTRL_PE_EXT_ERR BIT(19)
#define EIP93_PE_CTRL_PE_SEQNUM_ERR BIT(18)
#define EIP93_PE_CTRL_PE_PAD_ERR BIT(17)
#define EIP93_PE_CTRL_PE_AUTH_ERR BIT(16)
#define EIP93_PE_CTRL_PE_PAD_VALUE GENMASK(15, 8)
#define EIP93_PE_CTRL_PE_PRNG_MODE GENMASK(7, 6)
#define EIP93_PE_CTRL_PE_HASH_FINAL BIT(4)
#define EIP93_PE_CTRL_PE_INIT_ARC4 BIT(3)
#define EIP93_PE_CTRL_PE_READY_DES_TRING_OWN GENMASK(1, 0)
#define EIP93_PE_CTRL_PE_READY 0x2
#define EIP93_PE_CTRL_HOST_READY 0x1
#define EIP93_REG_PE_SOURCE_ADDR 0x4
#define EIP93_REG_PE_DEST_ADDR 0x8
#define EIP93_REG_PE_SA_ADDR 0xc
#define EIP93_REG_PE_ADDR 0x10 /* STATE_ADDR */
/*
* Special implementation for user ID
* user_id in eip93_descriptor is used to identify the
* descriptor and is opaque and can be used by the driver
* in custom way.
*
* The usage of this should be to put an address to the crypto
* request struct from the kernel but this can't work in 64bit
* world.
*
* Also it's required to put some flags to identify the last
* descriptor.
*
* To handle this, split the u32 in 2 part:
* - 31:16 descriptor flags
* - 15:0 IDR to connect the crypto request address
*/
#define EIP93_REG_PE_USER_ID 0x18
#define EIP93_PE_USER_ID_DESC_FLAGS GENMASK(31, 16)
#define EIP93_PE_USER_ID_CRYPTO_IDR GENMASK(15, 0)
#define EIP93_REG_PE_LENGTH 0x1c
#define EIP93_PE_LENGTH_BYPASS GENMASK(31, 24)
#define EIP93_PE_LENGTH_HOST_PE_READY GENMASK(23, 22)
#define EIP93_PE_LENGTH_PE_READY 0x2
#define EIP93_PE_LENGTH_HOST_READY 0x1
#define EIP93_PE_LENGTH_LENGTH GENMASK(19, 0)
/* PACKET ENGINE RING configuration registers */
#define EIP93_REG_PE_CDR_BASE 0x80
#define EIP93_REG_PE_RDR_BASE 0x84
#define EIP93_REG_PE_RING_CONFIG 0x88
#define EIP93_PE_EN_EXT_TRIG BIT(31)
/* Absent in later revision of eip93 */
/* #define EIP93_PE_RING_OFFSET GENMASK(23, 15) */
#define EIP93_PE_RING_SIZE GENMASK(9, 0)
#define EIP93_REG_PE_RING_THRESH 0x8c
#define EIPR93_PE_TIMEROUT_EN BIT(31)
#define EIPR93_PE_RD_TIMEOUT GENMASK(29, 26)
#define EIPR93_PE_RDR_THRESH GENMASK(25, 16)
#define EIPR93_PE_CDR_THRESH GENMASK(9, 0)
#define EIP93_REG_PE_CD_COUNT 0x90
#define EIP93_PE_CD_COUNT GENMASK(10, 0)
/*
* In the same register, writing a value in GENMASK(7, 0) will
* increment the descriptor count and start DMA action.
*/
#define EIP93_PE_CD_COUNT_INCR GENMASK(7, 0)
#define EIP93_REG_PE_RD_COUNT 0x94
#define EIP93_PE_RD_COUNT GENMASK(10, 0)
/*
* In the same register, writing a value in GENMASK(7, 0) will
* increment the descriptor count and start DMA action.
*/
#define EIP93_PE_RD_COUNT_INCR GENMASK(7, 0)
#define EIP93_REG_PE_RING_RW_PNTR 0x98 /* RING_PNTR */
/* PACKET ENGINE configuration registers */
#define EIP93_REG_PE_CONFIG 0x100
#define EIP93_PE_CONFIG_SWAP_TARGET BIT(20)
#define EIP93_PE_CONFIG_SWAP_DATA BIT(18)
#define EIP93_PE_CONFIG_SWAP_SA BIT(17)
#define EIP93_PE_CONFIG_SWAP_CDRD BIT(16)
#define EIP93_PE_CONFIG_EN_CDR_UPDATE BIT(10)
#define EIP93_PE_CONFIG_PE_MODE GENMASK(9, 8)
#define EIP93_PE_TARGET_AUTO_RING_MODE FIELD_PREP(EIP93_PE_CONFIG_PE_MODE, 0x3)
#define EIP93_PE_TARGET_COMMAND_NO_RDR_MODE FIELD_PREP(EIP93_PE_CONFIG_PE_MODE, 0x2)
#define EIP93_PE_TARGET_COMMAND_WITH_RDR_MODE FIELD_PREP(EIP93_PE_CONFIG_PE_MODE, 0x1)
#define EIP93_PE_DIRECT_HOST_MODE FIELD_PREP(EIP93_PE_CONFIG_PE_MODE, 0x0)
#define EIP93_PE_CONFIG_RST_RING BIT(2)
#define EIP93_PE_CONFIG_RST_PE BIT(0)
#define EIP93_REG_PE_STATUS 0x104
#define EIP93_REG_PE_BUF_THRESH 0x10c
#define EIP93_PE_OUTBUF_THRESH GENMASK(23, 16)
#define EIP93_PE_INBUF_THRESH GENMASK(7, 0)
#define EIP93_REG_PE_INBUF_COUNT 0x100
#define EIP93_REG_PE_OUTBUF_COUNT 0x114
#define EIP93_REG_PE_BUF_RW_PNTR 0x118 /* BUF_PNTR */
/* PACKET ENGINE endian config */
#define EIP93_REG_PE_ENDIAN_CONFIG 0x1cc
#define EIP93_AIROHA_REG_PE_ENDIAN_CONFIG 0x1d0
#define EIP93_PE_ENDIAN_TARGET_BYTE_SWAP GENMASK(23, 16)
#define EIP93_PE_ENDIAN_MASTER_BYTE_SWAP GENMASK(7, 0)
/*
* Byte goes 2 and 2 and are referenced by ID
* Split GENMASK(7, 0) in 4 part, one for each byte.
* Example LITTLE ENDIAN: Example BIG ENDIAN
* GENMASK(7, 6) 0x3 GENMASK(7, 6) 0x0
* GENMASK(5, 4) 0x2 GENMASK(7, 6) 0x1
* GENMASK(3, 2) 0x1 GENMASK(3, 2) 0x2
* GENMASK(1, 0) 0x0 GENMASK(1, 0) 0x3
*/
#define EIP93_PE_ENDIAN_BYTE0 0x0
#define EIP93_PE_ENDIAN_BYTE1 0x1
#define EIP93_PE_ENDIAN_BYTE2 0x2
#define EIP93_PE_ENDIAN_BYTE3 0x3
/* EIP93 CLOCK control registers */
#define EIP93_REG_PE_CLOCK_CTRL 0x1e8
#define EIP93_PE_CLOCK_EN_HASH_CLK BIT(4)
#define EIP93_PE_CLOCK_EN_ARC4_CLK BIT(3)
#define EIP93_PE_CLOCK_EN_AES_CLK BIT(2)
#define EIP93_PE_CLOCK_EN_DES_CLK BIT(1)
#define EIP93_PE_CLOCK_EN_PE_CLK BIT(0)
/* EIP93 Device Option and Revision Register */
#define EIP93_REG_PE_OPTION_1 0x1f4
#define EIP93_PE_OPTION_MAC_KEY256 BIT(31)
#define EIP93_PE_OPTION_MAC_KEY192 BIT(30)
#define EIP93_PE_OPTION_MAC_KEY128 BIT(29)
#define EIP93_PE_OPTION_AES_CBC_MAC BIT(28)
#define EIP93_PE_OPTION_AES_XCBX BIT(23)
#define EIP93_PE_OPTION_SHA_256 BIT(19)
#define EIP93_PE_OPTION_SHA_224 BIT(18)
#define EIP93_PE_OPTION_SHA_1 BIT(17)
#define EIP93_PE_OPTION_MD5 BIT(16)
#define EIP93_PE_OPTION_AES_KEY256 BIT(15)
#define EIP93_PE_OPTION_AES_KEY192 BIT(14)
#define EIP93_PE_OPTION_AES_KEY128 BIT(13)
#define EIP93_PE_OPTION_AES BIT(2)
#define EIP93_PE_OPTION_ARC4 BIT(1)
#define EIP93_PE_OPTION_TDES BIT(0) /* DES and TDES */
#define EIP93_REG_PE_OPTION_0 0x1f8
#define EIP93_REG_PE_REVISION 0x1fc
#define EIP93_PE_REVISION_MAJ_HW_REV GENMASK(27, 24)
#define EIP93_PE_REVISION_MIN_HW_REV GENMASK(23, 20)
#define EIP93_PE_REVISION_HW_PATCH GENMASK(19, 16)
#define EIP93_PE_REVISION_EIP_NO GENMASK(7, 0)
/* EIP93 Interrupt Control Register */
#define EIP93_REG_INT_UNMASK_STAT 0x200
#define EIP93_REG_INT_MASK_STAT 0x204
#define EIP93_REG_INT_CLR 0x204
#define EIP93_REG_INT_MASK 0x208 /* INT_EN */
/* Each int reg have the same bitmap */
#define EIP93_INT_INTERFACE_ERR BIT(18)
#define EIP93_INT_RPOC_ERR BIT(17)
#define EIP93_INT_PE_RING_ERR BIT(16)
#define EIP93_INT_HALT BIT(15)
#define EIP93_INT_OUTBUF_THRESH BIT(11)
#define EIP93_INT_INBUF_THRESH BIT(10)
#define EIP93_INT_OPERATION_DONE BIT(9)
#define EIP93_INT_RDR_THRESH BIT(1)
#define EIP93_INT_CDR_THRESH BIT(0)
#define EIP93_INT_ALL (EIP93_INT_INTERFACE_ERR | \
EIP93_INT_RPOC_ERR | \
EIP93_INT_PE_RING_ERR | \
EIP93_INT_HALT | \
EIP93_INT_OUTBUF_THRESH | \
EIP93_INT_INBUF_THRESH | \
EIP93_INT_OPERATION_DONE | \
EIP93_INT_RDR_THRESH | \
EIP93_INT_CDR_THRESH)
#define EIP93_REG_INT_CFG 0x20c
#define EIP93_INT_TYPE_PULSE BIT(0)
#define EIP93_REG_MASK_ENABLE 0x210
#define EIP93_REG_MASK_DISABLE 0x214
/* EIP93 SA Record register */
#define EIP93_REG_SA_CMD_0 0x400
#define EIP93_SA_CMD_SAVE_HASH BIT(29)
#define EIP93_SA_CMD_SAVE_IV BIT(28)
#define EIP93_SA_CMD_HASH_SOURCE GENMASK(27, 26)
#define EIP93_SA_CMD_HASH_NO_LOAD FIELD_PREP(EIP93_SA_CMD_HASH_SOURCE, 0x3)
#define EIP93_SA_CMD_HASH_FROM_STATE FIELD_PREP(EIP93_SA_CMD_HASH_SOURCE, 0x2)
#define EIP93_SA_CMD_HASH_FROM_SA FIELD_PREP(EIP93_SA_CMD_HASH_SOURCE, 0x0)
#define EIP93_SA_CMD_IV_SOURCE GENMASK(25, 24)
#define EIP93_SA_CMD_IV_FROM_PRNG FIELD_PREP(EIP93_SA_CMD_IV_SOURCE, 0x3)
#define EIP93_SA_CMD_IV_FROM_STATE FIELD_PREP(EIP93_SA_CMD_IV_SOURCE, 0x2)
#define EIP93_SA_CMD_IV_FROM_INPUT FIELD_PREP(EIP93_SA_CMD_IV_SOURCE, 0x1)
#define EIP93_SA_CMD_IV_NO_LOAD FIELD_PREP(EIP93_SA_CMD_IV_SOURCE, 0x0)
#define EIP93_SA_CMD_DIGEST_LENGTH GENMASK(23, 20)
#define EIP93_SA_CMD_DIGEST_10WORD FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, 0xa) /* SRTP and TLS */
#define EIP93_SA_CMD_DIGEST_8WORD FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, 0x8) /* SHA-256 */
#define EIP93_SA_CMD_DIGEST_7WORD FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, 0x7) /* SHA-224 */
#define EIP93_SA_CMD_DIGEST_6WORD FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, 0x6)
#define EIP93_SA_CMD_DIGEST_5WORD FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, 0x5) /* SHA1 */
#define EIP93_SA_CMD_DIGEST_4WORD FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, 0x4) /* MD5 and AES-based */
#define EIP93_SA_CMD_DIGEST_3WORD_IPSEC FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, 0x3) /* IPSEC */
#define EIP93_SA_CMD_DIGEST_2WORD FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, 0x2)
#define EIP93_SA_CMD_DIGEST_1WORD FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, 0x1)
#define EIP93_SA_CMD_DIGEST_3WORD FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, 0x0) /* 96bit output */
#define EIP93_SA_CMD_HDR_PROC BIT(19)
#define EIP93_SA_CMD_EXT_PAD BIT(18)
#define EIP93_SA_CMD_SCPAD BIT(17)
#define EIP93_SA_CMD_HASH GENMASK(15, 12)
#define EIP93_SA_CMD_HASH_NULL FIELD_PREP(EIP93_SA_CMD_HASH, 0xf)
#define EIP93_SA_CMD_HASH_SHA256 FIELD_PREP(EIP93_SA_CMD_HASH, 0x3)
#define EIP93_SA_CMD_HASH_SHA224 FIELD_PREP(EIP93_SA_CMD_HASH, 0x2)
#define EIP93_SA_CMD_HASH_SHA1 FIELD_PREP(EIP93_SA_CMD_HASH, 0x1)
#define EIP93_SA_CMD_HASH_MD5 FIELD_PREP(EIP93_SA_CMD_HASH, 0x0)
#define EIP93_SA_CMD_CIPHER GENMASK(11, 8)
#define EIP93_SA_CMD_CIPHER_NULL FIELD_PREP(EIP93_SA_CMD_CIPHER, 0xf)
#define EIP93_SA_CMD_CIPHER_AES FIELD_PREP(EIP93_SA_CMD_CIPHER, 0x3)
#define EIP93_SA_CMD_CIPHER_ARC4 FIELD_PREP(EIP93_SA_CMD_CIPHER, 0x2)
#define EIP93_SA_CMD_CIPHER_3DES FIELD_PREP(EIP93_SA_CMD_CIPHER, 0x1)
#define EIP93_SA_CMD_CIPHER_DES FIELD_PREP(EIP93_SA_CMD_CIPHER, 0x0)
#define EIP93_SA_CMD_PAD_TYPE GENMASK(7, 6)
#define EIP93_SA_CMD_PAD_CONST_SSL FIELD_PREP(EIP93_SA_CMD_PAD_TYPE, 0x6)
#define EIP93_SA_CMD_PAD_TLS_DTLS FIELD_PREP(EIP93_SA_CMD_PAD_TYPE, 0x5)
#define EIP93_SA_CMD_PAD_ZERO FIELD_PREP(EIP93_SA_CMD_PAD_TYPE, 0x3)
#define EIP93_SA_CMD_PAD_CONST FIELD_PREP(EIP93_SA_CMD_PAD_TYPE, 0x2)
#define EIP93_SA_CMD_PAD_PKCS7 FIELD_PREP(EIP93_SA_CMD_PAD_TYPE, 0x1)
#define EIP93_SA_CMD_PAD_IPSEC FIELD_PREP(EIP93_SA_CMD_PAD_TYPE, 0x0)
#define EIP93_SA_CMD_OPGROUP GENMASK(5, 4)
#define EIP93_SA_CMD_OP_EXT FIELD_PREP(EIP93_SA_CMD_OPGROUP, 0x2)
#define EIP93_SA_CMD_OP_PROTOCOL FIELD_PREP(EIP93_SA_CMD_OPGROUP, 0x1)
#define EIP93_SA_CMD_OP_BASIC FIELD_PREP(EIP93_SA_CMD_OPGROUP, 0x0)
#define EIP93_SA_CMD_DIRECTION_IN BIT(3) /* 0: outbount 1: inbound */
#define EIP93_SA_CMD_OPCODE GENMASK(2, 0)
#define EIP93_SA_CMD_OPCODE_BASIC_OUT_PRNG 0x7
#define EIP93_SA_CMD_OPCODE_BASIC_OUT_HASH 0x3
#define EIP93_SA_CMD_OPCODE_BASIC_OUT_ENC_HASH 0x1
#define EIP93_SA_CMD_OPCODE_BASIC_OUT_ENC 0x0
#define EIP93_SA_CMD_OPCODE_BASIC_IN_HASH 0x3
#define EIP93_SA_CMD_OPCODE_BASIC_IN_HASH_DEC 0x1
#define EIP93_SA_CMD_OPCODE_BASIC_IN_DEC 0x0
#define EIP93_SA_CMD_OPCODE_PROTOCOL_OUT_ESP 0x0
#define EIP93_SA_CMD_OPCODE_PROTOCOL_OUT_SSL 0x4
#define EIP93_SA_CMD_OPCODE_PROTOCOL_OUT_TLS 0x5
#define EIP93_SA_CMD_OPCODE_PROTOCOL_OUT_SRTP 0x7
#define EIP93_SA_CMD_OPCODE_PROTOCOL_IN_ESP 0x0
#define EIP93_SA_CMD_OPCODE_PROTOCOL_IN_SSL 0x2
#define EIP93_SA_CMD_OPCODE_PROTOCOL_IN_TLS 0x3
#define EIP93_SA_CMD_OPCODE_PROTOCOL_IN_SRTP 0x7
#define EIP93_SA_CMD_OPCODE_EXT_OUT_DTSL 0x1
#define EIP93_SA_CMD_OPCODE_EXT_OUT_SSL 0x4
#define EIP93_SA_CMD_OPCODE_EXT_OUT_TLSV10 0x5
#define EIP93_SA_CMD_OPCODE_EXT_OUT_TLSV11 0x6
#define EIP93_SA_CMD_OPCODE_EXT_IN_DTSL 0x1
#define EIP93_SA_CMD_OPCODE_EXT_IN_SSL 0x4
#define EIP93_SA_CMD_OPCODE_EXT_IN_TLSV10 0x5
#define EIP93_SA_CMD_OPCODE_EXT_IN_TLSV11 0x6
#define EIP93_REG_SA_CMD_1 0x404
#define EIP93_SA_CMD_EN_SEQNUM_CHK BIT(29)
/* This mask can be either used for ARC4 or AES */
#define EIP93_SA_CMD_ARC4_KEY_LENGHT GENMASK(28, 24)
#define EIP93_SA_CMD_AES_DEC_KEY BIT(28) /* 0: encrypt key 1: decrypt key */
#define EIP93_SA_CMD_AES_KEY_LENGTH GENMASK(26, 24)
#define EIP93_SA_CMD_AES_KEY_256BIT FIELD_PREP(EIP93_SA_CMD_AES_KEY_LENGTH, 0x4)
#define EIP93_SA_CMD_AES_KEY_192BIT FIELD_PREP(EIP93_SA_CMD_AES_KEY_LENGTH, 0x3)
#define EIP93_SA_CMD_AES_KEY_128BIT FIELD_PREP(EIP93_SA_CMD_AES_KEY_LENGTH, 0x2)
#define EIP93_SA_CMD_HASH_CRYPT_OFFSET GENMASK(23, 16)
#define EIP93_SA_CMD_BYTE_OFFSET BIT(13) /* 0: CRYPT_OFFSET in 32bit word 1: CRYPT_OFFSET in 8bit bytes */
#define EIP93_SA_CMD_HMAC BIT(12)
#define EIP93_SA_CMD_SSL_MAC BIT(12)
/* This mask can be either used for ARC4 or AES */
#define EIP93_SA_CMD_CHIPER_MODE GENMASK(9, 8)
/* AES or DES operations */
#define EIP93_SA_CMD_CHIPER_MODE_ICM FIELD_PREP(EIP93_SA_CMD_CHIPER_MODE, 0x3)
#define EIP93_SA_CMD_CHIPER_MODE_CTR FIELD_PREP(EIP93_SA_CMD_CHIPER_MODE, 0x2)
#define EIP93_SA_CMD_CHIPER_MODE_CBC FIELD_PREP(EIP93_SA_CMD_CHIPER_MODE, 0x1)
#define EIP93_SA_CMD_CHIPER_MODE_ECB FIELD_PREP(EIP93_SA_CMD_CHIPER_MODE, 0x0)
/* ARC4 operations */
#define EIP93_SA_CMD_CHIPER_MODE_STATEFULL FIELD_PREP(EIP93_SA_CMD_CHIPER_MODE, 0x1)
#define EIP93_SA_CMD_CHIPER_MODE_STATELESS FIELD_PREP(EIP93_SA_CMD_CHIPER_MODE, 0x0)
#define EIP93_SA_CMD_COPY_PAD BIT(3)
#define EIP93_SA_CMD_COPY_PAYLOAD BIT(2)
#define EIP93_SA_CMD_COPY_HEADER BIT(1)
#define EIP93_SA_CMD_COPY_DIGEST BIT(0) /* With this enabled, COPY_PAD is required */
/* State save register */
#define EIP93_REG_STATE_IV_0 0x500
#define EIP93_REG_STATE_IV_1 0x504
#define EIP93_REG_PE_ARC4STATE 0x700
struct sa_record {
u32 sa_cmd0_word;
u32 sa_cmd1_word;
u32 sa_key[8];
u8 sa_i_digest[32];
u8 sa_o_digest[32];
u32 sa_spi;
u32 sa_seqnum[2];
u32 sa_seqmum_mask[2];
u32 sa_nonce;
} __packed;
struct sa_state {
u32 state_iv[4];
u32 state_byte_cnt[2];
u8 state_i_digest[32];
} __packed;
struct eip93_descriptor {
u32 pe_ctrl_stat_word;
u32 src_addr;
u32 dst_addr;
u32 sa_addr;
u32 state_addr;
u32 arc4_addr;
u32 user_id;
u32 pe_length_word;
} __packed;
#endif