178 lines
4 KiB
C
Executable file
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_ */
|