# The asynchronous Advanced Encryption Standard driver

This AES driver will completely of-load the encryption and decryption process from the CPU, including transmission of data to and from the AES hardware module, which is taken care of by the DMA controller.

## Initialization of the AES module

Before the AES module can start encrypting or decrypting, it has to be set up and configured. Firstly, the aes_init() function have to be executed. This function will set up key-size and which AES mode to use, as well as allocating DMA channels for the AES hardware. Secondly, the key has to be loaded with the aes_load_key() function. In addition to this, some AES modes require an initialization vector to be loaded before encrypting or decrypting any data. If such a mode is to be used, used the aes_load_init_vector() function to load this vector.

## Using the AES driver

When the AES module has been properly set up, it is ready to accept encryption or decryption requests. Multiple requests can be submitted simultaneously, but they must all be either encryption or decryption requests using the same AES mode, not a mix. When all submitted requests have been completed, the AES direction can be changed with the aes_set_cipher() function. In order to change AES mode, the module has to be freed, and reinitialized.

## The AES request

The space needed by an AES request is allocated by calling aes_alloc_request(). The request is then prepared with aes_prepare_request(), and submitted to the driver with aes_submit_request(). After it has completed, it can be reused by running aes_prepare_request() and aes_submit_request() again. If a callback should be called when the request completes, the callback aes_request::req_done and a context pointer aes_request::context must be set before submitting the request. When reusing a request, it is only necessary to set these parameters the first time. When a request is not needed anymore, the memory it occupies should be freed with aes_free_request().