The SEC2 device driver manages the operation of the SEC 2.0
commonly instantiate d into PowerQUICC pro cessors. It is a fully
functional c omponent, meant to ser ve as an example of a pplication
interaction with the SEC2 core.
The driver is coded i n ANSI C. In it’s design, an attempt ha s been
made to write a devic e driver that is as oper ating system agnostic
as practical. Where necessary, ope rating syste m dependenci es are
identifi e d a n d Section 8, “Por ting ” addresses them.
Testing has been accomplished on VxWorks 5.5 and LinuxPPC
using kernel version 2.4. 27.
Application inter faces to this driver are implement ed through the
ioctl() function cal l. R equests made through this interface can
be broken down into specific compone nts, including
miscellaneous reque sts and process requests. The miscellaneou s
requests are any requests not related to the direct processing of
data by the SEC2 core.
Process requests comprise the majority of the requests and all are
executed usi ng the same
to compose these reque sts are desc ribed in de tail in Section 3.3.6,
Both acronyms indicate the devi ce's functional block that performs the crypto functions requested. For furth er
details on the device see the Hardwa re Refer ence Manual.
The reader should underst and that the design of this driver is a legacy holdover from two prior generations of
security processors. As applications have already been written for those processors, certain aspects of the interface
for this drive r have been designed so as t o maintain source-level a pplication portability with prior driver/ processor
versions. Where relevant in this document, prior-version compatibility features will be indicated to the reader.
Table 1 contains acronyms and abbreviations that are used in this user’s guide.
Table 1. Acronyms and Abbreviations
TermMeaning
AESAAES accelerator—This term is synonymous with AESU in the
documentation.
AFHAARC-4 hardware accelerator—This term is synonymous with AFEU in the
and other documentation.
APADAutopad—The MDHA will automatically pad incomplete message blocks out to 512 bits when APAD
is enabled.
ARC-4Encryption algorithm compatible with the RC-4 algorithm developed by RSA, Inc.
AuthAuthentication
CBCCipher block chaining—An encryption mode commonly used with block ciphers.
CHACrypto hardware accelerator—This term is synonymous with ‘execution unit’ in the
Manual
and other documentation.
CTXContext
DESADES accelerator—This term is synonymous with DEU in the
documentation.
DPDData packet descriptor
ECBElectronic code book—An encryption mode less commonly used with block ciphers.
EUExecution unit
HMACHashed message authentication code
IDGSInitialize digest
MPC18x User’s Manual
MPC18x User’s Manual
MPC18x User’s Manual
and other
MPC18x User’s
and other
IPSecInternet protocol security
ISRInterrupt service routine
KEAKasumi encryption acceleration
MDMessage digest
MDHAMessage digest hardware accelerator—This term is synonymous with MDEU in the
Manual
and other documentation.
OSOperating system
PKPublic key
PKHAPublic key hardware accelerator—This term is synonymous with PKEU in the
2PRELIMINARY—SUBJECT TO CHANGE WITHOUT NOTICEFreescale Semiconductor
MPC18x User’s
MPC18x User’s
Device Driver Components
Table 1. Acronyms and Abbreviations (continued)
TermMeaning
RDKRestore decrypt key—An AESA option to re-use an existing expanded AES decryption key.
RNGARandom number generator accelerator
SDESSingle DES
TEATransfer error acknowledge
TDESTriple DES
VxWorksOperating systems provided by VxWorks Company.
2Device Driver Components
This section is provided to help users understand the internal struct ure of the dev ice driver.
2.1Device Driver Structure
Internally, the driver is structured in four basic components:
•Driver Initialization and Setup
•Application Request Processing
•Interrupt Service Routine
•Defe rred Service Ro ut ine
While executing a request , the driver runs in system/kernel state for all components with the exception of the ISR,
which runs in the operating syst em's standard interrupt processi ng context.
End-User Application
Prepare Request
(Non-Blocking)
ioctl ( )
Callback Function
ProcessingComplete Task
Sleeps on Queue
Completes the User Request
Execute Callback Function
If no callback function is defined, no callback takes place.
Freescale SemiconductorPRELIMINARY—SUBJECT TO CHANGE WITHOUT NOTICE3
Device Driver Components
2.1.1Driver Initialization Routine
The driver initializ ation routine includes both OS-specif ic and hardware-specific initi alization. The steps taken by
the driver initialization routine are as follows:
•Finds the security engine core and sets the device memory map starting address in
•Initialize the security engin e's registers
— Controller regis ters
— Channel registers
—EU registers
•Initializes driver internal variables
•Initializes the channel assign ment table
— The device driver will maintain this structure with state informat ion for each channel and user request.
A mutual-exclusion semaph ore protects this structure so multipl e tasks are prevented from interfering
with e ach ot her.
•Initializes the internal reque st queue
— This queue holds requests to be dispatche d when channels becom e availa ble. The queue can hold up to
24 requests. The driver will reject requests with an error when the queue is full.
ProcessingComplete() is spawned then pends on the IsrMsgQId which se rve s as th e inter face betwe en
•
the interrupt service routine and this deferred task.
IOBaseAddress.
2.1.2Request Dispatch Routine
The request dispatch routine provides the ioctl() interface to the device driver. It uses the callers request code to
identify which function is to e xecute and dispatches the appropriat e handler to process the request. The driver
performs a number of tasks that include tracking requests, queuing requests when the requested channel is
unavailable, preparing data packet descriptors, and writing said descriptor's address to the appropriate channel; in
effect giving the security engine the direction to begin processing the request. The ioctl() f unction returns to the
end-user application without waiting for the security engine to complete, assuming that once a DPD (data packet
descriptor) is init iated for processi ng by the hardware, int errupt service may invok e a handler to provide completion
notification
2.1.3Process Request Routine
The process req uest routine t ranslates t he reque st into a seque nce of o ne or mor e data pac ket desc riptor s (DPD) and
feeds it to the security engi ne cor e to initiate processing. If no channels are availa ble to handle the request, the
request is queued.
2.1.4Interrupt Service Routine
When processing is completed by the security eng ine, an interrupt is generated. The interr upt service routine handles
the interrupt and queues the result of the operation in the
4PRELIMINARY—SUBJECT TO CHANGE WITHOUT NOTICEFreescale Semiconductor
IsrMsgQId queue for deferred processing by the
User Interface
2.1.5Deferred Service Routine
The ProcessingComplete() routine completes the requ est outside of the interrupt servi ce routine, and r uns in a
non-ISR context. This routine depends on the IsrMsgQId queue and processes messages written to the queue by
the interrupt servi ce routine. This function will determine which reque st is complete, and notify the calling task
using any handler specified by that calling task. It will then check the remaining content of the process request
queue, and schedule any queued requests.
3User Interface
3.1Application Interface
In order to make a request of the SEC2 devic e, the calling appl ication populates a request structur e with information
describing the request. These structures are described in Section 4, “Individual Request Type Descriptions,” and
include items such as operation ID, channel, callback routines (succe ss and error), and data.
Once the requ est is prep ar ed , the appli cat io n calls
system call used by operating system I/O subsystems to implement special-purpo se func tions. It typically follows
the format:
int ioctl(int fd, /* file descriptor */
int function, /* function code */
int arg /* arbitrary argument (driver dependent) */
The function code (second ar gument) is defined as the I/O control code. This code will specify the driver-specif ic
operation to be performed by the device in question. The third argument is the pointer to the SEC2 user request
structure which contains information needed by the driver to perform the function requested.
The following is a list of guideline s to be followed by the end-user application when preparing a request structure:
•The first member of every request structure is an operation ID (opID). The operation ID is used by the
device driver to determine the format of the request structure.
•While all requests have a “channel” member, it's presence is a holdover from earlier variations of the
security engine. For SEC2, it no longer has a valid use, and is retained solely to maintaining request
compatibility for ap plications written for older security engines.
•All process request st ructure s have a status member. This value is f illed i n by the devic e drive r when the
interrupt for t he opera tion occurs and it refle cts the statu s of the ope rati on as indi cated by t he inte rrupt. The
valid values for this sta tus member are DONE (normal status) or ERROR (error status).
•All process request stru ctures have two not ify members, notify and notify_on_error. These notify
members can be used by the device driver to notify the application when its request has been completed.
They may be the same function, or diff erent, as required by the caller's operational requirements.
•All process request structures have a
process requests tog ether.
•It is the application's choice to use a notifier function or to poll the status member.
ioctl() with the prepared request. This function is a standard
next request member. This allows the application to chain multiple
Freescale SemiconductorPRELIMINARY—SUBJECT TO CHANGE WITHOUT NOTICE5
User Interface
3.2Error Handling
Due to the asynchronous nature of the device/driver, there are two primary sources of errors:
•Syntax or logic. These are returned in the
status member of the 'user request' argument and as a return
code from ioctl function. Errors of this type are detected by the driver, not by hardware.
•Prot oco l /p roced u re . The s e errors are ret urn ed on ly in the
status member of the user request argument.
Errors of this type are detected by hardware in the course of their execution.
Consequently, the end-user application needs two levels of error checking, the first one after the return from the
ioctl function, and the second one after the comple tion of the request. The second level is possible only if the
request was done with at least the
notify_on_error member of the user request structure. If the
notification/callback function has not been requested, this level of error will be lost.
A code example of the two levels of errors are as follows, using an AES request as an example:
AESA_CRYPT_REQ aesdynReq;
..
aesdynReq.opId = DPD_AESA_CBC_ENCRYPT_CRYPT;
aesdynReq.channel = 0;
aesdynReq.notify = (void *) notifAes;
aesdynReq.notify_on_error = (void *) notifAes;
aesdynReq.status = 0;
aesdynReq.inIvBytes = 16;
aesdynReq.inIvData = iv_in;
aesdynReq.keyBytes = 32;
aesdynReq.keyData = AesKey;
aesdynReq.inBytes = packet_length;
aesdynReq.inData = aesData;
aesdynReq.outData = aesResult;
aesdynReq.outIvBytes = 16;
aesdynReq.outIvData = iv_out;
aesdynReq.nextReq = 0;
status = Ioctl(device, IOCTL_PROC_REQ, &aesdynReq);
if (status != 0) {
printf ("Syntax-Logic Error in dynamic descriptor 0x%x\n", status); .
6PRELIMINARY—SUBJECT TO CHANGE WITHOUT NOTICEFreescale Semiconductor
User Interface
/* in callback function notifAes */
if (aesdynReq.status != 0) {
printf ("Error detected by HW 0x%x\n", aesdynReq.status) ;
.
.
}
3.3Global Definitions
3.3.1I/O Control Codes
The I/O control code is the second argument in the ioctl function. Definitions of these control codes are defined
in
Sec2.h.
Internally, these values are used in conjunction with a ba se index to cre ate the I /O control c odes. The macro f or this
base index is defined by
SEC2_IOCTL_INDEX and has a value of 0x0800.
Table 2. Second and Third Arguments in the ioctl Function
I/O Control Code (Second
Argument in
SEC2_PROC_REQPointer to user's request structure
SEC2_GET_STATUSPointer to a
SEC2_MALLOCPointer to be assigned to a block of kernel memory for holding
SEC2_FREEPointer to free a block originally allocated by
SEC2_COPYFROMPointer to type
SEC2_COPYTOPointer to type
ioctl Function) Third Argument in ioctl Function
STATUS_REQ
caller data to be operated upon
MALLOC_REQ, which will hold information
about a user buffer that will be copied from user memory space
to kernel memory space allocated by
MALLOC_REQ, which will hold information
about a user buffer that will be copied from kernel memory
space allocated by
SEC2_MALLOC back to a user's buffer.
SEC2_MALLOC
SEC2_MALLOC
3.3.2Channel Definitions
The NUM_CHANNELS definition is used to specify the number of channels implemented in the SEC2 device. If not
specified, it will be set to a value of 4 as a default.
Freescale SemiconductorPRELIMINARY—SUBJECT TO CHANGE WITHOUT NOTICE7
User Interface
Table 3. Channel Defines
DefineDescription
NUM_AFHASNumber of ARC4 CHAs
NUM_DESASNumber of DES CHAs
NUM_MDHASNumber of MD CHAs
NUM_RNGASNumber of RNG CHAs
NUM_PKHASNumber of PK CHAs
NUM_AESASNumber of AESA CHAs
The NUM_CHAS defini tion conta ins the tot al number of crypt o hardware acc elerator s (CHAs) in SEC2 and is si mply
defined as the sum of the individual channels.
The device name is defined as
/dev/sec2.
3.3.3Operation ID (opId) Masks
Operation Ids can be broken down into two parts, the group or type of request and the request index or descriptor
within a group or type. This is provided to he lp unders tand the structur ing of the opIds . It is not speci fically needed
within a user applicati on.
Table 4. Request Operation ID Mask
Define Description Value
DESC_TYPE_MASKThe mask for the group or type of an opId 0xFF00
DESC_NUM_MASKThe mask for the request index or descriptor within that group or type 0x00FF
3.3.4Return Codes
A complete list of the error status results that may be returned to the callback routine s follows:
Table 5. Callback Error Status Return Code
Define Description Value
SEC2_SUCCESSSuccessful completion of request 0
SEC2_MEMORY_ALLOCATIONDriver can’t obtain memory from the host operating
system
0xE004FFFF
SEC2_INVALID_CHANNELChannel specification was out of range. This exists for
legacy compatibility, and has no relevance for SEC2
SEC2_INVALID_CHA_TYPERequested CHA doesn’t exist0xE004FFFD
SEC2_INVALID_OPERATION_IDRequested opID is out of range for this request type 0xE004FFFC
SEC2_CHANNEL_NOT_AVAILABLERequested channel was not available. This error
exists for legacy compatibility reasons, and has no
relevance for SEC2
Freescale SemiconductorPRELIMINARY—SUBJECT TO CHANGE WITHOUT NOTICE9
User Interface
Table 5. Callback Error Status Return Code (continued)
Define Description Value
SEC2_CANCELLED_REQUESTError due to canceled request -1010
SEC2_INVALID_ADDRESSError due to a NULL request -1011
3.3.5 Miscellaneous Request Structures
3.3.5.1 STATUS_REQ Structure
Used to indicate the internal state of the SEC2 core as well as the driver after the occurrence of an event. Returned
as a pointer by GetStatus() and embedded in all requests. This structure is defined in Sec2Notify.h
Each element is a copy of the contents of the same register in the
SEC2 driver. This structure is also known as
SEC2_STATUS through a typedef.
unsigned long ChaAssignmentStatusRegister[2];
unsigned long InterruptControlRegister[2];
unsigned long InterruptStatusRegister[2];
unsigned long IdRegister;
unsigned long ChannelStatusRegister[NUM_CHANNELS][2];
unsigned long ChannelConfigurationRegister[NUM_CHANNELS][2];
unsigned long CHAInterruptStatusRegister[NUM_CHAS][2];
unsigned long QueueEntryDepth;
unsigned long FreeChannels;
unsigned long FreeAfhas;
unsigned long FreeDesas;
unsigned long FreeMdhas;
unsigned long FreePkhas;
unsigned long FreeAesas;
unsigned long FreeKeas;
unsigned long BlockSize;
3.3.5.2 SEC2_NOTIFY_ON_ERROR_CTX Structure
Structure returned to the notify_on_error callback routine that was setup in the initial process request. This
structure contains the original request structure as well as an error and driver status.
unsigned long errorcode; // Error that the request generated
Freescale SemiconductorPRELIMINARY—SUBJECT TO CHANGE WITHOUT NOTICE11
User Interface
notify_on_errorpointer to the notify on error routine that will be called when the request has completed
unsuccessfully. May instead be a process ID if a user-state signal handler will flag
completion. Refer back to
ctxNotifyOnErrcontext area that is filled in by the driver when there is an error.
statuswill contain the returned status of request.
nextReqpointer to next request which allows for multiple request to be linked together and sent
via a single
ioctl function call.
notifyFlags for more info.
The additional data in the process request structures is specific to each request; refer to the specific structure for this
information.
3.3.7Scatter-Gather Buffer Management
A unique feature of the SEC 2.0 processor is the hardware's abilit y to read and act on a scatter- gather descripti on list
for a data buffer. This allows the hardwa re to more efficiently deal with buffers located in memory belonging to a
non-privilege d process; memory which may not be contiguous, bu t instead may be at scatt ered locations de termined
by the memory management scheme of the host system. Any data buffer in any request may be “marked” as a
scattered m emory buffer by the reque sto r as ne ed ed.
For the requestor to do so, two actions must be take n:
•A linked list of structur es of type
EXT_SCATTER_ELEMENT, one per memory f ragment, must be c onstructed
to describe the whole of the buffer's content.
•The buffer pointer shall refer ence the head of this list, not the data itself. The buf fers containing scatter
references shall be ma rked in the request's
scatterBufs element. Which bits get marked shall be
determined by a helper function that understands the mapping used on an individual reque st basis.
3.3.7.1 Building the Local Scatter/Gather List with EXT_SCATTER_ELEMENT
Since individual oper ating systems shall have their own internal means def ining memory mapping constructs, the
driver cannot be designe d with specific knowledge of one particular mapping method. Therefore, a generic memory
fragment definition structure, EXT_SCATTER_ELEMENT is defined for this purpose .
EXT_SCATTER_ELEMENT describes one con tiguous fragment of user memory, and is designed so that multiple
Each
fragments can be tied together into a single linked list. It contains these elem ents:
void *next;pointer to next fragment in list, NULL if at end of list.
void *fragment;pointer to contiguous data fragment.
unsigned short size;size of this fragment in bytes.
With this, the caller must construct the lis t of all the fragments neede d to describe the buf fer ,
of the list, and pass the head as the buff er pointer argument. This li st must rema in intact until completion of the
request.
NULL terminate the end
3.3.7.2 Scatter Buffer Marking
For reasons o f legacy compatibilit y , the structur e of all driver r equest type s maintains the same size and form as prior
versions, with a minor change in that a size-compatible scatterBufs element was added as a modification to the
channel element in other versions. This allows the caller a means of indicating which buffers in the request are
12PRELIMINARY—SUBJECT TO CHANGE WITHOUT NOTICEFreescale Semiconductor
User Interface
scatter -composed, as opposed to direct, contiguous memory (for instance, key data could be in contiguous system
memory, while ciphertext data will be in fragm ented user memory).
A problem with marking buff ers using this method is that there is no means for the caller to clearly identify which
scatterBufs matches any given pointer in the request, sinc e the data description portion of dif ferent requests
bit in
cannot be consistent or of any particular order.
A helper function,
MarkScatterBuffer(), is therefore made available by the driver to make the bit/pointer
association logi c in the driv er ac ces sibl e to th e cal ler. It's form is:
MarkScatterBuffer(void *request, void *buffer);
where request points to the request block being built (the opId element must be set prior to call), and buffer
points to the element within the request which references a scattered buffer. It will then mark the necessary bit in
scatterBufs that defines this buffer for this specific request type.
3.3.7.3 Direct Scatter-Gather Usage Example
In order to make this usage clear, an example is presented. Assume that a triple DES encryption operation is to be
constructed, where the input and output buffers are loca ted in fragmented user memory, and the cipher keys and IV
are contained in system memory. A DES_LOADCTX_CRYPT_REQ is zer o-allocated as encReq, and constructed:
/* set up encryption operation */
encReq.opId = DPD_TDES_CBC_CTX_ENCRYPT;
encReq.notify = notifier;
encReq.notify_on_error = notifier;
encReq.inIvBytes = 8;
encReq.keyBytes = 24;
encReq.inBytes = bufsize;
encReq.inIvData = iv;
encReq.keyData = cipherKey;
encReq.inData = (unsigned char *)input; /* this buffer is scattered */
encReq.outIvBytes = 8;
encReq.outIvData = ctx;
encReq.outData = (unsigned char *)output; /* this buffer is scattered */
MarkScatterBuffer(&encReq, &encReq.input);
MarkScatterBuffer(&encReq, &encReq.output);
Upon completion of the two mark calls, encReq.scatterBufs will have two bits set within it that the driver
knows how to interpret as meaning that the inte nded buffers have scatter lists de fined for them, and will process
them accordingly as the DPD is built for the hardware .
Freescale SemiconductorPRELIMINARY—SUBJECT TO CHANGE WITHOUT NOTICE13
Individual Request Type Descriptions
4Individual Request Type Descriptions
4.1Random Number Requests
4.1.1 RNG_REQ
COMMON_REQ_PREAMBLE
unsigned long rngBytes;
unsigned char* rngData;
NUM_RNGA_DESC defines the number of descriptor s within the DPD_RNG_GROUP that use this request.
DPD_RNG_GROUP (0x1000) defines the group for all descr iptors within this request.
Table 6. RNG_REQ Valid Descriptor (opId)
Descriptor Value Function Description
DPD_RNG_GETRN 0x1000 Generate a series of random values