linux/drivers/mxc/security/rng/rng_driver.c File Reference

Defines

#define TRUE   1

Functions

static DECLARE_COMPLETION (rng_self_testing)
 OS_WAIT_OBJECT (rng_wait_queue)
 OS_DEV_INIT (rng_init)
 OS_DEV_SHUTDOWN (rng_shutdown)
static void rng_cleanup (void)
static uint32_t finish_random (shw_queue_entry_t *gen_entry)
fsl_shw_return_t fsl_shw_get_random (fsl_shw_uco_t *user_ctx, uint32_t length, uint8_t *data)
fsl_shw_return_t fsl_shw_add_entropy (fsl_shw_uco_t *user_ctx, uint32_t length, uint8_t *data)
 OS_DEV_ISR (rng_irq)
static os_error_code rng_map_RNG_memory (void)
static os_error_code rng_setup_interrupt_handling (void)
static os_error_code rng_grab_config_values (void)
static fsl_shw_return_t rng_drain_fifo (uint32_t *random_p, int count_words)
 OS_DEV_TASK (rng_entropy_task)

Variables

static volatile void * rng_base
static int rng_irq_set = FALSE
static int rng_output_fifo_size
static int rng_major
os_driver_reg_t rng_reg_handle
static volatile rng_status_t rng_availability = RNG_STATUS_INITIAL
static os_lock_t rng_queue_lock = NULL
static shw_queue_t rng_work_queue
static unsigned task_started = FALSE

Detailed Description

This is the driver code for the hardware Random Number Generator (RNG).

It provides the following functions to callers: fsl_shw_return_t fsl_shw_get_random(fsl_shw_uco_t* user_ctx, uint32_t length, uint8_t* data);

fsl_shw_return_t fsl_shw_add_entropy(fsl_shw_uco_t* user_ctx, uint32_t length, uint8_t* data);

The life of the driver starts at boot (or module load) time, with a call by the kernel to rng_init(). As part of initialization, a background task running rng_entropy_task() will be created.

The life of the driver ends when the kernel is shutting down (or the driver is being unloaded). At this time, rng_shutdown() is called. No function will ever be called after that point. In the case that the driver is reloaded, a new copy of the driver, with fresh global values, etc., is loaded, and there will be a new call to rng_init().

A call to fsl_shw_get_random() gets converted into a work entry which is queued and handed off to a background task for fulfilment. This provides for a single thread of control for reading the RNG's FIFO register, which might otherwise underflow if not carefully managed.

A call to fsl_shw_add_entropy() will cause the additional entropy to be passed directly into the hardware.

In a debug configuration, it provides the following kernel functions: rng_return_t rng_read_register(uint32_t byte_offset, uint32_t* valuep); rng_return_t rng_write_register(uint32_t byte_offset, uint32_t value);


Define Documentation

#define TRUE   1

Non-true value for arguments, return values.

True value for arguments, return values.


Function Documentation

static DECLARE_COMPLETION ( rng_self_testing   )  [static]

Waiting queue for RNG SELF TESTING

static uint32_t finish_random ( shw_queue_entry_t *  gen_entry  )  [static]

Post-process routine for fsl_shw_get_random().

This function will copy the random data generated by the background task into the user's buffer and then free the local buffer.

Parameters:
gen_entry The work request.
Returns:
0 = meaning work completed, pass back result.

References rng_work_entry::data_local, rng_work_entry::data_user, FSL_UCO_USERMODE_USER, rng_work_entry::hdr, rng_work_entry::length, os_copy_to_user, and os_free_memory.

Referenced by fsl_shw_get_random().

OS_DEV_INIT ( rng_init   ) 

Initialize the driver.

Set up the driver to have access to RNG device registers and verify that it appears to be a proper working device.

Set up interrupt handling. Assure RNG is ready to go and (possibly) set it into High Assurance mode. Create a background task to run rng_entropy_task(). Set up up a callback with the SCC driver should the security alarm go off. Tell the kernel that the driver is here.

This routine is called during kernel init or module load (insmod).

The function will fail in one of two ways: Returning OK to the caller so that kernel startup / driver initialization completes, or returning an error. In the success case, the function could set the rng_avaailability to RNG_STATUS_FAILED so that only minimal support (e.g. register peek / poke) is available in the driver.

