// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
#include <linux/kernel.h>
#include <linux/module.h>
#include <crypto/algapi.h>
#include <crypto/internal/skcipher.h>
#include <crypto/des.h>
#include <crypto/xts.h>
#include <crypto/scatterwalk.h>
#include "cc_driver.h"
#include "cc_lli_defs.h"
#include "cc_buffer_mgr.h"
#include "cc_cipher.h"
#include "cc_request_mgr.h"
#define MAX_ABLKCIPHER_SEQ_LEN 6
#define template_skcipher template_u.skcipher
#define CC_MIN_AES_XTS_SIZE 0x10
#define CC_MAX_AES_XTS_SIZE 0x2000
struct cc_cipher_handle {
struct list_head alg_list;
};
struct cc_user_key_info {
u8 *key;
dma_addr_t key_dma_addr;
};
struct cc_hw_key_info {
enum cc_hw_crypto_key key1_slot;
enum cc_hw_crypto_key key2_slot;
};
struct cc_cipher_ctx {
struct cc_drvdata *drvdata;
int keylen;
int key_round_number;
int cipher_mode;
int flow_mode;
unsigned int flags;
bool hw_key;
struct cc_user_key_info user;
struct cc_hw_key_info hw;
struct crypto_shash *shash_tfm;
};
static void cc_cipher_complete(struct device *dev, void *cc_req, int err);
static inline bool cc_is_hw_key(struct crypto_tfm *tfm)
{
struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm);
return ctx_p->hw_key;
}
static int validate_keys_sizes(struct cc_cipher_ctx *ctx_p, u32 size)
{
switch (ctx_p->flow_mode) {
case S_DIN_to_AES:
switch (size) {
case CC_AES_128_BIT_KEY_SIZE:
case CC_AES_192_BIT_KEY_SIZE:
if (ctx_p->cipher_mode != DRV_CIPHER_XTS &&
ctx_p->cipher_mode != DRV_CIPHER_ESSIV &&
ctx_p->cipher_mode != DRV_CIPHER_BITLOCKER)
return 0;