Defines | |
#define | SCM_ACCESS_ERRORS |
Functions | |
static int | scc_init (void) |
static void | scc_cleanup (void) |
scc_config_t * | scc_get_configuration (void) |
scc_return_t | scc_zeroize_memories (void) |
scc_return_t | scc_crypt (unsigned long count_in_bytes, const uint8_t *data_in, const uint8_t *init_vector, scc_enc_dec_t direction, scc_crypto_mode_t crypto_mode, scc_verify_t check_mode, uint8_t *data_out, unsigned long *count_out_bytes) |
void | scc_set_sw_alarm (void) |
scc_return_t | scc_monitor_security_failure (void callback_func(void)) |
void | scc_stop_monitoring_security_failure (void callback_func(void)) |
scc_return_t | scc_read_register (int register_offset, uint32_t *value) |
scc_return_t | scc_write_register (int register_offset, uint32_t value) |
OS_DEV_ISR (scc_irq) | |
static void | scc_perform_callbacks (void) |
static uint32_t | copy_to_scc (const uint8_t *from, uint32_t to, unsigned long count_bytes, uint16_t *crc) |
static uint32_t | copy_from_scc (const uint32_t from, uint8_t *to, unsigned long count_bytes, uint16_t *crc) |
static scc_return_t | scc_strip_padding (uint8_t *from, unsigned *count_bytes_stripped) |
static uint32_t | scc_update_state (void) |
static void | scc_init_ccitt_crc (void) |
static uint32_t | scc_grab_config_values (void) |
static int | setup_interrupt_handling (void) |
static uint32_t | scc_do_crypto (int byte_count, uint32_t scm_control) |
static scc_return_t | scc_encrypt (uint32_t count_in_bytes, const uint8_t *data_in, uint32_t scm_control, uint8_t *data_out, int add_crc, unsigned long *count_out_bytes) |
static scc_return_t | scc_decrypt (uint32_t count_in_bytes, const uint8_t *data_in, uint32_t scm_control, uint8_t *data_out, int verify_crc, unsigned long *count_out_bytes) |
scc_return_t | scc_alloc_slot (uint32_t value_size_bytes, uint64_t owner_id, uint32_t *slot) |
scc_return_t | scc_verify_slot_access (uint64_t owner_id, uint32_t slot, uint32_t access_len) |
scc_return_t | scc_dealloc_slot (uint64_t owner_id, uint32_t slot) |
scc_return_t | scc_load_slot (uint64_t owner_id, uint32_t slot, const uint8_t *key_data, uint32_t key_length) |
scc_return_t | scc_read_slot (uint64_t owner_id, uint32_t slot, uint32_t key_length, uint8_t *key_data) |
scc_return_t | scc_encrypt_slot (uint64_t owner_id, uint32_t slot, uint32_t length, uint8_t *black_data) |
scc_return_t | scc_decrypt_slot (uint64_t owner_id, uint32_t slot, uint32_t length, const uint8_t *black_data) |
scc_return_t | scc_get_slot_info (uint64_t owner_id, uint32_t slot, uint32_t *address, uint32_t *value_size_bytes, uint32_t *slot_size_bytes) |
static void | scc_wait_completion (void) |
static int | is_cipher_done (void) |
static int | offset_within_smn (uint32_t register_offset) |
static int | offset_within_scm (uint32_t register_offset) |
static scc_return_t | check_register_accessible (uint32_t register_offset, uint32_t smn_status, uint32_t scm_status) |
static scc_return_t | check_register_offset (uint32_t register_offset) |
Variables | |
static volatile void * | scc_base |
static void(* | scc_callbacks [SCC_CALLBACK_SIZE])(void) |
static scc_config_t | scc_configuration |
static struct scc_key_slot | scc_key_info [SCC_KEY_SLOTS] |
static enum scc_status | scc_availability = SCC_STATUS_INITIAL |
static int | smn_irq_set = 0 |
static int | scm_irq_set = 0 |
static spinlock_t | scc_callbacks_lock = SPIN_LOCK_UNLOCKED |
static spinlock_t | scc_crypto_lock = SPIN_LOCK_UNLOCKED |
static uint32_t | scc_memory_size_bytes |
static uint32_t | scm_highest_memory_address |
static uint16_t | scc_crc_lookup_table [256] |
static uint8_t | scc_block_padding [8] |
This is the driver code for the Security Controller (SCC). It has no device driver interface, so no user programs may access it. Its interaction with the Linux kernel is from calls to scc_init() when the driver is loaded, and scc_cleanup() should the driver be unloaded. The driver uses locking and (task-sleep/task-wakeup) functions of the kernel. It also registers itself to handle the interrupt line(s) from the SCC.
Other drivers in the kernel may use the remaining API functions to get at the services of the SCC. The main service provided is the Secure Memory, which allows encoding and decoding of secrets with a per-chip secret key.
The SCC is single-threaded, and so is this module. When the scc_crypt() routine is called, it will lock out other accesses to the function. If another task is already in the module, the subsequent caller will spin on a lock waiting for the other access to finish.
Note that long crypto operations could cause a task to spin for a while, preventing other kernel work (other than interrupt processing) to get done.
The external (kernel module) interface is through the following functions:
All other functions are internal to the driver.
#define SCM_ACCESS_ERRORS |
(SCM_ERR_USER_ACCESS | SCM_ERR_ILLEGAL_ADDRESS | \ SCM_ERR_ILLEGAL_MASTER | SCM_ERR_CACHEABLE_ACCESS | \ SCM_ERR_UNALIGNED_ACCESS | SCM_ERR_BYTE_ACCESS | \ SCM_ERR_INTERNAL_ERROR | SCM_ERR_SMN_BLOCKING_ACCESS | \ SCM_ERR_CIPHERING | SCM_ERR_ZEROIZING | SCM_ERR_BUSY)
This is the set of errors which signal that access to the SCM RAM has failed or will fail.
Referenced by copy_from_scc(), and copy_to_scc().
static scc_return_t check_register_accessible | ( | uint32_t | register_offset, | |
uint32_t | smn_status, | |||
uint32_t | scm_status | |||
) | [static] |
Given the current SCM and SMN status, verify that access to the requested register should be OK.
[in] | register_offset | register offset within SCC |
[in] | smn_status | recent value from SMN_STATUS |
[in] | scm_status | recent value from SCM_STATUS |
References offset_within_scm(), offset_within_smn(), SCM_CONFIGURATION, SCM_ERROR_STATUS, SCM_INTERRUPT_CTRL, SCM_STATUS, SCM_STATUS_BUSY, SMN_COMMAND, SMN_DEBUG_DETECT_STAT, SMN_STATE_FAIL, SMN_STATUS, and SMN_STATUS_STATE_MASK.
Referenced by scc_read_register(), and scc_write_register().
static scc_return_t check_register_offset | ( | uint32_t | register_offset | ) | [static] |
Check that the offset is with the bounds of the SCC register set.
[in] | register_offset | register offset of SMN. |
SCC_RET_OK if ok, SCC_RET_FAIL if not
References offset_within_scm(), offset_within_smn(), and SCC_BYTE_OFFSET.
Referenced by scc_read_register(), and scc_write_register().
static uint32_t copy_from_scc | ( | const uint32_t | from, | |
uint8_t * | to, | |||
unsigned long | count_bytes, | |||
uint16_t * | crc | |||
) | [static] |
Move data from aligned 32-bit source and place in (possibly unaligned) target, and maybe calculate CRC at the same time.
Multiple calls can be made to this routine (without intervening calls to copy_to_scc(), as long as the sum total of bytes copied is be a multiple of four.
[in] | from | Location in SCC |
[out] | to | Location in memory |
[in] | count_bytes | Number of bytes to copy |
[in,out] | crc | Pointer to CRC. Initial value must be CRC_CCITT_START if this is the start of message. Output is the resulting (maybe partial) CRC. If NULL, crc is not calculated. |
References CALC_CRC, SCC_BYTE_OFFSET, SCC_READ_REGISTER, SCC_WORD_PTR, SCC_WRITE_REGISTER, SCM_ACCESS_ERRORS, and SCM_ERROR_STATUS.
Referenced by scc_decrypt(), scc_encrypt(), scc_encrypt_slot(), and scc_read_slot().
static uint32_t copy_to_scc | ( | const uint8_t * | from, | |
uint32_t | to, | |||
unsigned long | count_bytes, | |||
uint16_t * | crc | |||
) | [static] |
Move data from possibly unaligned source and realign for SCC, possibly while calculating CRC.
Multiple calls can be made to this routine (without intervening calls to copy_from_scc(), as long as the sum total of bytes copied is a multiple of four (SCC native word size).
[in] | from | Location in memory |
[out] | to | Location in SCC |
[in] | count_bytes | Number of bytes to copy |
[in,out] | crc | Pointer to CRC. Initial value must be CRC_CCITT_START if this is the start of message. Output is the resulting (maybe partial) CRC. If NULL, no crc is calculated. |
References CALC_CRC, SCC_BYTE_OFFSET, SCC_READ_REGISTER, SCC_WORD_PTR, SCC_WRITE_REGISTER, SCM_ACCESS_ERRORS, and SCM_ERROR_STATUS.
Referenced by scc_crypt(), scc_decrypt(), scc_decrypt_slot(), scc_encrypt(), and scc_load_slot().
static int is_cipher_done | ( | void | ) | [static] |
This function returns non-zero if SCM Status register indicates that a cipher has terminated or some other interrupt-generating condition has occurred.
References SCC_READ_REGISTER, SCM_STATUS, SCM_STATUS_CIPHERING, and SCM_STATUS_ZEROIZING.
Referenced by scc_wait_completion().
static int offset_within_scm | ( | uint32_t | register_offset | ) | [inline, static] |
Check that the offset is with the bounds of the SCM register set.
[in] | register_offset | Register offset of SCM |
References scm_highest_memory_address, and SCM_RED_START.
Referenced by check_register_accessible(), and check_register_offset().
static int offset_within_smn | ( | uint32_t | register_offset | ) | [inline, static] |
Check that the offset is with the bounds of the SMN register set.
[in] | register_offset | register offset of SMN. |
References SMN_STATUS, and SMN_TIMER.
Referenced by check_register_accessible(), and check_register_offset().
OS_DEV_ISR | ( | scc_irq | ) |
This is the interrupt handler for the SCC.
This function checks the SMN Status register to see whether it generated the interrupt, then it checks the SCM Status register to see whether it needs attention.
If an SMN Interrupt is active, then the SCC state set to failure, and scc_perform_callbacks() is invoked to notify any interested parties.
The SCM Interrupt should be masked, as this driver uses polling to determine when the SCM has completed a crypto or zeroing operation. Therefore, if the interrupt is active, the driver will just clear the interrupt and (re)mask.
scc_return_t scc_alloc_slot | ( | uint32_t | value_size_bytes, | |
uint64_t | owner_id, | |||
uint32_t * | slot | |||
) |
Allocate a key slot to fit the requested size.
value_size_bytes | Size of the key or other secure data | |
owner_id | Value to tie owner to slot | |
[out] | slot | Handle to access or deallocate slot |
References scc_key_slot::length, scc_key_slot::owner_id, scc_availability, scc_crypto_lock, scc_key_info, SCC_KEY_SLOTS, SCC_STATUS_OK, and scc_key_slot::status.
static void scc_cleanup | ( | void | ) | [static] |
Perform cleanup before driver/module is unloaded by setting the machine state close to what it was when the driver was loaded. This function is called when the kernel is shutting down or when this driver is being unloaded.
A driver like this should probably never be unloaded, especially if there are other module relying upon the callback feature for monitoring the SCC status.
In any case, cleanup the callback table (by clearing out all of the pointers). Deregister the interrupt handler(s). Unmap SCC registers.
References os_deregister_interrupt, scc_availability, scc_base, SCC_CALLBACK_SIZE, scc_callbacks, SCC_STATUS_UNIMPLEMENTED, SCC_WRITE_REGISTER, SCM_INTERRUPT_CTRL, SCM_INTERRUPT_CTRL_MASK_INTERRUPTS, SCM_INTERRUPT_CTRL_ZEROIZE_MEMORY, scm_irq_set, SMN_COMMAND, SMN_COMMAND_CLEAR_INTERRUPT, and smn_irq_set.
Referenced by scc_init().
scc_return_t scc_crypt | ( | unsigned long | count_in_bytes, | |
const uint8_t * | data_in, | |||
const uint8_t * | init_vector, | |||
scc_enc_dec_t | direction, | |||
scc_crypto_mode_t | crypto_mode, | |||
scc_verify_t | check_mode, | |||
uint8_t * | data_out, | |||
unsigned long * | count_out_bytes | |||
) |
Perform a Triple DES encryption or decryption operation.
This routine will cause the SCM to perform an encryption or decryption with its internal key. If the SCC's SMN_STATUS register shows that the SCC is in SMN_STATE_SECURE, then the Secret Key will be used. If it is SMN_STATE_NON_SECURE (or health check), then the Default Key will be used.
This function will perform in a variety of ways, depending upon the values of direction
, crypto_mode
, and check_mode
. If SCC_VERIFY_MODE_CCITT_CRC mode is requested, upon successful completion, the count_in_bytes
will be different from the returned value of count_out_bytes
. This is because the two-byte CRC and some amount of padding (at least one byte) will either be added or stripped.
This function will not return until the SCC has performed the operation (or reported failure to do so). It must therefore not be called from interrupt level. In the current version, it will poll the SCC for completion. In future versions, it may sleep.
[in] | count_in_bytes | The number of bytes to move through the crypto function. Must be greater than zero. |
[in] | data_in | Pointer to the array of bytes to be used as input to the crypto function. |
[in] | init_vector | Pointer to the block-sized (8 byte) array of bytes which form the initialization vector for this operation. A non-null value is required when crypto_mode has the value SCC_CBC_MODE; the value is ignored in SCC_ECB_MODE. |
[in] | direction | Direct the driver to perform encryption or decryption. |
[in] | crypto_mode | Run the crypto function in ECB or CBC mode. |
[in] | check_mode | During encryption, generate and append a check value to the plaintext and pad the resulting data. During decryption, validate the plaintext with that check value and remove the padding. |
[in,out] | count_out_bytes | On input, the number of bytes available for copying to data_out . On return, the number of bytes copied to data_out . |
[out] | data_out | Pointer to the array of bytes that are where the output of the crypto function are to be placed. For encryption, this must be able to hold a longer ciphertext than the plaintext message at data_in . The driver will append a 'pad' of 1-8 bytes to the message, and if check_mode is used, additional bytes may be added, the number depending upon the type of check being requested. |
References copy_to_scc(), CRC_SIZE_BYTES, scc_availability, SCC_BLOCK_SIZE_BYTES, scc_crypto_lock, scc_decrypt(), scc_encrypt(), scc_init(), SCC_STATUS_INITIAL, SCC_STATUS_OK, scc_update_state(), SCC_WRITE_REGISTER, SCM_BLACK_START, SCM_CBC_MODE, SCM_CONTROL_START_CIPHER, SCM_INIT_VECTOR_0, and SCM_RED_START.
scc_return_t scc_dealloc_slot | ( | uint64_t | owner_id, | |
uint32_t | slot | |||
) |
Deallocate the key slot of a stored key or secret value.
owner_id | The id which owns the slot . | |
slot | The slot number for the key. |
References scc_key_slot::owner_id, scc_crypto_lock, scc_key_info, SCC_WRITE_REGISTER, SCM_BLACK_MEMORY, SCM_RED_MEMORY, and scc_key_slot::status.
static scc_return_t scc_decrypt | ( | uint32_t | count_in_bytes, | |
const uint8_t * | data_in, | |||
uint32_t | scm_control, | |||
uint8_t * | data_out, | |||
int | verify_crc, | |||
unsigned long * | count_out_bytes | |||
) | [static] |
Perform a decryption on the input. If verify_crc
is true, the last block (maybe the two last blocks) is special - it should contain a CRC and padding. These must be stripped and verified.
[in] | count_in_bytes | Count of bytes of ciphertext |
[in] | data_in | Pointer to the ciphertext |
[in] | scm_control | Bit values for the SCM_CONTROL register |
[in,out] | data_out | Pointer for storing plaintext |
[in] | verify_crc | Flag for running CRC - 0 no, else yes |
[in,out] | count_out_bytes | Number of bytes available at data_out |
References CALC_CRC, copy_from_scc(), copy_to_scc(), CRC_CCITT_START, CRC_SIZE_BYTES, SCC_BLOCK_SIZE_BYTES, scc_do_crypto(), scc_memory_size_bytes, scc_strip_padding(), SCC_WRITE_REGISTER, SCM_BLACK_MEMORY, SCM_DECRYPT_MODE, and SCM_RED_MEMORY.
Referenced by scc_crypt().
scc_return_t scc_decrypt_slot | ( | uint64_t | owner_id, | |
uint32_t | slot, | |||
uint32_t | length, | |||
const uint8_t * | black_data | |||
) |
Decrypt some black data and leave result in the slot.
owner_id | Value of owner of slot | |
slot | Handle of slot | |
length | Length, in bytes, of black_data | |
black_data | Location of data to dencrypt and store in slot |
References copy_to_scc(), scc_key_slot::offset, SCC_BLOCK_SIZE_BYTES, scc_crypto_lock, scc_do_crypto(), scc_key_info, SCC_WRITE_REGISTER, SCM_BLACK_MEMORY, SCM_BLACK_START, SCM_CBC_MODE, SCM_CONTROL_START_CIPHER, SCM_DECRYPT_MODE, SCM_INIT_VECTOR_0, SCM_INIT_VECTOR_1, and SCM_RED_START.
static uint32_t scc_do_crypto | ( | int | byte_count, | |
uint32_t | scm_control | |||
) | [static] |
Have the SCM perform the crypto function.
Set up length register, and the store scm_control
into control register to kick off the operation. Wait for completion, gather status, clear interrupt / status.
byte_count | number of bytes to perform in this operation | |
scm_control | Bit values to be set in SCM_CONTROL register |
References SCC_BLOCK_SIZE_BYTES, SCC_READ_REGISTER, scc_wait_completion(), SCC_WRITE_REGISTER, SCM_CONTROL, SCM_ERR_INTERNAL_ERROR, SCM_ERROR_STATUS, SCM_INTERRUPT_CTRL, SCM_INTERRUPT_CTRL_CLEAR_INTERRUPT, SCM_INTERRUPT_CTRL_MASK_INTERRUPTS, SCM_LENGTH, SCM_STATUS, SCM_STATUS_CIPHERING_DONE, SCM_STATUS_INTERNAL_ERROR, and SCM_STATUS_LENGTH_ERROR.
Referenced by scc_decrypt(), scc_decrypt_slot(), scc_encrypt(), and scc_encrypt_slot().
static scc_return_t scc_encrypt | ( | uint32_t | count_in_bytes, | |
const uint8_t * | data_in, | |||
uint32_t | scm_control, | |||
uint8_t * | data_out, | |||
int | add_crc, | |||
unsigned long * | count_out_bytes | |||
) | [static] |
Perform an encryption on the input. If verify_crc
is true, a CRC must be calculated on the plaintext, and appended, with padding, before computing the ciphertext.
[in] | count_in_bytes | Count of bytes of plaintext |
[in] | data_in | Pointer to the plaintext |
[in] | scm_control | Bit values for the SCM_CONTROL register |
[in,out] | data_out | Pointer for storing ciphertext |
[in] | add_crc | Flag for computing CRC - 0 no, else yes |
[in,out] | count_out_bytes | Number of bytes available at data_out |
References copy_from_scc(), copy_to_scc(), CRC_CCITT_START, CRC_SIZE_BYTES, PADDING_BUFFER_MAX_BYTES, scc_block_padding, SCC_BLOCK_SIZE_BYTES, scc_do_crypto(), scc_memory_size_bytes, SCC_READ_REGISTER, SCC_WRITE_REGISTER, SCM_BLACK_MEMORY, SCM_BLACK_START, SCM_RED_MEMORY, and SCM_RED_START.
Referenced by scc_crypt().
scc_return_t scc_encrypt_slot | ( | uint64_t | owner_id, | |
uint32_t | slot, | |||
uint32_t | length, | |||
uint8_t * | black_data | |||
) |
Encrypt the key data stored in a slot.
owner_id | Value of owner of slot | |
slot | Handle of slot | |
length | Length, in bytes, of black_data | |
black_data | Location to store result of encrypting RED data in slot |
References copy_from_scc(), scc_key_slot::offset, SCC_BLOCK_SIZE_BYTES, scc_crypto_lock, scc_do_crypto(), scc_key_info, SCC_WRITE_REGISTER, SCM_BLACK_MEMORY, SCM_BLACK_START, SCM_CBC_MODE, SCM_CONTROL_START_CIPHER, SCM_INIT_VECTOR_0, SCM_INIT_VECTOR_1, and SCM_RED_START.
scc_config_t* scc_get_configuration | ( | void | ) |
Retrieve configuration information from the SCC.
This function always succeeds.
References scc_availability, scc_init(), and SCC_STATUS_INITIAL.
Referenced by fsl_shw_smalloc(), OS_DEV_INIT(), and OS_DEV_MMAP().
scc_return_t scc_get_slot_info | ( | uint64_t | owner_id, | |
uint32_t | slot, | |||
uint32_t * | address, | |||
uint32_t * | value_size_bytes, | |||
uint32_t * | slot_size_bytes | |||
) |
Determine address and value length for a give slot.
owner_id | Value of owner of slot | |
slot | Handle of slot | |
address | Location to store kernel address of slot data | |
value_size_bytes | Location to store allocated length of data in slot. May be NULL if value is not needed by caller. | |
slot_size_bytes | Location to store max length data in slot May be NULL if value is not needed by caller. |
References scc_key_slot::length, scc_key_slot::offset, scc_key_info, and SCM_RED_MEMORY.
static uint32_t scc_grab_config_values | ( | void | ) | [static] |
grab_config_values() will read the SCM Configuration and SMN Status registers and store away version and size information for later use.
References scc_config_t::black_ram_size_blocks, scc_config_t::block_size_bytes, scc_config_t::red_ram_size_blocks, scc_availability, SCC_BLOCK_SIZE_BYTES, scc_memory_size_bytes, SCC_READ_REGISTER, SCC_STATUS_UNIMPLEMENTED, scc_update_state(), SCM_BLACK_MEMORY, SCM_CFG_BLACK_SIZE_MASK, SCM_CFG_BLACK_SIZE_SHIFT, SCM_CFG_BLOCK_SIZE_MASK, SCM_CFG_BLOCK_SIZE_SHIFT, SCM_CFG_RED_SIZE_MASK, SCM_CFG_RED_SIZE_SHIFT, SCM_CFG_VERSION_ID_MASK, SCM_CFG_VERSION_ID_SHIFT, SCM_CONFIGURATION, scm_highest_memory_address, scc_config_t::scm_version, SCM_VERSION_1, SMN_STATE_FAIL, SMN_STATUS_VERSION_ID_MASK, SMN_STATUS_VERSION_ID_SHIFT, and scc_config_t::smn_version.
Referenced by scc_init().
static int scc_init | ( | void | ) | [static] |
Initialize the driver at boot time or module load time.
Register with the kernel as the interrupt handler for the SCC interrupt line(s).
Map the SCC's register space into the driver's memory space.
Query the SCC for its configuration and status. Save the configuration in scc_configuration and save the status in scc_availability. Called by the kernel.
Do any locking/wait queue initialization which may be necessary.
The availability fuse may be checked, depending on platform.
References scc_key_slot::offset, os_printk, scc_availability, scc_base, SCC_CALLBACK_SIZE, scc_callbacks, scc_cleanup(), scc_grab_config_values(), scc_init_ccitt_crc(), scc_key_info, SCC_KEY_SLOTS, SCC_STATUS_CHECKING, SCC_STATUS_FAILED, SCC_STATUS_INITIAL, SCC_STATUS_OK, SCC_STATUS_UNIMPLEMENTED, SCC_WRITE_REGISTER, SCM_ERROR_STATUS, SCM_INTERRUPT_CTRL, SCM_INTERRUPT_CTRL_CLEAR_INTERRUPT, SCM_INTERRUPT_CTRL_MASK_INTERRUPTS, scm_irq_set, setup_interrupt_handling(), SMN_COMMAND, SMN_COMMAND_CLEAR_INTERRUPT, SMN_COMMAND_ENABLE_INTERRUPT, smn_irq_set, and scc_key_slot::status.
Referenced by scc_crypt(), scc_get_configuration(), scc_monitor_security_failure(), scc_read_register(), scc_set_sw_alarm(), scc_stop_monitoring_security_failure(), scc_write_register(), and scc_zeroize_memories().
static void scc_init_ccitt_crc | ( | void | ) | [static] |
Populate the partial CRC lookup table.
References CRC_POLYNOMIAL, and scc_crc_lookup_table.
Referenced by scc_init().
scc_return_t scc_load_slot | ( | uint64_t | owner_id, | |
uint32_t | slot, | |||
const uint8_t * | key_data, | |||
uint32_t | key_length | |||
) |
Load a value into a slot.
owner_id | Value of owner of slot | |
slot | Handle of slot | |
key_data | Data to load into the slot | |
key_length | Length, in bytes, of key_data to copy to SCC. |
key_length
exceeds the size of the slot. References copy_to_scc(), scc_crypto_lock, scc_key_info, and SCM_RED_MEMORY.
scc_return_t scc_monitor_security_failure | ( | void | callback_funcvoid | ) |
This routine will register a function to be called should a Security Failure be signalled by the SCC (Security Monitor).
The callback function may be called from interrupt level, it may be called from some process' task. It should therefore not take a long time to perform its operation, and it may not sleep.
callback_func | Function pointer to routine which will receive notification of the security failure. |
References scc_availability, SCC_CALLBACK_SIZE, scc_callbacks, scc_callbacks_lock, scc_init(), and SCC_STATUS_INITIAL.
Referenced by OS_DEV_INIT().
static void scc_perform_callbacks | ( | void | ) | [static] |
Perform callbacks registered by scc_monitor_security_failure().
Make sure callbacks only happen once... Since there may be some reason why the interrupt isn't generated, this routine could be called from base(task) level.
One at a time, go through scc_callbacks[] and call any non-null pointers.
References SCC_CALLBACK_SIZE, scc_callbacks, and scc_callbacks_lock.
Referenced by scc_set_sw_alarm(), and scc_update_state().
scc_return_t scc_read_register | ( | int | register_offset, | |
uint32_t * | value | |||
) |
Read value from an SCC register. The offset will be checked for validity (range) as well as whether it is accessible (e.g. not busy, not in failed state) at the time of the call.
[in] | register_offset | The (byte) offset within the SCC block of the register to be queried. See SCM Registers and SMN Registers. |
[out] | value | Pointer to where value from the register should be placed. |
References check_register_accessible(), check_register_offset(), scc_availability, scc_init(), SCC_READ_REGISTER, SCC_STATUS_INITIAL, SCC_STATUS_UNIMPLEMENTED, scc_update_state(), SCM_STATUS, and SMN_BITBANK_DECREMENT.
scc_return_t scc_read_slot | ( | uint64_t | owner_id, | |
uint32_t | slot, | |||
uint32_t | key_length, | |||
uint8_t * | key_data | |||
) |
Read a value from a slot.
owner_id | Value of owner of slot | |
slot | Handle of slot | |
key_length | Length, in bytes, of key_data to copy from SCC. | |
key_data | Location to write the key |
key_length
exceeds the size of the slot. References copy_from_scc(), scc_crypto_lock, scc_key_info, and SCM_RED_MEMORY.
void scc_set_sw_alarm | ( | void | ) |
Signal a software alarm to the SCC. This will take the SCC and other PISA parts out of Secure mode and into Security Failure mode. The SCC will stay in failed mode until a reboot.
References scc_availability, scc_init(), scc_perform_callbacks(), SCC_STATUS_FAILED, SCC_STATUS_INITIAL, SCC_STATUS_OK, scc_update_state(), SCC_WRITE_REGISTER, SMN_COMMAND, and SMN_COMMAND_SET_SOFTWARE_ALARM.
void scc_stop_monitoring_security_failure | ( | void | callback_funcvoid | ) |
This routine will deregister a function previously registered with scc_monitor_security_failure().
callback_func | Function pointer to routine previously registered with scc_stop_monitoring_security_failure(). |
References scc_availability, SCC_CALLBACK_SIZE, scc_callbacks, scc_callbacks_lock, scc_init(), and SCC_STATUS_INITIAL.
Referenced by rng_cleanup().
static scc_return_t scc_strip_padding | ( | uint8_t * | from, | |
unsigned * | count_bytes_stripped | |||
) | [static] |
Remove padding from plaintext. Search backwards for SCC_DRIVER_PAD_CHAR, verifying that each byte passed over is zero (0). Maximum number of bytes to examine is 8.
[in] | from | Pointer to byte after end of message |
[out] | count_bytes_stripped | Number of padding bytes removed by this function. |
References SCC_BLOCK_SIZE_BYTES, and SCC_DRIVER_PAD_CHAR.
Referenced by scc_decrypt().
static uint32_t scc_update_state | ( | void | ) | [static] |
Make certain SCC is still running.
Side effect is to update scc_availability and, if the state goes to failed, run scc_perform_callbacks().
(If SCC_BRINGUP is defined, bring SCC to secure state if it is found to be in health check state)
References os_printk, scc_availability, scc_perform_callbacks(), SCC_READ_REGISTER, SCC_STATUS_CHECKING, SCC_STATUS_FAILED, SCC_STATUS_OK, SCC_STATUS_UNIMPLEMENTED, SCC_WRITE_REGISTER, SMN_SEQUENCE_CHECK, SMN_SEQUENCE_END, SMN_SEQUENCE_START, SMN_STATE_FAIL, SMN_STATE_HEALTH_CHECK, SMN_STATE_NON_SECURE, SMN_STATE_SECURE, SMN_STATUS, and SMN_STATUS_STATE_MASK.
Referenced by OS_DEV_ISR(), scc_crypt(), scc_grab_config_values(), scc_read_register(), scc_set_sw_alarm(), and scc_write_register().
scc_return_t scc_verify_slot_access | ( | uint64_t | owner_id, | |
uint32_t | slot, | |||
uint32_t | access_len | |||
) |
Determine if the given credentials match that of the key slot.
[in] | owner_id | A value which will control access to the slot. |
[in] | slot | Key Slot to query |
[in] | access_len | Length of the key |
static void scc_wait_completion | ( | void | ) | [static] |
Poll looking for end-of-cipher indication. Only used if SCC_SCM_SLEEP
is not defined.
References is_cipher_done(), and SCC_CIPHER_MAX_POLL_COUNT.
Referenced by scc_do_crypto(), and scc_zeroize_memories().
scc_return_t scc_write_register | ( | int | register_offset, | |
uint32_t | value | |||
) |
Write a new value into an SCC register. The offset will be checked for validity (range) as well as whether it is accessible (e.g. not busy, not in failed state) at the time of the call.
[in] | register_offset | The (byte) offset within the SCC block of the register to be modified. See SCM Registers and SMN Registers. |
[in] | value | The value to store into the register. |
References check_register_accessible(), check_register_offset(), scc_availability, scc_init(), SCC_READ_REGISTER, SCC_STATUS_INITIAL, SCC_STATUS_UNIMPLEMENTED, scc_update_state(), SCC_WRITE_REGISTER, SCM_CONFIGURATION, SCM_STATUS, SMN_BIT_COUNT, and SMN_TIMER.
scc_return_t scc_zeroize_memories | ( | void | ) |
Zeroize Red and Black memories of the SCC. This will start the Zeroizing process. The routine will return when the memories have zeroized or failed to do so. The driver will poll waiting for this to occur, so this routine must not be called from interrupt level. Some future version of driver may elect instead to sleep.
References scc_availability, scc_crypto_lock, scc_init(), SCC_READ_REGISTER, SCC_STATUS_INITIAL, SCC_STATUS_OK, scc_wait_completion(), SCC_WRITE_REGISTER, SCM_ERR_ZEROIZE_FAILED, SCM_ERROR_STATUS, SCM_INTERRUPT_CTRL, SCM_INTERRUPT_CTRL_CLEAR_INTERRUPT, SCM_INTERRUPT_CTRL_MASK_INTERRUPTS, and SCM_INTERRUPT_CTRL_ZEROIZE_MEMORY.
static int setup_interrupt_handling | ( | void | ) | [static] |
Register the SCM and SMN interrupt handlers.
Called from scc_init()
References os_printk, os_register_interrupt, SCC_DRIVER_NAME, SCC_WRITE_REGISTER, SCM_INTERRUPT_CTRL, SCM_INTERRUPT_CTRL_CLEAR_INTERRUPT, SCM_INTERRUPT_CTRL_MASK_INTERRUPTS, scm_irq_set, SMN_COMMAND, SMN_COMMAND_CLEAR_INTERRUPT, SMN_COMMAND_ENABLE_INTERRUPT, and smn_irq_set.
Referenced by scc_init().
enum scc_status scc_availability = SCC_STATUS_INITIAL [static] |
Internal flag to know whether SCC is in Failed state (and thus many registers are unavailable). Once it goes failed, it never leaves it.
Referenced by scc_alloc_slot(), scc_cleanup(), scc_crypt(), scc_get_configuration(), scc_grab_config_values(), scc_init(), scc_monitor_security_failure(), scc_read_register(), scc_set_sw_alarm(), scc_stop_monitoring_security_failure(), scc_update_state(), scc_write_register(), and scc_zeroize_memories().
volatile void* scc_base [static] |
This is type void* so that a) it cannot directly be dereferenced, and b) pointer arithmetic on it will function in a 'normal way' for the offsets in scc_defines.h
scc_base is the location in the iomap where the SCC's registers (and memory) start.
The referenced data is declared volatile so that the compiler will not make any assumptions about the value of registers in the SCC, and thus will always reload the register into CPU memory before using it (i.e. wherever it is referenced in the driver).
This value should only be referenced by the SCC_READ_REGISTER and SCC_WRITE_REGISTER macros and their ilk. All dereferences must be 32 bits wide.
Referenced by scc_cleanup(), and scc_init().
uint8_t scc_block_padding[8] [static] |
{ SCC_DRIVER_PAD_CHAR, 0, 0, 0, 0, 0, 0, 0 }
Fixed padding for appending to plaintext to fill out a block
Referenced by scc_encrypt().
void(* scc_callbacks[SCC_CALLBACK_SIZE])(void) [static] |
Array to hold function pointers registered by scc_monitor_security_failure() and processed by scc_perform_callbacks()
Referenced by scc_cleanup(), scc_init(), scc_monitor_security_failure(), scc_perform_callbacks(), and scc_stop_monitoring_security_failure().
spinlock_t scc_callbacks_lock = SPIN_LOCK_UNLOCKED [static] |
This lock protects the scc_callbacks list as well as the callbacks_performed
flag in scc_perform_callbacks. Since the data this protects may be read or written from either interrupt or base level, all operations should use the irqsave/irqrestore or similar to make sure that interrupts are inhibited when locking from base level.
Referenced by scc_monitor_security_failure(), scc_perform_callbacks(), and scc_stop_monitoring_security_failure().
scc_config_t scc_configuration [static] |
{ .driver_major_version = SCC_DRIVER_MAJOR_VERSION_1, .driver_minor_version = SCC_DRIVER_MINOR_VERSION_8, .scm_version = -1, .smn_version = -1, .block_size_bytes = -1, .black_ram_size_blocks = -1, .red_ram_size_blocks = -1 }
Structure returned by scc_get_configuration()
Referenced by fsl_shw_smalloc(), and OS_DEV_MMAP().
uint16_t scc_crc_lookup_table[256] [static] |
The lookup table for an 8-bit value. Calculated once by scc_init_ccitt_crc().
Referenced by scc_init_ccitt_crc().
spinlock_t scc_crypto_lock = SPIN_LOCK_UNLOCKED [static] |
Ownership of this lock prevents conflicts on the crypto operation in the SCC and the integrity of the scc_key_info.
Referenced by scc_alloc_slot(), scc_crypt(), scc_dealloc_slot(), scc_decrypt_slot(), scc_encrypt_slot(), scc_load_slot(), scc_read_slot(), and scc_zeroize_memories().
struct scc_key_slot scc_key_info[SCC_KEY_SLOTS] [static] |
Key Control Information. Integrity is controlled by use of scc_crypto_lock.
Referenced by scc_alloc_slot(), scc_dealloc_slot(), scc_decrypt_slot(), scc_encrypt_slot(), scc_get_slot_info(), scc_init(), scc_load_slot(), and scc_read_slot().
uint32_t scc_memory_size_bytes [static] |
Calculated once for quick reference to size of the unreserved space in one RAM in SCM.
Referenced by scc_decrypt(), scc_encrypt(), and scc_grab_config_values().
uint32_t scm_highest_memory_address [static] |
Calculated once for quick reference to size of SCM address space
Referenced by offset_within_scm(), and scc_grab_config_values().
int scm_irq_set = 0 [static] |
Flag to say whether interrupt handler has been registered for SCM interrupt
Referenced by scc_cleanup(), scc_init(), and setup_interrupt_handling().
int smn_irq_set = 0 [static] |
Flag to say whether interrupt handler has been registered for SMN interrupt
Referenced by scc_cleanup(), scc_init(), and setup_interrupt_handling().
© Freescale Semiconductor, Inc., 2007.
All rights reserved. Freescale Confidential Proprietary NDA Required |
![]() |