Returns:
a call to os_dev_init_return()

References os_create_task, os_dev_init_return, os_driver_complete_registration, os_driver_init_registration, OS_ERROR_FAIL_S, OS_ERROR_OK_S, os_lock_alloc_init(), os_printk, rng_availability, rng_base, RNG_CHECK_SEED_ERR, RNG_CHECK_SELF_ERR, rng_cleanup(), RNG_CLEAR_ALL_STATUS, RNG_CLEAR_ERR, RNG_DRIVER_NAME, RNG_GET_HIGH_ASSURANCE, RNG_GET_STATUS, RNG_GO, rng_grab_config_values(), RNG_HAS_BAD_KEY, RNG_HAS_ERROR, rng_major, rng_map_RNG_memory(), RNG_MASK_ALL_INTERRUPTS, RNG_OSCILLATOR_FAILED, RNG_PUT_RNG_TO_SLEEP, rng_queue_lock, RNG_READ_REGISTER, RNG_SELF_TEST, RNG_SET_HIGH_ASSURANCE, rng_setup_interrupt_handling(), RNG_STATUS_CHECKING, RNG_STATUS_FAILED, RNG_STATUS_OK, RNG_STATUS_UNIMPLEMENTED, RNG_UNMASK_ALL_INTERRUPTS, RNG_WAKE, rng_work_queue, RNG_WORKING, RNGC_ERROR, RNGC_STATUS, scc_monitor_security_failure(), and task_started.

OS_DEV_ISR ( rng_irq   ) 

This is the interrupt handler for the RNG. It is only ever invoked if the RNG detects a FIFO Underflow error.

If the error is a Security Violation, this routine will set the rng_availability to RNG_STATUS_FAILED, as the entropy pool may have been corrupted. The RNG will also be placed into low power mode. The SCC will have noticed the problem as well.

The other possibility, if the RNG is not in High Assurance mode, would be simply a FIFO Underflow. No special action, other than to clear the interrupt, is taken.

References os_dev_isr_return, rng_availability, RNG_CLEAR_ALL_STATUS, RNG_GET_HIGH_ASSURANCE, RNG_HAS_ERROR, RNG_MASK_ALL_INTERRUPTS, RNG_SEED_DONE, RNG_SELF_TEST_DONE, RNG_SLEEP, and RNG_STATUS_FAILED.

OS_DEV_SHUTDOWN ( rng_shutdown   ) 

Prepare driver for exit.

This is called during rmmod when the driver is unloading. Try to undo whatever was done during rng_init(), to make the machine be in the same state, if possible.

Calls rng_cleanup() to do all work, and then unmap device's register space.

References os_dev_shutdown_return, os_driver_remove_registration, OS_ERROR_OK_S, os_unmap_device, RNG_ADDRESS_RANGE, rng_base, and rng_cleanup().

OS_DEV_TASK ( rng_entropy_task   ) 

This is the background task of the driver. It is scheduled by RNG_ADD_WORK_ENTRY().

This will process each entry on the rng_work_queue. Blocking requests will cause sleepers to be awoken. Non-blocking requests will be placed on the results queue, and if appropriate, the callback function will be invoked.

References BYTES_TO_WORDS, rng_work_entry::completed, rng_work_entry::data_local, FSL_UCO_BLOCKING_MODE, FSL_UCO_CALLBACK_MODE, rng_work_entry::hdr, rng_work_entry::length, os_dev_task_begin, os_dev_task_return, OS_ERROR_OK_S, os_lock_save_context, os_unlock_restore_context, os_wake_sleepers, rng_drain_fifo(), and rng_queue_lock.

OS_WAIT_OBJECT ( rng_wait_queue   ) 

Object for blocking-mode callers of RNG driver to sleep.

static void rng_cleanup ( void   )  [static]

Undo everything done by rng_init() and place driver in fail mode.

Deregister from SCC, stop tasklet, shutdown the RNG. Leave the register map in place in case other drivers call rng_read/write_register()

Returns:
void

References os_deregister_interrupt, os_dev_stop_task, rng_availability, rng_base, rng_irq_set, RNG_MASK_ALL_INTERRUPTS, RNG_SLEEP, RNG_STATUS_FAILED, RNG_STATUS_UNIMPLEMENTED, scc_stop_monitoring_security_failure(), and task_started.

