blob: 155c3c9b87c20ac5ca85238557c625e38c0e560b [file] [log] [blame]
/*
*
* sep_crypto.h - Crypto interface structures
*
* Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
* Contributions(c) 2009-2010 Discretix. All rights reserved.
*
* 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; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* CONTACTS:
*
* Mark Allyn mark.a.allyn@intel.com
* Jayant Mangalampalli jayant.mangalampalli@intel.com
*
* CHANGES:
*
* 2009.06.26 Initial publish
* 2011.02.22 Enable Kernel Crypto
*
*/
/* Constants for SEP (from vendor) */
#define SEP_START_MSG_TOKEN 0x02558808
#define SEP_DES_IV_SIZE_WORDS 2
#define SEP_DES_IV_SIZE_BYTES (SEP_DES_IV_SIZE_WORDS * \
sizeof(u32))
#define SEP_DES_KEY_SIZE_WORDS 2
#define SEP_DES_KEY_SIZE_BYTES (SEP_DES_KEY_SIZE_WORDS * \
sizeof(u32))
#define SEP_DES_BLOCK_SIZE 8
#define SEP_DES_DUMMY_SIZE 16
#define SEP_DES_INIT_OPCODE 0x10
#define SEP_DES_BLOCK_OPCODE 0x11
#define SEP_AES_BLOCK_SIZE_WORDS 4
#define SEP_AES_BLOCK_SIZE_BYTES \
(SEP_AES_BLOCK_SIZE_WORDS * sizeof(u32))
#define SEP_AES_DUMMY_BLOCK_SIZE 16
#define SEP_AES_IV_SIZE_WORDS SEP_AES_BLOCK_SIZE_WORDS
#define SEP_AES_IV_SIZE_BYTES \
(SEP_AES_IV_SIZE_WORDS * sizeof(u32))
#define SEP_AES_KEY_128_SIZE 16
#define SEP_AES_KEY_192_SIZE 24
#define SEP_AES_KEY_256_SIZE 32
#define SEP_AES_KEY_512_SIZE 64
#define SEP_AES_MAX_KEY_SIZE_WORDS 16
#define SEP_AES_MAX_KEY_SIZE_BYTES \
(SEP_AES_MAX_KEY_SIZE_WORDS * sizeof(u32))
#define SEP_AES_WRAP_MIN_SIZE 8
#define SEP_AES_WRAP_MAX_SIZE 0x10000000
#define SEP_AES_WRAP_BLOCK_SIZE_WORDS 2
#define SEP_AES_WRAP_BLOCK_SIZE_BYTES \
(SEP_AES_WRAP_BLOCK_SIZE_WORDS * sizeof(u32))
#define SEP_AES_SECRET_RKEK1 0x1
#define SEP_AES_SECRET_RKEK2 0x2
#define SEP_AES_INIT_OPCODE 0x2
#define SEP_AES_BLOCK_OPCODE 0x3
#define SEP_AES_FINISH_OPCODE 0x4
#define SEP_AES_WRAP_OPCODE 0x6
#define SEP_AES_UNWRAP_OPCODE 0x7
#define SEP_AES_XTS_FINISH_OPCODE 0x8
#define SEP_HASH_RESULT_SIZE_WORDS 16
#define SEP_MD5_DIGEST_SIZE_WORDS 4
#define SEP_MD5_DIGEST_SIZE_BYTES \
(SEP_MD5_DIGEST_SIZE_WORDS * sizeof(u32))
#define SEP_SHA1_DIGEST_SIZE_WORDS 5
#define SEP_SHA1_DIGEST_SIZE_BYTES \
(SEP_SHA1_DIGEST_SIZE_WORDS * sizeof(u32))
#define SEP_SHA224_DIGEST_SIZE_WORDS 7
#define SEP_SHA224_DIGEST_SIZE_BYTES \
(SEP_SHA224_DIGEST_SIZE_WORDS * sizeof(u32))
#define SEP_SHA256_DIGEST_SIZE_WORDS 8
#define SEP_SHA256_DIGEST_SIZE_BYTES \
(SEP_SHA256_DIGEST_SIZE_WORDS * sizeof(u32))
#define SEP_SHA384_DIGEST_SIZE_WORDS 12
#define SEP_SHA384_DIGEST_SIZE_BYTES \
(SEP_SHA384_DIGEST_SIZE_WORDS * sizeof(u32))
#define SEP_SHA512_DIGEST_SIZE_WORDS 16
#define SEP_SHA512_DIGEST_SIZE_BYTES \
(SEP_SHA512_DIGEST_SIZE_WORDS * sizeof(u32))
#define SEP_HASH_BLOCK_SIZE_WORDS 16
#define SEP_HASH_BLOCK_SIZE_BYTES \
(SEP_HASH_BLOCK_SIZE_WORDS * sizeof(u32))
#define SEP_SHA2_BLOCK_SIZE_WORDS 32
#define SEP_SHA2_BLOCK_SIZE_BYTES \
(SEP_SHA2_BLOCK_SIZE_WORDS * sizeof(u32))
#define SEP_HASH_INIT_OPCODE 0x20
#define SEP_HASH_UPDATE_OPCODE 0x21
#define SEP_HASH_FINISH_OPCODE 0x22
#define SEP_HASH_SINGLE_OPCODE 0x23
#define SEP_HOST_ERROR 0x0b000000
#define SEP_OK 0x0
#define SEP_INVALID_START (SEP_HOST_ERROR + 0x3)
#define SEP_WRONG_OPCODE (SEP_HOST_ERROR + 0x1)
#define SEP_TRANSACTION_WAIT_TIME 5
#define SEP_QUEUE_LENGTH 2
/* Macros */
#ifndef __LITTLE_ENDIAN
#define CHG_ENDIAN(val) \
(((val) >> 24) | \
(((val) & 0x00FF0000) >> 8) | \
(((val) & 0x0000FF00) << 8) | \
(((val) & 0x000000FF) << 24))
#else
#define CHG_ENDIAN(val) val
#endif
/* Enums for SEP (from vendor) */
enum des_numkey {
DES_KEY_1 = 1,
DES_KEY_2 = 2,
DES_KEY_3 = 3,
SEP_NUMKEY_OPTIONS,
SEP_NUMKEY_LAST = 0x7fffffff,
};
enum des_enc_mode {
SEP_DES_ENCRYPT = 0,
SEP_DES_DECRYPT = 1,
SEP_DES_ENC_OPTIONS,
SEP_DES_ENC_LAST = 0x7fffffff,
};
enum des_op_mode {
SEP_DES_ECB = 0,
SEP_DES_CBC = 1,
SEP_OP_OPTIONS,
SEP_OP_LAST = 0x7fffffff,
};
enum aes_keysize {
AES_128 = 0,
AES_192 = 1,
AES_256 = 2,
AES_512 = 3,
AES_SIZE_OPTIONS,
AEA_SIZE_LAST = 0x7FFFFFFF,
};
enum aes_enc_mode {
SEP_AES_ENCRYPT = 0,
SEP_AES_DECRYPT = 1,
SEP_AES_ENC_OPTIONS,
SEP_AES_ENC_LAST = 0x7FFFFFFF,
};
enum aes_op_mode {
SEP_AES_ECB = 0,
SEP_AES_CBC = 1,
SEP_AES_MAC = 2,
SEP_AES_CTR = 3,
SEP_AES_XCBC = 4,
SEP_AES_CMAC = 5,
SEP_AES_XTS = 6,
SEP_AES_OP_OPTIONS,
SEP_AES_OP_LAST = 0x7FFFFFFF,
};
enum hash_op_mode {
SEP_HASH_SHA1 = 0,
SEP_HASH_SHA224 = 1,
SEP_HASH_SHA256 = 2,
SEP_HASH_SHA384 = 3,
SEP_HASH_SHA512 = 4,
SEP_HASH_MD5 = 5,
SEP_HASH_OPTIONS,
SEP_HASH_LAST_MODE = 0x7FFFFFFF,
};
/* Structures for SEP (from vendor) */
struct sep_des_internal_key {
u32 key1[SEP_DES_KEY_SIZE_WORDS];
u32 key2[SEP_DES_KEY_SIZE_WORDS];
u32 key3[SEP_DES_KEY_SIZE_WORDS];
};
struct sep_des_internal_context {
u32 iv_context[SEP_DES_IV_SIZE_WORDS];
struct sep_des_internal_key context_key;
enum des_numkey nbr_keys;
enum des_enc_mode encryption;
enum des_op_mode operation;
u8 dummy_block[SEP_DES_DUMMY_SIZE];
};
struct sep_des_private_context {
u32 valid_tag;
u32 iv;
u8 ctx_buf[sizeof(struct sep_des_internal_context)];
};
/* This is the structure passed to SEP via msg area */
struct sep_des_key {
u32 key1[SEP_DES_KEY_SIZE_WORDS];
u32 key2[SEP_DES_KEY_SIZE_WORDS];
u32 key3[SEP_DES_KEY_SIZE_WORDS];
u32 pad[SEP_DES_KEY_SIZE_WORDS];
};
struct sep_aes_internal_context {
u32 aes_ctx_iv[SEP_AES_IV_SIZE_WORDS];
u32 aes_ctx_key[SEP_AES_MAX_KEY_SIZE_WORDS / 2];
enum aes_keysize keysize;
enum aes_enc_mode encmode;
enum aes_op_mode opmode;
u8 secret_key;
u32 no_add_blocks;
u32 last_block_size;
u32 last_block[SEP_AES_BLOCK_SIZE_WORDS];
u32 prev_iv[SEP_AES_BLOCK_SIZE_WORDS];
u32 remaining_size;
union {
struct {
u32 dkey1[SEP_AES_BLOCK_SIZE_WORDS];
u32 dkey2[SEP_AES_BLOCK_SIZE_WORDS];
u32 dkey3[SEP_AES_BLOCK_SIZE_WORDS];
} cmac_data;
struct {
u32 xts_key[SEP_AES_MAX_KEY_SIZE_WORDS / 2];
u32 temp1[SEP_AES_BLOCK_SIZE_WORDS];
u32 temp2[SEP_AES_BLOCK_SIZE_WORDS];
} xtx_data;
} s_data;
u8 dummy_block[SEP_AES_DUMMY_BLOCK_SIZE];
};
struct sep_aes_private_context {
u32 valid_tag;
u32 aes_iv;
u32 op_mode;
u8 cbuff[sizeof(struct sep_aes_internal_context)];
};
struct sep_hash_internal_context {
u32 hash_result[SEP_HASH_RESULT_SIZE_WORDS];
enum hash_op_mode hash_opmode;
u32 previous_data[SEP_SHA2_BLOCK_SIZE_WORDS];
u16 prev_update_bytes;
u32 total_proc_128bit[4];
u16 op_mode_block_size;
u8 dummy_aes_block[SEP_AES_DUMMY_BLOCK_SIZE];
};
struct sep_hash_private_context {
u32 valid_tag;
u32 iv;
u8 internal_context[sizeof(struct sep_hash_internal_context)];
};
union key_t {
struct sep_des_key des;
u32 aes[SEP_AES_MAX_KEY_SIZE_WORDS];
};
/* Context structures for crypto API */
/**
* Structure for this current task context
* This same structure is used for both hash
* and crypt in order to reduce duplicate code
* for stuff that is done for both hash operations
* and crypto operations. We cannot trust that the
* system context is not pulled out from under
* us during operation to operation, so all
* critical stuff such as data pointers must
* be in in a context that is exclusive for this
* particular task at hand.
*/
struct this_task_ctx {
struct sep_device *sep_used;
u32 done;
unsigned char iv[100];
enum des_enc_mode des_encmode;
enum des_op_mode des_opmode;
enum aes_enc_mode aes_encmode;
enum aes_op_mode aes_opmode;
u32 init_opcode;
u32 block_opcode;
size_t data_length;
size_t ivlen;
struct ablkcipher_walk walk;
int i_own_sep; /* Do I have custody of the sep? */
struct sep_call_status call_status;
struct build_dcb_struct_kernel dcb_input_data;
struct sep_dma_context *dma_ctx;
void *dmatables_region;
size_t nbytes;
struct sep_dcblock *dcb_region;
struct sep_queue_info *queue_elem;
int msg_len_words;
unsigned char msg[SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES];
void *msgptr;
struct scatterlist *src_sg;
struct scatterlist *dst_sg;
struct scatterlist *src_sg_hold;
struct scatterlist *dst_sg_hold;
struct ahash_request *current_hash_req;
struct ablkcipher_request *current_cypher_req;
enum type_of_request current_request;
int digest_size_words;
int digest_size_bytes;
int block_size_words;
int block_size_bytes;
enum hash_op_mode hash_opmode;
enum hash_stage current_hash_stage;
/**
* Not that this is a pointer. The are_we_done_yet variable is
* allocated by the task function. This way, even if the kernel
* crypto infrastructure has grabbed the task structure out from
* under us, the task function can still see this variable.
*/
int *are_we_done_yet;
unsigned long end_time;
};
struct sep_system_ctx {
union key_t key;
size_t keylen;
int key_sent;
enum des_numkey des_nbr_keys;
enum aes_keysize aes_key_size;
unsigned long end_time;
struct sep_des_private_context des_private_ctx;
struct sep_aes_private_context aes_private_ctx;
struct sep_hash_private_context hash_private_ctx;
};
/* work queue structures */
struct sep_work_struct {
struct work_struct work;
void (*callback)(void *);
void *data;
};
/* Functions */
int sep_crypto_setup(void);
void sep_crypto_takedown(void);