kernel_samsung_a53x/include/crypto/fmp.h
2024-06-15 16:02:09 -03:00

178 lines
4 KiB
C
Executable file

/*
* Copyright (C) 2016 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _EXYNOS_FMP_H_
#define _EXYNOS_FMP_H_
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/bio.h>
#include <crypto/fmp_fips.h>
#define FMP_DRV_VERSION "4.0.1"
#define FMP_KEY_SIZE_16 16
#define FMP_KEY_SIZE_32 32
#define FMP_IV_SIZE_16 16
#define FMP_CBC_MAX_KEY_SIZE FMP_KEY_SIZE_16
#define FMP_XTS_MAX_KEY_SIZE ((FMP_KEY_SIZE_32) * (2))
#define FMP_MAX_KEY_SIZE FMP_XTS_MAX_KEY_SIZE
#define FMP_HOST_TYPE_NAME_LEN 8
#define FMP_BLOCK_TYPE_NAME_LEN 8
#define FMP_SECTOR_SIZE 0x1000
#define FMP_MIN_SECTOR_SIZE 0x200
#define NUM_SECTOR_UNIT ((FMP_SECTOR_SIZE)/(FMP_MIN_SECTOR_SIZE))
#define MAX_AES_XTS_TRANSFER_SIZE 0x1000
#define CMDQ_DISABLED 0
#define MAX_RETRY_COUNT 0x100
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
enum fmp_crypto_fips_algo_mode {
EXYNOS_FMP_BYPASS_MODE = 0,
EXYNOS_FMP_ALGO_MODE_AES_CBC = 1,
EXYNOS_FMP_ALGO_MODE_AES_XTS = 2,
};
enum fmp_crypto_key_size {
EXYNOS_FMP_KEY_SIZE_16 = 16,
EXYNOS_FMP_KEY_SIZE_32 = 32,
};
enum fmp_crypto_enc_mode {
EXYNOS_FMP_FILE_ENC = 0,
EXYNOS_FMP_ENC_MAX
};
struct fmp_crypto_info {
/* This field's stongly aligned 'crypto_diskcipher->algo' */
u8 key[FMP_MAX_KEY_SIZE];
u32 key_size;
enum fmp_crypto_key_size fmp_key_size;
enum fmp_crypto_enc_mode enc_mode;
enum fmp_crypto_fips_algo_mode algo_mode;
void *ctx;
};
struct fmp_data_setting {
struct fmp_crypto_info crypt[EXYNOS_FMP_ENC_MAX];
struct fmp_table_setting *table;
bool cmdq_enabled;
};
struct fips_result {
bool overall;
bool aes_xts;
bool sha256;
bool hmac;
bool integrity;
};
#define EXYNOS_FMP_ALGO_MODE_MASK (0x3)
#define EXYNOS_FMP_ALGO_MODE_TEST_OFFSET (0xf)
#define EXYNOS_FMP_ALGO_MODE_TEST (1 << EXYNOS_FMP_ALGO_MODE_TEST_OFFSET)
struct fmp_test_data {
char block_type[FMP_BLOCK_TYPE_NAME_LEN];
struct block_device *bdev;
sector_t sector;
dev_t devt;
uint32_t test_block_offset;
/* iv to submitted */
u8 iv[FMP_IV_SIZE_16];
/* diskcipher for test */
struct fmp_crypto_info ci;
u64 DataUnitSeqNumber;
};
struct exynos_fmp {
struct device *dev;
struct fmp_test_data *test_data;
atomic_t fips_start;
struct fips_result result;
struct miscdevice miscdev;
void *test_vops;
int fips_run;
u8 dun_swap;
int fips_fin;
struct buffer_head *bh;
};
struct fmp_sg_entry {
/* The first four fields correspond to those of ufshcd_sg_entry. */
__le32 des0;
__le32 des1;
__le32 des2;
/*
* The algorithm and key length are configured in the high bits of des3,
* whose low bits already contain ufshcd_sg_entry::size.
*/
__le32 des3;
/* The IV with all bytes reversed */
__be32 file_iv[4];
/*
* The key with all bytes reversed. For XTS, the two halves of the key
* are given separately and are byte-reversed separately.
*/
__be32 file_enckey[8];
__be32 file_twkey[8];
/* Not used */
__be32 disk_iv[4];
__le32 reserved[4];
};
#define ACCESS_CONTROL_ABORT 0x14
#ifndef SMC_CMD_FMP_SECURITY
/* For FMP/SMU Ctrl */
#define SMC_CMD_FMP_SECURITY (0xC2001810)
#define SMC_CMD_SMU (0xC2001850)
#define SMC_CMD_FMP_SMU_RESUME (0xC2001860)
#define SMC_CMD_FMP_SMU_DUMP (0xC2001870)
#define SMC_CMD_UFS_LOG (0xC2001880)
#endif
/* Keyslot Selftest */
#define FMP_KW_SECUREKEY 0x8000
#define FMP_KW_SECUREKEY_OFFSET 0x80
#define EXYNOS_FMP_FIPS_KEYSLOT 0xF
#define AES_256_XTS_KEY_SIZE 64
#define AES_256_XTS_TWK_OFFSET 8
#define FMP_KW_KEYVALID 0xA00C
#define FMP_EMBEDDED 0
#define DEFAULT_KWMODE (1 | (1 << 4))
struct exynos_fmp *get_fmp(void);
int get_fmp_fips_state(void);
void exynos_fmp_fips_test(struct exynos_fmp *fmp);
#ifndef CONFIG_KEYS_IN_PRDT
unsigned long exynos_fmp_set_kw_mode(uint64_t kw_mode);
unsigned long exynos_fmp_get_kw_mode(dma_addr_t kw_mode_addr);
#endif /* CONFIG_KEYS_IN_PRDT */
#endif /* _EXYNOS_FMP_H_ */