Referenced by OS_DEV_INIT(), and OS_DEV_SHUTDOWN().

static fsl_shw_return_t rng_drain_fifo ( uint32_t *  random_p,
int  count_words 
) [static]

This function copies words from the RNG FIFO into the caller's buffer.

Parameters:
random_p Location to copy random data
count_words Number of words to copy
Returns:
An error code.

References FSL_RETURN_ERROR_S, FSL_RETURN_INTERNAL_ERROR_S, FSL_RETURN_NO_RESOURCE_S, FSL_RETURN_OK_S, os_printk, rng_availability, RNG_CHECK_SEED_ERR, RNG_CLEAR_ERR, RNG_GET_WORDS_IN_FIFO, RNG_MAX_TRIES, RNG_READ_FIFO, and RNG_STATUS_OK.

Referenced by OS_DEV_TASK().

static os_error_code rng_grab_config_values ( void   )  [static]

Read configuration information from the RNG.

Sets rng_output_fifo_size.

Returns:
A error code indicating whether the part is the expected one.

References OS_ERROR_FAIL_S, OS_ERROR_OK_S, RNG_GET_FIFO_SIZE, RNG_GET_RNG_TYPE, rng_output_fifo_size, and RNG_VERIFY_TYPE.

Referenced by OS_DEV_INIT().

static os_error_code rng_map_RNG_memory ( void   )  [static]

Place the RNG's memory into kernel virtual space.

Returns:
OS_ERROR_OK_S on success, os_error_code on failure

References OS_ERROR_FAIL_S, OS_ERROR_OK_S, os_map_device, RNG_ADDRESS_RANGE, rng_base, and RNG_BASE_ADDR.

Referenced by OS_DEV_INIT().

static os_error_code rng_setup_interrupt_handling ( void   )  [static]

Register rng_irq() as the interrupt handler for INT_RNG.

Returns:
OS_ERROR_OK_S on success, os_error_code on failure

References OS_DEV_ISR_REF, OS_ERROR_OK_S, os_register_interrupt, RNG_DRIVER_NAME, rng_irq_set, and RNG_UNMASK_ALL_INTERRUPTS.

Referenced by OS_DEV_INIT().


Variable Documentation

volatile rng_status_t rng_availability = RNG_STATUS_INITIAL [static]

Internal flag to know whether RNG is in Failed state (and thus many registers are unavailable). If the value ever goes to RNG_STATUS_FAILED, it will never change.

Referenced by fsl_shw_add_entropy(), fsl_shw_get_random(), OS_DEV_INIT(), OS_DEV_ISR(), rng_cleanup(), and rng_drain_fifo().

volatile void* rng_base [static]

This is type void* so that a) it cannot directly be dereferenced, and b) pointer arithmetic on it will function for the byte offsets in rng_rnga.h and rng_rngc.h

rng_base is the location in the iomap where the RNG'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 RNG, 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 RNG_READ_REGISTER and RNG_WRITE_REGISTER macros and their ilk. All dereferences must be 32 bits wide.

Referenced by OS_DEV_INIT(), OS_DEV_SHUTDOWN(), rng_cleanup(), and rng_map_RNG_memory().

int rng_irq_set = FALSE [static]

Flag to say whether interrupt handler has been registered for RNG interrupt

Referenced by rng_cleanup(), and rng_setup_interrupt_handling().

int rng_major [static]

Major number for device driver.

Referenced by OS_DEV_INIT().

int rng_output_fifo_size [static]

Size of the RNG's OUTPUT_FIFO, in words. Retrieved with RNG_GET_FIFO_SIZE() during driver initialization.

Referenced by rng_grab_config_values().

os_lock_t rng_queue_lock = NULL [static]

Global lock for the RNG driver. Mainly used for entries on the RNG work queue.

Referenced by OS_DEV_INIT(), and OS_DEV_TASK().

Registration handle for registering driver with OS.

shw_queue_t rng_work_queue [static]

Queue for the RNG task to process.

Referenced by OS_DEV_INIT(), and RNG_ADD_WORK_ENTRY().

unsigned task_started = FALSE [static]

Flag to say whether task initialization succeeded.

Referenced by OS_DEV_INIT(), and rng_cleanup().

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