summaryrefslogtreecommitdiff
path: root/drivers/crypto/ux500/hash/hash_alg.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/crypto/ux500/hash/hash_alg.h')
-rwxr-xr-xdrivers/crypto/ux500/hash/hash_alg.h476
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
+