linux/drivers/mxc/security/mxc_scc.c File Reference

Defines

#define SCM_ACCESS_ERRORS

Functions

static int scc_init (void)
static void scc_cleanup (void)
scc_config_tscc_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]

Detailed Description

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 Documentation

#define SCM_ACCESS_ERRORS

Function Documentation

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.

Parameters:
[in] register_offset register offset within SCC
[in] smn_status recent value from SMN_STATUS
[in] scm_status recent value from SCM_STATUS
Returns:
SCC_RET_OK if ok, SCC_RET_FAIL if not

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.

Parameters:
[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.

Parameters:
[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.
Returns:
Zero - success. Non-zero - SCM status bits defining failure.

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).

Parameters:
[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.
Returns:
Zero - success. Non-zero - SCM status bits defining failure.

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.

Parameters:
[in] register_offset Register offset of SCM
Returns:
1 if true, 0 if false (not within 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.

Parameters:
[in] register_offset register offset of SMN.
Returns:
1 if true, 0 if false (not within 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.

Parameters:
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
Returns:
SCC_RET_OK on success, SCC_RET_INSUFFICIENT_SPACE if not slots of requested size are available.

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.

Parameters:
[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.
Returns:
0 on success, non-zero on failure. See scc_return_t.

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.

Parameters:
owner_id The id which owns the slot.
slot The slot number for the key.
Returns:
0 on success, non-zero on failure. See scc_return_t.

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.

Parameters:
[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.

Parameters:
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
Returns:
SCC_RET_OK on success, SCC_RET_FAIL if slot specified cannot be accessed for any reason.

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.

Parameters:
byte_count number of bytes to perform in this operation
scm_control Bit values to be set in SCM_CONTROL register
Returns:
0 on success, value of SCM_ERROR_STATUS on failure

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.

Parameters:
[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.

Parameters:
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
Returns:
SCC_RET_OK on success, SCC_RET_FAIL if slot specified cannot be accessed for any reason.

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.

Returns:
A pointer to the configuration information. This is a pointer to static memory and must not be freed. The values never change, and the return value will never be null.

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.

Parameters:
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.
Returns:
SCC_RET_OK or error indication

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]
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.

Returns:
none

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.

Parameters:
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.
Returns:
SCC_RET_OK on success. SCC_RET_FAIL will be returned if slot specified cannot be accessed for any reason, or SCC_RET_INSUFFICIENT_SPACE if 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.

Parameters:
callback_func Function pointer to routine which will receive notification of the security failure.
Returns:
0 if function was successfully registered, non-zero on failure. See scc_return_t.

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.

Parameters:
[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.
Returns:
0 if OK, non-zero on error. See scc_return_t.

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.

Parameters:
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
Returns:
SCC_RET_OK on success. SCC_RET_FAIL will be returned if slot specified cannot be accessed for any reason, or SCC_RET_INSUFFICIENT_SPACE if 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().

Parameters:
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.

Parameters:
[in] from Pointer to byte after end of message
[out] count_bytes_stripped Number of padding bytes removed by this function.
Returns:
SCC_RET_OK if all goes, well, SCC_RET_FAIL if padding was not present.

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)

Returns:
Current value of SMN_STATUS register.

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.

Parameters:
[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
Returns:
0 on success, non-zero on failure. See scc_return_t.
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.

Parameters:
[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.
Returns:
0 if OK, non-zero on error. See scc_return_t.

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.

Returns:
0 or error if initialization fails.

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]

Variable Documentation

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]
Initial value:
    { 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]
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().

Initial value:
 {
        .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().

footer
©  Freescale Semiconductor, Inc., 2007.  All rights reserved.
Freescale Confidential Proprietary
NDA Required
doxygen