diff options
Diffstat (limited to 'drivers/crypto/ux500/hash/hash_alg.h')
-rwxr-xr-x | drivers/crypto/ux500/hash/hash_alg.h | 476 |
1 files changed, 476 insertions, 0 deletions
diff --git a/drivers/crypto/ux500/hash/hash_alg.h b/drivers/crypto/ux500/hash/hash_alg.h new file mode 100755 index 00000000000..e1f7c2eb60b --- /dev/null +++ b/drivers/crypto/ux500/hash/hash_alg.h @@ -0,0 +1,476 @@ +#ifndef _HASH_ALG_H +#define _HASH_ALG_H +/* + * Copyright (C) 2010 ST-Ericsson. + * Copyright (C) 2010 STMicroelectronics. + * + * 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. + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include <mach/hcl_defs.h> + +/* Number of bytes the message digest */ +#define HASH_MSG_DIGEST_SIZE 32 +#define HASH_BLOCK_SIZE 64 + +#define __HASH_ENHANCED + +/* Version defines */ +#define HASH_HCL_VERSION_ID 1 +#define HASH_HCL_MAJOR_ID 2 +#define HASH_HCL_MINOR_ID 1 + +#define MAX_HASH_DEVICE 2 + +/* Maximum value of the length's high word */ +#define HASH_HIGH_WORD_MAX_VAL 0xFFFFFFFFUL + +/* Power on Reset values HASH registers */ +#define HASH_RESET_CONTROL_REG_VALUE 0x0 +#define HASH_RESET_START_REG_VALUE 0x0 + +/* Number of context swap registers */ +#define HASH_CSR_COUNT 52 + +#define HASH_RESET_CSRX_REG_VALUE 0x0 +#define HASH_RESET_CSFULL_REG_VALUE 0x0 +#define HASH_RESET_CSDATAIN_REG_VALUE 0x0 + +#define HASH_RESET_INDEX_VAL 0x0 +#define HASH_RESET_BIT_INDEX_VAL 0x0 +#define HASH_RESET_BUFFER_VAL 0x0 +#define HASH_RESET_LEN_HIGH_VAL 0x0 +#define HASH_RESET_LEN_LOW_VAL 0x0 + +/* Control register bitfields */ +#define HASH_CR_RESUME_MASK 0x11FCF + +#define HASH_CR_SWITCHON_POS 31 +#define HASH_CR_SWITCHON_MASK MASK_BIT31 + +#define HASH_CR_EMPTYMSG_POS 20 +#define HASH_CR_EMPTYMSG_MASK MASK_BIT20 + +#define HASH_CR_DINF_POS 12 +#define HASH_CR_DINF_MASK MASK_BIT12 + +#define HASH_CR_NBW_POS 8 +#define HASH_CR_NBW_MASK 0x00000F00UL + +#define HASH_CR_LKEY_POS 16 +#define HASH_CR_LKEY_MASK MASK_BIT16 + +#define HASH_CR_ALGO_POS 7 +#define HASH_CR_ALGO_MASK MASK_BIT7 + +#define HASH_CR_MODE_POS 6 +#define HASH_CR_MODE_MASK MASK_BIT6 + +#define HASH_CR_DATAFORM_POS 4 +#define HASH_CR_DATAFORM_MASK (MASK_BIT4 | MASK_BIT5) + +#define HASH_CR_DMAE_POS 3 +#define HASH_CR_DMAE_MASK MASK_BIT3 + +#define HASH_CR_INIT_POS 2 +#define HASH_CR_INIT_MASK MASK_BIT2 + +#define HASH_CR_PRIVN_POS 1 +#define HASH_CR_PRIVN_MASK MASK_BIT1 + +#define HASH_CR_SECN_POS 0 +#define HASH_CR_SECN_MASK MASK_BIT0 + +/* Start register bitfields */ +#define HASH_STR_DCAL_POS 8 +#define HASH_STR_DCAL_MASK MASK_BIT8 + +#define HASH_STR_NBLW_POS 0 +#define HASH_STR_NBLW_MASK 0x0000001FUL + +#define HASH_NBLW_MAX_VAL 0x1F + +/* PrimeCell IDs */ +#define HASH_P_ID0 0xE0 +#define HASH_P_ID1 0x05 +#define HASH_P_ID2 0x38 +#define HASH_P_ID3 0x00 +#define HASH_CELL_ID0 0x0D +#define HASH_CELL_ID1 0xF0 +#define HASH_CELL_ID2 0x05 +#define HASH_CELL_ID3 0xB1 + +#define HASH_SET_DIN(val) HCL_WRITE_REG(g_sys_ctx.registry[hid]->din, (val)) + +#define HASH_INITIALIZE \ + HCL_WRITE_BITS( \ + g_sys_ctx.registry[hid]->cr, \ + 0x01 << HASH_CR_INIT_POS, \ + HASH_CR_INIT_MASK) + +#define HASH_SET_DATA_FORMAT(data_format) \ + HCL_WRITE_BITS( \ + g_sys_ctx.registry[hid]->cr, \ + (u32) (data_format) << HASH_CR_DATAFORM_POS, \ + HASH_CR_DATAFORM_MASK) + +#define HASH_GET_HX(pos) \ + HCL_READ_REG(g_sys_ctx.registry[hid]->hx[pos]) + +#define HASH_SET_HX(pos, val) \ + HCL_WRITE_REG(g_sys_ctx.registry[hid]->hx[pos], (val)); + +#define HASH_SET_NBLW(val) \ + HCL_WRITE_BITS( \ + g_sys_ctx.registry[hid]->str, \ + (u32) (val) << HASH_STR_NBLW_POS, \ + HASH_STR_NBLW_MASK) + +#define HASH_SET_DCAL \ + HCL_WRITE_BITS( \ + g_sys_ctx.registry[hid]->str, \ + 0x01 << HASH_STR_DCAL_POS, \ + HASH_STR_DCAL_MASK) + +/** + * struct uint64 - Structure to handle 64 bits integers. + * @high_word: Most significant bits + * @high_word: Least significant bits + * + * Used to handle 64 bits integers. + */ +struct uint64 { + u32 high_word; + u32 low_word; +}; + +/** + * struct hash_register - Contains all registers in u8500 hash hardware. + * @cr: HASH control register (0x000) + * @din: HASH data input register (0x004) + * @str: HASH start register (0x008) + * @hx: HASH digest register 0..7 (0x00c-0x01C) + * @padding0: Reserved (0x02C) + * @itcr: Integration test control register (0x080) + * @itip: Integration test input register (0x084) + * @itop: Integration test output register (0x088) + * @padding1: Reserved (0x08C) + * @csfull: HASH context full register (0x0F8) + * @csdatain: HASH context swap data input register (0x0FC) + * @csrx: HASH context swap register 0..51 (0x100-0x1CC) + * @padding2: Reserved (0x1D0) + * @periphid0: HASH peripheral identification register 0 (0xFE0) + * @periphid1: HASH peripheral identification register 1 (0xFE4) + * @periphid2: HASH peripheral identification register 2 (0xFE8) + * @periphid3: HASH peripheral identification register 3 (0xFEC) + * @cellid0: HASH PCell identification register 0 (0xFF0) + * @cellid1: HASH PCell identification register 1 (0xFF4) + * @cellid2: HASH PCell identification register 2 (0xFF8) + * @cellid3: HASH PCell identification register 3 (0xFFC) + * + * The device communicates to the HASH via 32-bit-wide control registers + * accessible via the 32-bit width AMBA rev. 2.0 AHB Bus. Below is a structure + * with the registers used. + */ +struct hash_register { + u32 cr; + u32 din; + u32 str; + u32 hx[8]; + + u32 padding0[(0x080 - 0x02C) >> 2]; + + u32 itcr; + u32 itip; + u32 itop; + + u32 padding1[(0x0F8 - 0x08C) >> 2]; + + u32 csfull; + u32 csdatain; + u32 csrx[HASH_CSR_COUNT]; + + u32 padding2[(0xFE0 - 0x1D0) >> 2]; + + u32 periphid0; + u32 periphid1; + u32 periphid2; + u32 periphid3; + + u32 cellid0; + u32 cellid1; + u32 cellid2; + u32 cellid3; +}; + +/** + * struct hash_state - Hash context state. + * @temp_cr: Temporary HASH Control Register + * @str_reg: HASH Start Register + * @din_reg: HASH Data Input Register + * @csr[52]: HASH Context Swap Registers 0-39 + * @csfull: HASH Context Swap Registers 40 ie Status flags + * @csdatain: HASH Context Swap Registers 41 ie Input data + * @buffer: Working buffer for messages going to the hardware + * @length: Length of the part of the message hashed so far (floor(N/64) * 64) + * @index: Valid number of bytes in buffer (N % 64) + * @bit_index: Valid number of bits in buffer (N % 8) + * + * This structure is used between context switches, i.e. when ongoing jobs are + * interupted with new jobs. When this happens we need to store intermediate + * results in software. + * + * WARNING: "index" is the member of the structure, to be sure that "buffer" + * is aligned on a 4-bytes boundary. This is highly implementation dependent + * and MUST be checked whenever this code is ported on new platforms. + */ +struct hash_state { + u32 temp_cr; + u32 str_reg; + u32 din_reg; + u32 csr[52]; + u32 csfull; + u32 csdatain; + u32 buffer[HASH_BLOCK_SIZE / sizeof(u32)]; + struct uint64 length; + u8 index; + u8 bit_index; +}; + +/** + * struct hash_system_context - Structure for the global system context. + * @registry: Pointer to the registry of the hash hardware + * @state: State of the hash device + */ +struct hash_system_context { + /* Pointer to HASH registers structure */ + volatile struct hash_register *registry[MAX_HASH_DEVICE]; + + /* State of HASH device */ + struct hash_state state[MAX_HASH_DEVICE]; +}; + +/** + * enum hash_device_id - HASH device ID. + * @HASH_DEVICE_ID_0: Hash hardware with ID 0 + * @HASH_DEVICE_ID_1: Hash hardware with ID 1 + */ +enum hash_device_id { + HASH_DEVICE_ID_0 = 0, + HASH_DEVICE_ID_1 = 1 +}; + +/** + * enum hash_data_format - HASH data format. + * @HASH_DATA_32_BITS: 32 bits data format + * @HASH_DATA_16_BITS: 16 bits data format + * @HASH_DATA_8_BITS: 8 bits data format + * @HASH_DATA_1_BITS: 1 bit data format + */ +enum hash_data_format { + HASH_DATA_32_BITS = 0x0, + HASH_DATA_16_BITS = 0x1, + HASH_DATA_8_BITS = 0x2, + HASH_DATA_1_BIT = 0x3 +}; + +/** + * enum hash_device_state - Device state + * @DISABLE: Disable the hash hardware + * @ENABLE: Enable the hash hardware + */ +enum hash_device_state { + DISABLE = 0, + ENABLE = 1 +}; + +/** + * struct hash_protection_config - Device protection configuration. + * @privilege_access: FIXME, add comment. + * @secure_access: FIXME, add comment. + */ +struct hash_protection_config { + int privilege_access; + int secure_access; +}; + +/** + * enum hash_input_status - Data Input flag status. + * @HASH_DIN_EMPTY: Indicates that nothing is in data registers + * @HASH_DIN_FULL: Indicates that data registers are full + */ +enum hash_input_status { + HASH_DIN_EMPTY = 0, + HASH_DIN_FULL = 1 +}; + +/** + * Number of words already pushed + */ +enum hash_nbw_pushed { + HASH_NBW_00 = 0x00, + HASH_NBW_01 = 0x01, + HASH_NBW_02 = 0x02, + HASH_NBW_03 = 0x03, + HASH_NBW_04 = 0x04, + HASH_NBW_05 = 0x05, + HASH_NBW_06 = 0x06, + HASH_NBW_07 = 0x07, + HASH_NBW_08 = 0x08, + HASH_NBW_09 = 0x09, + HASH_NBW_10 = 0x0A, + HASH_NBW_11 = 0x0B, + HASH_NBW_12 = 0x0C, + HASH_NBW_13 = 0x0D, + HASH_NBW_14 = 0x0E, + HASH_NBW_15 = 0x0F +}; + +/** + * struct hash_device_status - Device status for DINF, NBW, and NBLW bit + * fields. + * @dinf_status: HASH data in full flag + * @nbw_status: Number of words already pushed + * @nblw_status: Number of Valid Bits Last Word of the Message + */ +struct hash_device_status { + int dinf_status; + int nbw_status; + u8 nblw_status; +}; + +/** + * enum hash_dma_request - Enumeration for HASH DMA request types. + */ +enum hash_dma_request { + HASH_DISABLE_DMA_REQ = 0x0, + HASH_ENABLE_DMA_REQ = 0x1 +}; + +/** + * enum hash_digest_cal - Enumeration for digest calculation. + * @HASH_DISABLE_DCAL: Indicates that DCAL bit is not set/used. + * @HASH_ENABLE_DCAL: Indicates that DCAL bit is set/used. + */ +enum hash_digest_cal { + HASH_DISABLE_DCAL = 0x0, + HASH_ENABLE_DCAL = 0x1 +}; + +/** + * enum hash_algo - Enumeration for selecting between SHA1 or SHA2 algorithm + * @HASH_ALGO_SHA1: Indicates that SHA1 is used. + * @HASH_ALGO_SHA2: Indicates that SHA2 (SHA256) is used. + */ +enum hash_algo { + HASH_ALGO_SHA1 = 0x0, + HASH_ALGO_SHA2 = 0x1 +}; + +/** + * enum hash_op - Enumeration for selecting between HASH or HMAC mode + * @HASH_OPER_MODE_HASH: Indicates usage of normal HASH mode + * @HASH_OPER_MODE_HMAC: Indicates usage of HMAC + */ +enum hash_op { + HASH_OPER_MODE_HASH = 0x0, + HASH_OPER_MODE_HMAC = 0x1 +}; + +/** + * enum hash_key_type - Enumeration for selecting between long and short key. + * @HASH_SHORT_KEY: Key used is shorter or equal to block size (64 bytes) + * @HASH_LONG_KEY: Key used is greater than block size (64 bytes) + */ +enum hash_key_type { + HASH_SHORT_KEY = 0x0, + HASH_LONG_KEY = 0x1 +}; + +/** + * struct hash_config - Configuration data for the hardware + * @data_format: Format of data entered into the hash data in register + * @algorithm: Algorithm selection bit + * @oper_mode: Operating mode selection bit + * @hmac_key: Long key selection bit HMAC mode + */ +struct hash_config { + int data_format; + int algorithm; + int oper_mode; + int hmac_key; +}; + + +/** + * enum hash_error - Error codes for hash. + */ +enum hash_error { + HASH_OK = 0, + HASH_MSG_LENGTH_OVERFLOW, + HASH_INTERNAL_ERROR, + HASH_NOT_CONFIGURED, + HASH_REQUEST_PENDING, + HASH_REQUEST_NOT_APPLICABLE, + HASH_INVALID_PARAMETER, + HASH_UNSUPPORTED_FEATURE, + HASH_UNSUPPORTED_HW +}; + +int hash_init_base_address(int hash_device_id, t_logical_address base_address); + +int HASH_GetVersion(t_version *p_version); + +int HASH_Reset(int hash_devive_id); + +int HASH_ConfigureDmaRequest(int hash_device_id, int request_state); + +int HASH_ConfigureLastValidBits(int hash_device_id, u8 nblw_val); + +int HASH_ConfigureDigestCal(int hash_device_id, int dcal_state); + +int HASH_ConfigureProtection(int hash_device_id, + struct hash_protection_config + *p_protect_config); + +int hash_setconfiguration(int hash_device_id, struct hash_config *p_config); + +int hash_begin(int hash_device_id); + +int hash_get_digest(int hash_device_id, u8 digest[HASH_MSG_DIGEST_SIZE]); + +int HASH_ClockGatingOff(int hash_device_id); + +struct hash_device_status HASH_GetDeviceStatus(int hash_device_id); + +t_bool HASH_IsDcalOngoing(int hash_device_id); + +int hash_hw_update(int hash_device_id, + const u8 *p_data_buffer, + u32 msg_length); + +int hash_end(int hash_device_id, u8 digest[HASH_MSG_DIGEST_SIZE]); + +int hash_compute(int hash_device_id, + const u8 *p_data_buffer, + u32 msg_length, + struct hash_config *p_hash_config, + u8 digest[HASH_MSG_DIGEST_SIZE]); + +int hash_end_key(int hash_device_id); + +int hash_save_state(int hash_device_id, struct hash_state *state); + +int hash_resume_state(int hash_device_id, const struct hash_state *state); + +#ifdef __cplusplus +} +#endif +#endif + |