crypto: msm: Add QTI crypto drivers

This is a snapshot of the crypto drivers as of msm-4.9 commit
<e023d014d2039d59d> ( msm: pcie: fix PCIe L0s and L1 ASPM support)
with changes to comply with msm-4.14 format requirement.

Change-Id: I843073176bb25dc96e2d84757faa77008180e0fb
Signed-off-by: Zhen Kong <zkong@codeaurora.org>
This commit is contained in:
Zhen Kong
2018-01-05 15:47:10 -08:00
parent b2bdf7dc77
commit fc2d56f659
30 changed files with 20359 additions and 0 deletions

View File

@@ -0,0 +1,235 @@
Introduction:
=============
Storage encryption has been one of the most required feature from security
point of view. QTI based storage encryption solution uses general purpose
crypto engine. While this kind of solution provide a decent amount of
performance, it falls short as storage speed is improving significantly
continuously. To overcome performance degradation, newer chips are going to
have Inline Crypto Engine (ICE) embedded into storage device. ICE is supposed
to meet the line speed of storage devices.
Hardware Description
====================
ICE is a HW block that is embedded into storage device such as UFS/eMMC. By
default, ICE works in bypass mode i.e. ICE HW does not perform any crypto
operation on data to be processed by storage device. If required, ICE can be
configured to perform crypto operation in one direction (i.e. either encryption
or decryption) or in both direction(both encryption & decryption).
When a switch between the operation modes(plain to crypto or crypto to plain)
is desired for a particular partition, SW must complete all transactions for
that particular partition before switching the crypto mode i.e. no crypto, one
direction crypto or both direction crypto operation. Requests for other
partitions are not impacted due to crypto mode switch.
ICE HW currently supports AES128/256 bit ECB & XTS mode encryption algorithms.
Keys for crypto operations are loaded from SW. Keys are stored in a lookup
table(LUT) located inside ICE HW. Maximum of 32 keys can be loaded in ICE key
LUT. A Key inside the LUT can be referred using a key index.
SW Description
==============
ICE HW has catagorized ICE registers in 2 groups: those which can be accessed by
only secure side i.e. TZ and those which can be accessed by non-secure side such
as HLOS as well. This requires that ICE driver to be split in two pieces: one
running from TZ space and another from HLOS space.
ICE driver from TZ would configure keys as requested by HLOS side.
ICE driver on HLOS side is responsible for initialization of ICE HW.
SW Architecture Diagram
=======================
Following are all the components involved in the ICE driver for control path:
+++++++++++++++++++++++++++++++++++++++++
+ App layer +
+++++++++++++++++++++++++++++++++++++++++
+ System layer +
+ ++++++++ +++++++ +
+ + VOLD + + PFM + +
+ ++++++++ +++++++ +
+ || || +
+ || || +
+ \/ \/ +
+ ++++++++++++++ +
+ + LibQSEECom + +
+ ++++++++++++++ +
+++++++++++++++++++++++++++++++++++++++++
+ Kernel + +++++++++++++++++
+ + + KMS +
+ +++++++ +++++++++++ +++++++++++ + +++++++++++++++++
+ + ICE + + Storage + + QSEECom + + + ICE Driver +
+++++++++++++++++++++++++++++++++++++++++ <===> +++++++++++++++++
|| ||
|| ||
\/ \/
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Storage Device +
+ ++++++++++++++ +
+ + ICE HW + +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Use Cases:
----------
a) Device bootup
ICE HW is detected during bootup time and corresponding probe function is
called. ICE driver parses its data from device tree node. ICE HW and storage
HW are tightly coupled. Storage device probing is dependent upon ICE device
probing. ICE driver configures all the required registers to put the ICE HW
in bypass mode.
b) Configuring keys
Currently, there are couple of use cases to configure the keys.
1) Full Disk Encryption(FDE)
System layer(VOLD) at invocation of apps layer would call libqseecom to create
the encryption key. Libqseecom calls qseecom driver to communicate with KMS
module on the secure side i.e. TZ. KMS would call ICE driver on the TZ side to
create and set the keys in ICE HW. At the end of transaction, VOLD would have
key index of key LUT where encryption key is present.
2) Per File Encryption (PFE)
Per File Manager(PFM) calls QSEECom api to create the key. PFM has a peer comp-
onent(PFT) at kernel layer which gets the corresponding key index from PFM.
Following are all the components involved in the ICE driver for data path:
+++++++++++++++++++++++++++++++++++++++++
+ App layer +
+++++++++++++++++++++++++++++++++++++++++
+ VFS +
+---------------------------------------+
+ File System (EXT4) +
+---------------------------------------+
+ Block Layer +
+ --------------------------------------+
+ +++++++ +
+ dm-req-crypt => + PFT + +
+ +++++++ +
+ +
+---------------------------------------+
+ +++++++++++ +++++++ +
+ + Storage + + ICE + +
+++++++++++++++++++++++++++++++++++++++++
+ || +
+ || (Storage Req with +
+ \/ ICE parameters ) +
+++++++++++++++++++++++++++++++++++++++++
+ Storage Device +
+ ++++++++++++++ +
+ + ICE HW + +
+++++++++++++++++++++++++++++++++++++++++
c) Data transaction
Once the crypto key has been configured, VOLD/PFM creates device mapping for
data partition. As part of device mapping VOLD passes key index, crypto
algorithm, mode and key length to dm layer. In case of PFE, keys are provided
by PFT as and when request is processed by dm-req-crypt. When any application
needs to read/write data, it would go through DM layer which would add crypto
information, provided by VOLD/PFT, to Request. For each Request, Storage driver
would ask ICE driver to configure crypto part of request. ICE driver extracts
crypto data from Request structure and provide it to storage driver which would
finally dispatch request to storage device.
d) Error Handling
Due to issue # 1 mentioned in "Known Issues", ICE driver does not register for
any interrupt. However, it enables sources of interrupt for ICE HW. After each
data transaction, Storage driver receives transaction completion event. As part
of event handling, storage driver calls ICE driver to check if any of ICE
interrupt status is set. If yes, storage driver returns error to upper layer.
Error handling would be changed in future chips.
Interfaces
==========
ICE driver exposes interfaces for storage driver to :
1. Get the global instance of ICE driver
2. Get the implemented interfaces of the particular ice instance
3. Initialize the ICE HW
4. Reset the ICE HW
5. Resume/Suspend the ICE HW
6. Get the Crypto configuration for the data request for storage
7. Check if current data transaction has generated any interrupt
Driver Parameters
=================
This driver is built and statically linked into the kernel; therefore,
there are no module parameters supported by this driver.
There are no kernel command line parameters supported by this driver.
Power Management
================
ICE driver does not do power management on its own as it is part of storage
hardware. Whenever storage driver receives request for power collapse/suspend
resume, it would call ICE driver which exposes APIs for Storage HW. ICE HW
during power collapse or reset, wipes crypto configuration data. When ICE
driver receives request to resume, it would ask ICE driver on TZ side to
restore the configuration. ICE driver does not do anything as part of power
collapse or suspend event.
Interface:
==========
ICE driver exposes following APIs for storage driver to use:
int (*init)(struct platform_device *, void *, ice_success_cb, ice_error_cb);
-- This function is invoked by storage controller during initialization of
storage controller. Storage controller would provide success and error call
backs which would be invoked asynchronously once ICE HW init is done.
int (*reset)(struct platform_device *);
-- ICE HW reset as part of storage controller reset. When storage controller
received reset command, it would call reset on ICE HW. As of now, ICE HW
does not need to do anything as part of reset.
int (*resume)(struct platform_device *);
-- ICE HW while going to reset, wipes all crypto keys and other data from ICE
HW. ICE driver would reconfigure those data as part of resume operation.
int (*suspend)(struct platform_device *);
-- This API would be called by storage driver when storage device is going to
suspend mode. As of today, ICE driver does not do anything to handle suspend.
int (*config)(struct platform_device *, struct request* , struct ice_data_setting*);
-- Storage driver would call this interface to get all crypto data required to
perform crypto operation.
int (*status)(struct platform_device *);
-- Storage driver would call this interface to check if previous data transfer
generated any error.
Config options
==============
This driver is enabled by the kernel config option CONFIG_CRYPTO_DEV_MSM_ICE.
Dependencies
============
ICE driver depends upon corresponding ICE driver on TZ side to function
appropriately.
Known Issues
============
1. ICE HW emits 0s even if it has generated an interrupt
This issue has significant impact on how ICE interrupts are handled. Currently,
ICE driver does not register for any of the ICE interrupts but enables the
sources of interrupt. Once storage driver asks to check the status of interrupt,
it reads and clears the clear status and provide read status to storage driver.
This mechanism though not optimal but prevents filesystem curruption.
This issue has been fixed in newer chips.
2. ICE HW wipes all crypto data during power collapse
This issue necessiate that ICE driver on TZ side store the crypto material
which is not required in the case of general purpose crypto engine.
This issue has been fixed in newer chips.
Further Improvements
====================
Currently, Due to PFE use case, ICE driver is dependent upon dm-req-crypt to
provide the keys as part of request structure. This couples ICE driver with
dm-req-crypt based solution. It is under discussion to expose an IOCTL based
and registeration based interface APIs from ICE driver. ICE driver would use
these two interfaces to find out if any key exists for current request. If
yes, choose the right key index received from IOCTL or registeration based
APIs. If not, dont set any crypto parameter in the request.

View File

@@ -0,0 +1,228 @@
Introduction:
=============
The QTI crypto engine (qce) driver is a module that
provides common services for accessing the QTI crypto device.
Currently, the two main clients of qce are
-qcrypto driver (module provided for accessing CE HW by kernel space apps)
-qcedev driver (module provided for accessing CE HW by user space apps)
The crypto engine (qce) driver is a client to the DMA driver for the QTI
DMA device - Application Data Mover (ADM). ADM is used to provide the DMA
transfer capability between QTI crypto device hardware and DDR memory
for crypto operations.
Figure 1.
---------
Linux kernel
(ex:IPSec)<-----* QTI crypto driver----+
(qcrypto) |
(for kernel space app) |
|
+-->|
|
| *qce <----> QTI
| driver ADM driver <---> ADM HW
+-->| | |
| | |
| | |
| | |
Linux kernel | | |
misc device <--- *QCEDEV Driver-------+ | |
interface (qcedev) (Reg interface) (DMA interface)
(for user space app) \ /
\ /
\ /
\ /
\ /
\ /
\ /
QTI crypto CE3 HW
The entities marked with (*) in the Figure 1, are the software components of
the Linux QTI crypto modules.
===============
IMPORTANT NOTE:
===============
(1) The CE hardware can be accessed either from user space OR kernel space,
at one time. Both user space and kernel space clients cannot access the
qce driver (and the CE hardware) at the same time.
- If your device has user space apps that needs to access the crypto
hardware, make sure to have the qcrypto module disabled/unloaded.
This will result in the kernel space apps to use the registered
software implementation of the crypto algorithms.
- If your device has kernel space apps that needs to access the
crypto hardware, make sure to have qcedev module disabled/unloaded
and implement your user space application to use the software
implementation (ex: openssl/crypto) of the crypto algorithms.
(2) If your device has Playready(Windows Media DRM) application enabled and
uses the qcedev module to access the crypto hardware accelerator,
please be informed that for performance reasons, the CE hardware will need
to be dedicated to playready application. Any other user space application
should be implemented to use the SW implementation (ex: openssl/crypto)
of the crypto algorithms.
Hardware description:
=====================
QTI Crypto HW device family provides a series of algorithms implemented
in the device hardware.
Crypto 2 hardware provides hashing - SHA-1, SHA-256, ciphering - DES, 3DES, AES
algorithms, and concurrent operations of hashing, and ciphering.
In addition to those functions provided by Crypto 2 HW, Crypto 3 HW provides
fast AES algorithms.
In addition to those functions provided by Crypto 3 HW, Crypto 3E provides
HMAC-SHA1 hashing algorithm, and Over The Air (OTA) f8/f9 algorithms as
defined by the 3GPP forum.
Software description
====================
The crypto device is defined as a platform device. The driver is
independent of the platform. The driver supports multiple instances of
crypto HW.
All the platform specific parameters are defined in the board init
file, eg. arch/arm/mach-msm/board-msm7x30.c for MSM7x30.
The qce driver provide the common services of HW crypto
access to the two drivers as listed above (qcedev, qcrypto. It sets up
the crypto HW device for the operation, then it requests ADM driver for
the DMA of the crypto operation.
Two ADM channels and two command lists (one command list for each
channel) are involved in an operation.
The setting up of the command lists and the procedure of the operation
of the crypto device are described in the following sections.
The command list for the first DMA channel is set up as follows:
1st command of the list is for the DMA transfer from DDR memory to the
crypto device to input data to crypto device. The dst crci of the command
is set for crci-in for this crypto device.
2nd command is for the DMA transfer is from crypto device to DDR memory for
the authentication result. The src crci is set as crci-hash-done of the
crypto device. If authentication is not required in the operation,
the 2nd command is not used.
The command list for the second DMA channel is set up as follows:
One command to DMA data from crypto device to DDR memory for encryption or
decryption output from crypto device.
To accomplish ciphering and authentication concurrent operations, the driver
performs the following steps:
(a). set up HW crypto device
(b). hit the crypto go register.
(c). issue the DMA command of first channel to the ADM driver,
(d). issue the DMA command of 2nd channel to the ADM driver.
SHA1/SHA256 is an authentication/integrity hash algorithm. To accomplish
hash operation (or any authentication only algorithm), 2nd DMA channel is
not required. Only steps (a) to (c) are performed.
At the completion of the DMA operation (for (c) and (d)) ADM driver
invokes the callback registered to the DMA driver. This signifies the end of
the DMA operation(s). The driver reads the status and other information from
the CE hardware register and then invokes the callback to the qce driver client.
This signal the completion and the results of the DMA along with the status of
the CE hardware to the qce driver client. This completes a crypto operation.
In the qce driver initialization, memory for the two command lists, descriptor
lists for each crypto device are allocated out of coherent memory, using Linux
DMA API. The driver pre-configures most of the two ADM command lists
in the initialization. During each crypto operation, minimal set up is required.
src_dscr or/and dst_dscr descriptor list of the ADM command are populated
from the information obtained from the corresponding data structure. eg: for
AEAD request, the following data structure provides the information:
struct aead_request *req
......
req->assoc
req->src
req->dst
The DMA address of a scatter list will be retrieved and set up in the
descriptor list of an ADM command.
Power Management
================
none
Interface:
==========
The interface is defined in qce.h
The clients qcrypto, qcedev drivers are the clients using
the interfaces.
The following services are provided by the qce driver -
qce_open(), qce_close(), qce_ablk_cipher_req(),
qce_hw_support(), qce_process_sha_req()
qce_open() is the first request from the client, ex. QTI crypto
driver (qcedev, qcrypto), to open a crypto engine. It is normally
called at the probe function of the client for a device. During the
probe,
- ADM command list structure will be set up
- Crypto device will be initialized.
- Resource associated with the crypto engine is retrieved by doing
platform_get_resource() or platform_get_resource_byname().
The resources for a device are
- crci-in, crci-out, crci-hash-done
- two DMA channel IDs, one for encryption and decryption input, one for
output.
- base address of the HW crypto device.
qce_close() is the last request from the client. Normally, it is
called from the remove function of the client.
qce_hw_support() allows the client to query what is supported
by the crypto engine hardware.
qce_ablk_cipher_req() provides ciphering service to the client.
qce_process_sha_req() provide hashing service to the client.
qce_aead_req() provide aead service to the client.
Module parameters:
==================
The following module parameters are defined in the board init file.
-CE hardware base register address
-Data mover channel used for transfer to/from CE hardware
These parameters differ in each platform.
Dependencies:
=============
Existing DMA driver.
The transfers are DMA'ed between the crypto hardware and DDR memory via the
data mover, ADM. The data transfers are set up to use the existing dma driver.
User space utilities:
=====================
n/a
Known issues:
=============
n/a
To do:
======
n/a

View File

@@ -0,0 +1,231 @@
Introduction:
=============
This driver provides IOCTLS for user space application to access crypto
engine hardware for the qcedev crypto services. The driver supports the
following crypto algorithms
- AES-128, AES-256 (ECB, CBC and CTR mode)
- AES-192, (ECB, CBC and CTR mode)
(support exists on platform supporting CE 3.x hardware)
- SHA1/SHA256
- AES-128, AES-256 (XTS), AES CMAC, SHA1/SHA256 HMAC
(support exists on platform supporting CE 4.x hardware)
Hardware description:
=====================
Crypto 3E provides cipher and hash algorithms as defined in the
3GPP forum specifications.
Software description
====================
The driver is a Linux platform device driver. For an msm target,
there can be multiple crypto devices assigned for QCEDEV.
The driver is a misc device driver as well.
The following operations are registered in the driver,
-qcedev_ioctl()
-qcedev_open()
-qcedev_release()
The following IOCTLS are available to the user space application(s)-
Cipher IOCTLs:
--------------
QCEDEV_IOCTL_ENC_REQ is for encrypting data.
QCEDEV_IOCTL_DEC_REQ is for decrypting data.
Hashing/HMAC IOCTLs
-------------------
QCEDEV_IOCTL_SHA_INIT_REQ is for initializing a hash/hmac request.
QCEDEV_IOCTL_SHA_UPDATE_REQ is for updating hash/hmac.
QCEDEV_IOCTL_SHA_FINAL_REQ is for ending the hash/mac request.
QCEDEV_IOCTL_GET_SHA_REQ is for retrieving the hash/hmac for data
packet of known size.
QCEDEV_IOCTL_GET_CMAC_REQ is for retrieving the MAC (using AES CMAC
algorithm) for data packet of known size.
The requests are synchronous. The driver will put the process to
sleep, waiting for the completion of the requests using wait_for_completion().
Since the requests are coming out of user space application, before giving
the requests to the low level qce driver, the ioctl requests and the
associated input/output buffer will have to be safe checked, and copied
to/from kernel space.
The extra copying of requests/buffer can affect the performance. The issue
with copying the data buffer is resolved by having the client use PMEM
allocated buffers.
NOTE: Using memory allocated via PMEM is supported only for in place
operations where source and destination buffers point to the same
location. Support for different source and destination buffers
is not supported currently.
Furthermore, when using PMEM, and in AES CTR mode, when issuing an
encryption or decryption request, a non-zero byteoffset is not
supported.
The design of the driver is to allow multiple open, and multiple requests
to be issued from application(s). Therefore, the driver will internally queue
the requests, and serialize the requests to the low level qce (or qce40) driver.
On an IOCTL request from an application, if there is no outstanding
request, a the driver will issue a "qce" request, otherwise,
the request is queued in the driver queue. The process is suspended
waiting for completion.
On completion of a request by the low level qce driver, the internal
tasklet (done_tasklet) is scheduled. The sole purpose of done_tasklet is
to call the completion of the current active request (complete()), and
issue more requests to the qce, if any.
When the process wakes up from wait_for_completion(), it will collect the
return code, and return the ioctl.
A spin lock is used to protect the critical section of internal queue to
be accessed from multiple tasks, SMP, and completion callback
from qce.
The driver maintains a set of statistics using debug fs. The files are
in /debug/qcedev/stats1, /debug/qcedev/stats2, /debug/qcedev/stats3;
one for each instance of device. Reading the file associated with
a device will retrieve the driver statistics for that device.
Any write to the file will clear the statistics.
Power Management
================
n/a
Interface:
==========
Linux user space applications will need to open a handle
(file descriptor) to the qcedev device. This is achieved by doing
the following to retrieve a file descriptor to the device.
fd = open("/dev/qce", O_RDWR);
..
ioctl(fd, ...);
Once a valid fd is retrieved, user can call the following ioctls with
the fd as the first parameter and a pointer to an appropriate data
structure, qcedev_cipher_op_req or qcedev_sha_op_req (depending on
cipher/hash functionality) as the second parameter.
The following IOCTLS are available to the user space application(s)-
Cipher IOCTLs:
--------------
QCEDEV_IOCTL_ENC_REQ is for encrypting data.
QCEDEV_IOCTL_DEC_REQ is for decrypting data.
The caller of the IOCTL passes a pointer to the structure shown
below, as the second parameter.
struct qcedev_cipher_op_req {
int use_pmem;
union{
struct qcedev_pmem_info pmem;
struct qcedev_vbuf_info vbuf;
};
uint32_t entries;
uint32_t data_len;
uint8_t in_place_op;
uint8_t enckey[QCEDEV_MAX_KEY_SIZE];
uint32_t encklen;
uint8_t iv[QCEDEV_MAX_IV_SIZE];
uint32_t ivlen;
uint32_t byteoffset;
enum qcedev_cipher_alg_enum alg;
enum qcedev_cipher_mode_enum mode;
enum qcedev_oper_enum op;
};
Hashing/HMAC IOCTLs
-------------------
QCEDEV_IOCTL_SHA_INIT_REQ is for initializing a hash/hmac request.
QCEDEV_IOCTL_SHA_UPDATE_REQ is for updating hash/hmac.
QCEDEV_IOCTL_SHA_FINAL_REQ is for ending the hash/mac request.
QCEDEV_IOCTL_GET_SHA_REQ is for retrieving the hash/hmac for data
packet of known size.
QCEDEV_IOCTL_GET_CMAC_REQ is for retrieving the MAC (using AES CMAC
algorithm) for data packet of known size.
The caller of the IOCTL passes a pointer to the structure shown
below, as the second parameter.
struct qcedev_sha_op_req {
struct buf_info data[QCEDEV_MAX_BUFFERS];
uint32_t entries;
uint32_t data_len;
uint8_t digest[QCEDEV_MAX_SHA_DIGEST];
uint32_t diglen;
uint8_t *authkey;
uint32_t authklen;
enum qcedev_sha_alg_enum alg;
struct qcedev_sha_ctxt ctxt;
};
The IOCTLs and associated request data structures are defined in qcedev.h
Module parameters:
==================
The following module parameters are defined in the board init file.
-CE hardware nase register address
-Data mover channel used for transfer to/from CE hardware
These parameters differ in each platform.
Dependencies:
=============
qce driver. Please see Documentation/arm/msm/qce.txt.
User space utilities:
=====================
none
Known issues:
=============
none.
To do:
======
Enhance Cipher functionality:
(1) Add support for handling > 32KB for ciphering functionality when
- operation is not an "in place" operation (source != destination).
(when using PMEM allocated memory)
Limitations:
============
(1) In case of cipher functionality, Driver does not support
a combination of different memory sources for source/destination.
In other words, memory pointed to by src and dst,
must BOTH (src/dst) be "pmem" or BOTH(src/dst) be "vbuf".
(2) In case of hash functionality, driver does not support handling data
buffers allocated via PMEM.
(3) Do not load this driver if your device already has kernel space apps
that need to access the crypto hardware.
Make sure to have qcedev module disabled/unloaded and implement your user
space application to use the software implementation (ex: openssl/crypto)
of the crypto algorithms.
(NOTE: Please refer to details on the limitations listed in qce.txt)
(4) If your device has Playready (Windows Media DRM) application enabled
and uses the qcedev module to access the crypto hardware accelerator,
please be informed that for performance reasons, the CE hardware will
need to be dedicated to playready application. Any other user space
application should be implemented to use the software implementation
(ex: openssl/crypto) of the crypto algorithms.

View File

@@ -0,0 +1,142 @@
Introduction:
=============
QTI Crypto (qcrypto) driver is a Linux crypto driver which interfaces
with the Linux kernel crypto API layer to provide the HW crypto functions.
This driver is accessed by kernel space apps via the kernel crypto API layer.
At present there is no means for user space apps to access this module.
Hardware description:
=====================
QTI Crypto HW device family provides a series of algorithms implemented
in the device.
Crypto 2 hardware provides hashing - SHA-1, SHA-256, ciphering - DES, 3DES, AES
algorithms, and concurrent operations of hashing, and ciphering.
In addition to those functions provided by Crypto 2 HW, Crypto 3 provides fast
AES algorithms.
In addition to those functions provided by Crypto 3 HW, Crypto 3E provides
HMAC-SHA1 hashing algorithm.
In addition to those functions provided by Crypto 3 HW, Crypto 4.0 provides
HMAC-SHA1/SHA256, AES CBC-MAC hashing algorithm and AES XTS/CCM cipher
algorithms.
Software description
====================
The module init function (_qcrypto_init()), does a platform_register(),
to register the driver. As the result, the driver probe function,
_qcrypto_probe(), will be invoked for each registered device.
In the probe function, driver opens the low level CE (qce_open), and
registers the supported algorithms to the kernel crypto API layer.
Currently, qcrypto supports the following algorithms.
ablkcipher -
cbc(aes),ecb(aes),ctr(aes)
ahash -
sha1, sha256
aead -
authenc(hmac(sha1),cbc(aes))
The hmac(sha1), hmac(sha256, authenc(hmac(sha1),cbc(aes)), ccm(aes)
and xts(aes) algorithms are registered for some platforms that
support these in the CE hardware
The HW device can support various algorithms. However, the most important
algorithms to gain the performance using a HW crypto accelerator are
AEAD, and ABLKCIPHER.
AEAD stands for "authentication encryption with association data".
ABLKCIPHER stands of "asynchronous block cipher".
The AEAD structure is described in the following header file aead.h
The design of the driver is to allow multiple requests
issued from kernel client SW (eg IPSec).
Therefore, the driver will have to internally queue the requests, and
serialize the requests to the low level qce driver.
When a request is received from the client, if there is no outstanding
request, a qce (or qce40) request is issued, otherwise, the request is
queued in the driver queue.
On completion of a request, the qce (or qce40) invokes the registered
callback from the qcrypto. The internal tasklet (done_tasklet) is scheduled
in this callback function. The sole purpose of done_tasklet is
to call the completion of the current active request, and
issue more requests to the qce (or qce40), if any exists.
A spin lock is used to protect the critical section of internal queue to
be accessed from multiple tasks, SMP, and completion callback
from qce.
The driver maintains a set of statistics using debug fs. The files are
in /debug/qcrypto/stats1, /debug/qcrypto/stats2, /debug/qcrypto/stats3;
one for each instance of device. Reading the file associated with
a device will retrieve the driver statistics for that device.
Any write to the file will clear the statistics.
Test vectors for authenc(hmac(sha1),cbc(aes)) algorithm are
developed offline, and imported to crypto/testmgr.c, and crypto/testmgr.h.
Power Management
================
none
Interface:
==========
The kernel interface is defined in crypto.h.
Module parameters:
==================
All the platform specific parameters are defined in the board init
file, eg. arch/arm/mach-msm/board-mssm7x30.c for msm7x30.
Dependencies:
=============
qce driver.
User space utilities:
=====================
n/a
Known issues:
=============
n/a
To do:
======
Add Hashing algorithms.
Limitations:
===============
(1) Each packet transfer size (for cipher and hash) is limited to maximum of
32KB. This is a limitation in the crypto engine hardware. Client will
have to break packets larger than 32KB into multiple requests of smaller
size data packets.
(2) Do not load this driver if your device has user space apps that needs to
access the crypto hardware. Please make sure to have the qcrypto module
disabled/unloaded.
Not having the driver loaded, will result in the kernel space apps to use
the registered software implementation of the crypto algorithms.
(3) If your device has Playready application enabled and uses the qcedev module
to access the crypto hardware accelerator, please be informed that for
performance reasons, the CE hardware will need to be dedicated to playready
application. Any other user space or kernel application should be implemented
to use the software implementation of the crypto algorithms.
(NOTE: Please refer to details on the limitations listed in qce/40.txt)

View File

@@ -0,0 +1,61 @@
* Inline Crypto Engine (ICE)
Required properties:
- compatible : should be "qcom,ice"
- reg : <register mapping>
Optional properties:
- interrupt-names : name describing the interrupts for ICE IRQ
- interrupts : <interrupt mapping for ICE IRQ>
- qcom,enable-ice-clk : should enable clocks for ICE HW
- clocks : List of phandle and clock specifier pairs
- clock-names : List of clock input name strings sorted in the same
order as the clocks property.
- qocm,op-freq-hz : max clock speed sorted in the same order as the clocks
property.
- qcom,instance-type : describe the storage type for which ICE node is defined
currently, only "ufs" and "sdcc" are supported storage type
- vdd-hba-supply : regulated supply to be used by ICE HW
- qcom,msm-bus,name : bus for ICE transactions
- qcom,msm-bus,num-cases : bus case mapping for ICE HW
- qcom,msm-bus,num-paths : bus path mapping for iCE HW
- qcom,msm-bus,vectors-KBps : bus bandwidth to be voted
- qcom,bus-vector-names : bus vectors mapping
Example:
ufs_ice: ufsice@630000 {
compatible = "qcom,ice";
reg = <0x630000 0x8000>;
interrupt-names = "ufs_ice_nonsec_level_irq", "ufs_ice_sec_level_irq";
interrupts = <0 258 0>, <0 257 0>;
qcom,enable-ice-clk;
clock-names = "ice_core_clk_src", "ice_core_clk";
clocks = <&clock_gcc clk_ufs_ice_core_clk_src>,
<&clock_gcc clk_gcc_ufs_ice_core_clk>;
qcom,op-freq-hz = <300000000>, <0>;
qcom,instance-type = "ufs";
status = "disabled";
};
ufs_card_ice: ufscardice@1db0000 {
compatible = "qcom,ice_card";
reg = <0x1db0000 0x8000>;
qcom,enable-ice-clk;
clock-names = "ufs_core_clk", "bus_clk",
"iface_clk", "ice_core_clk";
clocks = <&clock_gcc GCC_UFS_CARD_AXI_CLK>,
<&clock_gcc GCC_UFS_CARD_CLKREF_CLK>,
<&clock_gcc GCC_UFS_CARD_AHB_CLK>,
<&clock_gcc GCC_UFS_CARD_ICE_CORE_CLK>;
qcom,op-freq-hz = <0>, <0>, <0>, <300000000>;
vdd-hba-supply = <&ufs_card_gdsc>;
qcom,msm-bus,name = "ufs_card_ice_noc";
qcom,msm-bus,num-cases = <2>;
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps =
<1 650 0 0>, /* No vote */
<1 650 1000 0>; /* Max. bandwidth */
qcom,bus-vector-names = "MIN",
"MAX";
qcom,instance-type = "ufs_card";
};

View File

@@ -0,0 +1,45 @@
* QCEDEV (QTI Crypto Engine Device)
Required properties:
- compatible : should be "qcom,qcedev"
- reg : should contain crypto, BAM register map.
- reg-names : should contain the crypto and bam base register names.
- interrupts : should contain crypto BAM interrupt.
- qcom,bam-pipe-pair : should contain crypto BAM pipe pair index.
- qcom,ce-hw-instance : should contain crypto HW instance.
- qcom,msm_bus,name: Should be "qcedev-noc"
- qcom,msm_bus,num_cases: Depends on the use cases for bus scaling
- qcom,msm_bus,active-only: Boolean flag for context of request (actve/dual)
- qcom,msm_bus,num_paths: The paths for source and destination ports
- qcom,msm_bus,vectors: Vectors for bus topology.
- qcom,ce-device: Device number.
- qcom,ce-opp-freq: indicates the CE operating frequency in Hz, changes from target to target.
Optional properties:
- qcom,ce-hw-shared : optional, indicates if the hardware is shared between EE.
- qcom,ce-hw-key : optional, indicates if the hardware supports use of HW KEY.
- qcom,support-core-clk-only : optional, indicates if the HW supports single crypto core clk.
- qcom,bsm-ee : optional, indicate the BAM EE value, changes from target to target. Default value is 1 if not specified.
- qcom,smmu-s1-enable : Boolean flag to enable SMMU stage 1 translation.
- iommus : A list of phandle and IOMMU specifier pairs that describe the IOMMU master interfaces of the device.
Example:
qcom,qcedev@fd440000 {
compatible = "qcom,qcedev";
reg = <0xfd440000 0x20000>,
<0xfd444000 0x8000>;
reg-names = "crypto-base","crypto-bam-base";
interrupts = <0 235 0>;
qcom,bam-pipe-pair = <0>;
qcom,ce-hw-instance = <1>;
qcom,ce-device = <0>;
qcom,ce-hw-shared;
qcom,msm-bus,name = "qcedev-noc";
qcom,msm-bus,num-cases = <2>;
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps =
<56 512 0 0>,
<56 512 3936000 393600>,
qcom,ce-opp-freq = <100000000>;
};

View File

@@ -0,0 +1,42 @@
* QCOTA (Over The Air Crypto Device)
Required properties:
- compatible : should be "qcom,qcota"
- reg : should contain crypto, BAM register map.
- reg-names : should contain the crypto and bam base register names.
- interrupts : should contain crypto BAM interrupt.
- qcom,bam-pipe-pair : should contain crypto BAM pipe pair index.
- qcom,ce-hw-instance : should contain crypto HW instance.
- qcom,ce-device: Unique QCOTA device identifier. 0 for first
instance, 1 for second instance, n-1 for n-th instance.
- qcom,ce-opp-freq: indicates the CE operating frequency in Hz, changes from target to target.
Optional properties:
- qcom,support-core-clk-only : optional, indicates if the HW supports single crypto core clk.
- qcom,bsm-ee : optional, indicate the BAM EE value, changes from target to target.Default value is 1 if not specified.
Example:
qcom,qcota@fe140000 {
compatible = "qcom,qcota";
reg = <0xfe140000 0x20000>,
<0xfe144000 0x8000>;
reg-names = "crypto-base","crypto-bam-base";
interrupts = <0 111 0>;
qcom,bam-pipe-pair = <1>;
qcom,ce-hw-instance = <2>;
qcom,ce-device = <0>;
qcom,ce-opp-freq = <100000000>;
};
qcom,qcota@fe0c0000 {
compatible = "qcom,qcota";
reg = <0xfe0c0000 0x20000>,
<0xfe0c4000 0x8000>;
reg-names = "crypto-base","crypto-bam-base";
interrupts = <0 113 0>;
qcom,bam-pipe-pair = <1>;
qcom,ce-hw-instance = <4>;
qcom,ce-device = <1>;
qcom,ce-opp-freq = <100000000>;
};

View File

@@ -0,0 +1,65 @@
* QCRYPTO (QTI Crypto)
Required properties:
- compatible : should be "qcom,qcrypto"
- reg : should contain crypto, BAM register map.
- reg-names : should contain the crypto and bam base register names.
- interrupts : should contain crypto BAM interrupt.
- qcom,bam-pipe-pair : should contain crypto BAM pipe pair index.
- qcom,ce-hw-instance : should contain crypto HW instance.
- qcom,msm_bus,name: Should be "qcrypto-noc"
- qcom,msm_bus,num_cases: Depends on the use cases for bus scaling
- qcom,msm_bus,active-only: Boolean flag for context of request (actve/dual)
- qcom,msm_bus,num_paths: The paths for source and destination ports
- qcom,ce-device: Device number. Device number is encoded with the following:
bit 3-0 device type: 0 for full disk encryption(fde)
1 for per file encrption(pfe)
bit 7-4 unit number within the device type.
Optional properties:
- qcom,ce-hw-shared : optional, indicates if the hardware is shared between EE.
- qcom,ce-hw-key : optional, indicates if the hardware supports use of HW KEY.
- qcom,use-sw-aes-cbc-ecb-ctr-algo : optional, indicates if use SW aes-cbc/ecb/ctr algorithm.
- qcom,use-sw-aes-xts-algo : optional, indicates if use SW aes-xts algorithm.
- qcom,use-sw-aead-algo : optional, indicates if use SW aead algorithm.
- qcom,use-sw-ahash-algo : optional, indicates if use SW hash algorithm.
- qcom,use-sw-hmac-algo : optional, indicates if use SW hmac algorithm.
- qcom,use-sw-aes-ccm-algo : optional, indicates if use SW aes-ccm algorithm.
- qcom,clk-mgmt-sus-res : optional, indicate if the ce clocks need to be disabled/enabled in suspend/resume function.
- qcom,support-core-clk-only : optional, indicates if the HW supports single crypto core clk.
- qcom,request-bw-before-clk : optional, indicates if the HW supports bandwidth requests prior to clock controls.
- qcom,bsm-ee : optional, indicate the BAM EE value, changes from target to target.Default value is 1 if not specified.
- qcom,ce-opp-freq: optional, indicates the CE operating frequency in Hz,
changes from target to target. If not specified, by default the
frequency is set as 100MHZ.
- qcom,msm_bus,vectors: optional, indicates vectors for bus topology.
This attribute is required for msm targets where bus scaling is
required. For other targets such as fsm, they do not perform
bus scaling. It is not required for those targets.
- qcom,smmu-s1-enable : Boolean flag to bypass SMMU stage 1 translation.
- iommus : A list of phandle and IOMMU specifier pairs that describe the IOMMU master interfaces of the device.
Example:
qcom,qcrypto@fd444000 {
compatible = "qcom,qcrypto";
reg = <0xfd440000 0x20000>,
<0xfd444000 0x8000>;
reg-names = "crypto-base","crypto-bam-base";
interrupts = <0 235 0>;
qcom,bam-pipe-pair = <1>;
qcom,ce-hw-instance = <1>;
qcom,ce-device = <0>;
qcom,ce-hw-shared;
qcom,msm-bus,name = "qcrypto-noc";
qcom,msm-bus,num-cases = <2>;
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps =
<56 512 0 0>,
<56 512 3936000 393600>,
qcom,ce-opp-freq = <100000000>;
};

View File

@@ -592,6 +592,48 @@ config CRYPTO_DEV_QCE
hardware. To compile this driver as a module, choose M here. The
module will be called qcrypto.
config CRYPTO_DEV_QCOM_MSM_QCE
tristate "QTI Crypto Engine (QCE) module"
depends on ARCH_QCOM
help
This driver supports QTI Crypto Engine accelerator hardware, which
is present on SDM845, etc. This is the core crypto driver which adds
CE5.0 functionalities. To compile this driver as a module, choose
M here. The module will be called QCE50.
config CRYPTO_DEV_QCRYPTO
tristate "QTI Crypto accelerator"
depends on ARCH_QCOM
select CRYPTO_DES
select CRYPTO_ALGAPI
select CRYPTO_AUTHENC
select CRYPTO_BLKCIPHER
help
This driver supports QTI crypto acceleration
for kernel clients. To compile this driver as a module,
choose M here: the module will be called qcrypto. Please
select Y here to enable.
config CRYPTO_DEV_QCEDEV
tristate "QCEDEV Interface to CE module"
depends on ARCH_QCOM
help
This driver supports QTI QCEDEV Crypto Engine 5.0.
This exposes the interface to the QCE hardware accelerator
via IOCTLs.
To compile this driver as a module, choose M here: the
module will be called qcedev.
config CRYPTO_DEV_OTA_CRYPTO
tristate "OTA Crypto module"
depends on ARCH_QCOM
help
This driver supports QTI OTA Crypto in the FSM9xxx.
To compile this driver as a module, choose M here: the
module will be called ota_crypto. Please select Y here
to enable.
config CRYPTO_DEV_VMX
bool "Support for VMX cryptographic acceleration instructions"
depends on PPC64 && VSX

View File

@@ -34,6 +34,7 @@ obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/
obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/
obj-$(CONFIG_CRYPTO_DEV_QCOM_MSM_QCE) += msm/
obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/
obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o

View File

@@ -0,0 +1,10 @@
config CRYPTO_DEV_QCOM_ICE
tristate "Inline Crypto Module"
default n
depends on BLK_DEV_DM
help
This driver supports Inline Crypto Engine for QTI chipsets, MSM8994
and later, to accelerate crypto operations for storage needs.
To compile this driver as a module, choose M here: the
module will be called ice.

View File

@@ -0,0 +1,5 @@
obj-$(CONFIG_CRYPTO_DEV_QCOM_MSM_QCE) += qce50.o
obj-$(CONFIG_CRYPTO_DEV_QCEDEV) += qcedev.o
obj-$(CONFIG_CRYPTO_DEV_QCRYPTO) += qcrypto.o
obj-$(CONFIG_CRYPTO_DEV_OTA_CRYPTO) += ota_crypto.o
obj-$(CONFIG_CRYPTO_DEV_QCOM_ICE) += ice.o

View File

@@ -0,0 +1,423 @@
/*
* QTI CE 32-bit compatibility syscall for 64-bit systems
*
* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/qcedev.h>
#include <linux/compat.h>
#include "compat_qcedev.h"
static int compat_get_qcedev_pmem_info(
struct compat_qcedev_pmem_info __user *pmem32,
struct qcedev_pmem_info __user *pmem)
{
compat_ulong_t offset;
compat_int_t fd_src;
compat_int_t fd_dst;
int err = 0, i = 0;
uint32_t len;
err |= get_user(fd_src, &pmem32->fd_src);
err |= put_user(fd_src, &pmem->fd_src);
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(offset, &pmem32->src[i].offset);
err |= put_user(offset, &pmem->src[i].offset);
err |= get_user(len, &pmem32->src[i].len);
err |= put_user(len, &pmem->src[i].len);
}
err |= get_user(fd_dst, &pmem32->fd_dst);
err |= put_user(fd_dst, &pmem->fd_dst);
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(offset, &pmem32->dst[i].offset);
err |= put_user(offset, &pmem->dst[i].offset);
err |= get_user(len, &pmem32->dst[i].len);
err |= put_user(len, &pmem->dst[i].len);
}
return err;
}
static int compat_put_qcedev_pmem_info(
struct compat_qcedev_pmem_info __user *pmem32,
struct qcedev_pmem_info __user *pmem)
{
compat_ulong_t offset;
compat_int_t fd_src;
compat_int_t fd_dst;
int err = 0, i = 0;
uint32_t len;
err |= get_user(fd_src, &pmem->fd_src);
err |= put_user(fd_src, &pmem32->fd_src);
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(offset, &pmem->src[i].offset);
err |= put_user(offset, &pmem32->src[i].offset);
err |= get_user(len, &pmem->src[i].len);
err |= put_user(len, &pmem32->src[i].len);
}
err |= get_user(fd_dst, &pmem->fd_dst);
err |= put_user(fd_dst, &pmem32->fd_dst);
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(offset, &pmem->dst[i].offset);
err |= put_user(offset, &pmem32->dst[i].offset);
err |= get_user(len, &pmem->dst[i].len);
err |= put_user(len, &pmem32->dst[i].len);
}
return err;
}
static int compat_get_qcedev_vbuf_info(
struct compat_qcedev_vbuf_info __user *vbuf32,
struct qcedev_vbuf_info __user *vbuf)
{
compat_uptr_t vaddr;
int err = 0, i = 0;
uint32_t len;
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, &vbuf32->src[i].vaddr);
err |= put_user(vaddr, (compat_uptr_t *)&vbuf->src[i].vaddr);
err |= get_user(len, &vbuf32->src[i].len);
err |= put_user(len, &vbuf->src[i].len);
}
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, &vbuf32->dst[i].vaddr);
err |= put_user(vaddr, (compat_uptr_t *)&vbuf->dst[i].vaddr);
err |= get_user(len, &vbuf32->dst[i].len);
err |= put_user(len, &vbuf->dst[i].len);
}
return err;
}
static int compat_put_qcedev_vbuf_info(
struct compat_qcedev_vbuf_info __user *vbuf32,
struct qcedev_vbuf_info __user *vbuf)
{
compat_uptr_t vaddr;
int err = 0, i = 0;
uint32_t len;
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, (compat_uptr_t *)&vbuf->src[i].vaddr);
err |= put_user(vaddr, &vbuf32->src[i].vaddr);
err |= get_user(len, &vbuf->src[i].len);
err |= put_user(len, &vbuf32->src[i].len);
}
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, (compat_uptr_t *)&vbuf->dst[i].vaddr);
err |= put_user(vaddr, &vbuf32->dst[i].vaddr);
err |= get_user(len, &vbuf->dst[i].len);
err |= put_user(len, &vbuf32->dst[i].len);
}
return err;
}
static int compat_get_qcedev_cipher_op_req(
struct compat_qcedev_cipher_op_req __user *data32,
struct qcedev_cipher_op_req __user *data)
{
enum qcedev_cipher_mode_enum mode;
enum qcedev_cipher_alg_enum alg;
compat_ulong_t byteoffset;
enum qcedev_oper_enum op;
compat_ulong_t data_len;
compat_ulong_t encklen;
compat_ulong_t entries;
compat_ulong_t ivlen;
uint8_t in_place_op;
int err = 0, i = 0;
uint8_t use_pmem;
uint8_t enckey;
uint8_t iv;
err |= get_user(use_pmem, &data32->use_pmem);
err |= put_user(use_pmem, &data->use_pmem);
if (use_pmem)
err |= compat_get_qcedev_pmem_info(&data32->pmem, &data->pmem);
else
err |= compat_get_qcedev_vbuf_info(&data32->vbuf, &data->vbuf);
err |= get_user(entries, &data32->entries);
err |= put_user(entries, &data->entries);
err |= get_user(data_len, &data32->data_len);
err |= put_user(data_len, &data->data_len);
err |= get_user(in_place_op, &data32->in_place_op);
err |= put_user(in_place_op, &data->in_place_op);
for (i = 0; i < QCEDEV_MAX_KEY_SIZE; i++) {
err |= get_user(enckey, &(data32->enckey[i]));
err |= put_user(enckey, &(data->enckey[i]));
}
err |= get_user(encklen, &data32->encklen);
err |= put_user(encklen, &data->encklen);
for (i = 0; i < QCEDEV_MAX_IV_SIZE; i++) {
err |= get_user(iv, &(data32->iv[i]));
err |= put_user(iv, &(data->iv[i]));
}
err |= get_user(ivlen, &data32->ivlen);
err |= put_user(ivlen, &data->ivlen);
err |= get_user(byteoffset, &data32->byteoffset);
err |= put_user(byteoffset, &data->byteoffset);
err |= get_user(alg, &data32->alg);
err |= put_user(alg, &data->alg);
err |= get_user(mode, &data32->mode);
err |= put_user(mode, &data->mode);
err |= get_user(op, &data32->op);
err |= put_user(op, &data->op);
return err;
}
static int compat_put_qcedev_cipher_op_req(
struct compat_qcedev_cipher_op_req __user *data32,
struct qcedev_cipher_op_req __user *data)
{
enum qcedev_cipher_mode_enum mode;
enum qcedev_cipher_alg_enum alg;
compat_ulong_t byteoffset;
enum qcedev_oper_enum op;
compat_ulong_t data_len;
compat_ulong_t encklen;
compat_ulong_t entries;
compat_ulong_t ivlen;
uint8_t in_place_op;
int err = 0, i = 0;
uint8_t use_pmem;
uint8_t enckey;
uint8_t iv;
err |= get_user(use_pmem, &data->use_pmem);
err |= put_user(use_pmem, &data32->use_pmem);
if (use_pmem)
err |= compat_put_qcedev_pmem_info(&data32->pmem, &data->pmem);
else
err |= compat_put_qcedev_vbuf_info(&data32->vbuf, &data->vbuf);
err |= get_user(entries, &data->entries);
err |= put_user(entries, &data32->entries);
err |= get_user(data_len, &data->data_len);
err |= put_user(data_len, &data32->data_len);
err |= get_user(in_place_op, &data->in_place_op);
err |= put_user(in_place_op, &data32->in_place_op);
for (i = 0; i < QCEDEV_MAX_KEY_SIZE; i++) {
err |= get_user(enckey, &(data->enckey[i]));
err |= put_user(enckey, &(data32->enckey[i]));
}
err |= get_user(encklen, &data->encklen);
err |= put_user(encklen, &data32->encklen);
for (i = 0; i < QCEDEV_MAX_IV_SIZE; i++) {
err |= get_user(iv, &(data->iv[i]));
err |= put_user(iv, &(data32->iv[i]));
}
err |= get_user(ivlen, &data->ivlen);
err |= put_user(ivlen, &data32->ivlen);
err |= get_user(byteoffset, &data->byteoffset);
err |= put_user(byteoffset, &data32->byteoffset);
err |= get_user(alg, &data->alg);
err |= put_user(alg, &data32->alg);
err |= get_user(mode, &data->mode);
err |= put_user(mode, &data32->mode);
err |= get_user(op, &data->op);
err |= put_user(op, &data32->op);
return err;
}
static int compat_get_qcedev_sha_op_req(
struct compat_qcedev_sha_op_req __user *data32,
struct qcedev_sha_op_req __user *data)
{
enum qcedev_sha_alg_enum alg;
compat_ulong_t authklen;
compat_ulong_t data_len;
compat_ulong_t entries;
compat_ulong_t diglen;
compat_uptr_t authkey;
compat_uptr_t vaddr;
int err = 0, i = 0;
uint8_t digest;
uint32_t len;
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, &data32->data[i].vaddr);
err |= put_user(vaddr, (compat_uptr_t *)&data->data[i].vaddr);
err |= get_user(len, &data32->data[i].len);
err |= put_user(len, &data->data[i].len);
}
err |= get_user(entries, &data32->entries);
err |= put_user(entries, &data->entries);
err |= get_user(data_len, &data32->data_len);
err |= put_user(data_len, &data->data_len);
for (i = 0; i < QCEDEV_MAX_SHA_DIGEST; i++) {
err |= get_user(digest, &(data32->digest[i]));
err |= put_user(digest, &(data->digest[i]));
}
err |= get_user(diglen, &data32->diglen);
err |= put_user(diglen, &data->diglen);
err |= get_user(authkey, &data32->authkey);
err |= put_user(authkey, (compat_uptr_t *)&data->authkey);
err |= get_user(authklen, &data32->authklen);
err |= put_user(authklen, &data->authklen);
err |= get_user(alg, &data32->alg);
err |= put_user(alg, &data->alg);
return err;
}
static int compat_put_qcedev_sha_op_req(
struct compat_qcedev_sha_op_req __user *data32,
struct qcedev_sha_op_req __user *data)
{
enum qcedev_sha_alg_enum alg;
compat_ulong_t authklen;
compat_ulong_t data_len;
compat_ulong_t entries;
compat_ulong_t diglen;
compat_uptr_t authkey;
compat_uptr_t vaddr;
int err = 0, i = 0;
uint8_t digest;
uint32_t len;
for (i = 0; i < QCEDEV_MAX_BUFFERS; i++) {
err |= get_user(vaddr, (compat_uptr_t *)&data->data[i].vaddr);
err |= put_user(vaddr, &data32->data[i].vaddr);
err |= get_user(len, &data->data[i].len);
err |= put_user(len, &data32->data[i].len);
}
err |= get_user(entries, &data->entries);
err |= put_user(entries, &data32->entries);
err |= get_user(data_len, &data->data_len);
err |= put_user(data_len, &data32->data_len);
for (i = 0; i < QCEDEV_MAX_SHA_DIGEST; i++) {
err |= get_user(digest, &(data->digest[i]));
err |= put_user(digest, &(data32->digest[i]));
}
err |= get_user(diglen, &data->diglen);
err |= put_user(diglen, &data32->diglen);
err |= get_user(authkey, (compat_uptr_t *)&data->authkey);
err |= put_user(authkey, &data32->authkey);
err |= get_user(authklen, &data->authklen);
err |= put_user(authklen, &data32->authklen);
err |= get_user(alg, &data->alg);
err |= put_user(alg, &data32->alg);
return err;
}
static unsigned int convert_cmd(unsigned int cmd)
{
switch (cmd) {
case COMPAT_QCEDEV_IOCTL_ENC_REQ:
return QCEDEV_IOCTL_ENC_REQ;
case COMPAT_QCEDEV_IOCTL_DEC_REQ:
return QCEDEV_IOCTL_DEC_REQ;
case COMPAT_QCEDEV_IOCTL_SHA_INIT_REQ:
return QCEDEV_IOCTL_SHA_INIT_REQ;
case COMPAT_QCEDEV_IOCTL_SHA_UPDATE_REQ:
return QCEDEV_IOCTL_SHA_UPDATE_REQ;
case COMPAT_QCEDEV_IOCTL_SHA_FINAL_REQ:
return QCEDEV_IOCTL_SHA_FINAL_REQ;
case COMPAT_QCEDEV_IOCTL_GET_SHA_REQ:
return QCEDEV_IOCTL_GET_SHA_REQ;
case COMPAT_QCEDEV_IOCTL_GET_CMAC_REQ:
return QCEDEV_IOCTL_GET_CMAC_REQ;
default:
return cmd;
}
}
long compat_qcedev_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
long ret;
switch (cmd) {
case COMPAT_QCEDEV_IOCTL_ENC_REQ:
case COMPAT_QCEDEV_IOCTL_DEC_REQ: {
struct compat_qcedev_cipher_op_req __user *data32;
struct qcedev_cipher_op_req __user *data;
int err;
data32 = compat_ptr(arg);
data = compat_alloc_user_space(sizeof(*data));
if (!data)
return -EFAULT;
err = compat_get_qcedev_cipher_op_req(data32, data);
if (err)
return err;
ret = qcedev_ioctl(file, convert_cmd(cmd), (unsigned long)data);
err = compat_put_qcedev_cipher_op_req(data32, data);
return ret ? ret : err;
}
case COMPAT_QCEDEV_IOCTL_SHA_INIT_REQ:
case COMPAT_QCEDEV_IOCTL_SHA_UPDATE_REQ:
case COMPAT_QCEDEV_IOCTL_SHA_FINAL_REQ:
case COMPAT_QCEDEV_IOCTL_GET_CMAC_REQ:
case COMPAT_QCEDEV_IOCTL_GET_SHA_REQ: {
struct compat_qcedev_sha_op_req __user *data32;
struct qcedev_sha_op_req __user *data;
int err;
data32 = compat_ptr(arg);
data = compat_alloc_user_space(sizeof(*data));
if (!data)
return -EFAULT;
err = compat_get_qcedev_sha_op_req(data32, data);
if (err)
return err;
ret = qcedev_ioctl(file, convert_cmd(cmd), (unsigned long)data);
err = compat_put_qcedev_sha_op_req(data32, data);
return ret ? ret : err;
}
default:
return -ENOIOCTLCMD;
}
return 0;
}
EXPORT_SYMBOL(compat_qcedev_ioctl);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("QTI 32-64 Compatibility for Crypto driver");

View File

@@ -0,0 +1,178 @@
/*
* Copyright (c) 2014, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _UAPI_COMPAT_QCEDEV__H
#define _UAPI_COMPAT_QCEDEV__H
#include <linux/types.h>
#include <linux/ioctl.h>
#if IS_ENABLED(CONFIG_COMPAT)
#include <linux/compat.h>
/**
* struct compat_buf_info - Buffer information
* @offset: Offset from the base address of the buffer
* (Used when buffer is allocated using PMEM)
* @vaddr: Virtual buffer address pointer
* @len: Size of the buffer
*/
struct compat_buf_info {
union {
compat_ulong_t offset;
compat_uptr_t vaddr;
};
compat_ulong_t len;
};
/**
* struct compat_qcedev_vbuf_info - Source and destination Buffer information
* @src: Array of buf_info for input/source
* @dst: Array of buf_info for output/destination
*/
struct compat_qcedev_vbuf_info {
struct compat_buf_info src[QCEDEV_MAX_BUFFERS];
struct compat_buf_info dst[QCEDEV_MAX_BUFFERS];
};
/**
* struct compat_qcedev_pmem_info - Stores PMEM buffer information
* @fd_src: Handle to /dev/adsp_pmem used to allocate
* memory for input/src buffer
* @src: Array of buf_info for input/source
* @fd_dst: Handle to /dev/adsp_pmem used to allocate
* memory for output/dst buffer
* @dst: Array of buf_info for output/destination
* @pmem_src_offset: The offset from input/src buffer
* (allocated by PMEM)
*/
struct compat_qcedev_pmem_info {
compat_int_t fd_src;
struct compat_buf_info src[QCEDEV_MAX_BUFFERS];
compat_int_t fd_dst;
struct compat_buf_info dst[QCEDEV_MAX_BUFFERS];
};
/**
* struct compat_qcedev_cipher_op_req - Holds the ciphering request information
* @use_pmem (IN): Flag to indicate if buffer source is PMEM
* QCEDEV_USE_PMEM/QCEDEV_NO_PMEM
* @pmem (IN): Stores PMEM buffer information.
* Refer struct qcedev_pmem_info
* @vbuf (IN/OUT): Stores Source and destination Buffer information
* Refer to struct qcedev_vbuf_info
* @data_len (IN): Total Length of input/src and output/dst in bytes
* @in_place_op (IN): Indicates whether the operation is inplace where
* source == destination
* When using PMEM allocated memory, must set this to 1
* @enckey (IN): 128 bits of confidentiality key
* enckey[0] bit 127-120, enckey[1] bit 119-112,..
* enckey[15] bit 7-0
* @encklen (IN): Length of the encryption key(set to 128 bits/16
* bytes in the driver)
* @iv (IN/OUT): Initialization vector data
* This is updated by the driver, incremented by
* number of blocks encrypted/decrypted.
* @ivlen (IN): Length of the IV
* @byteoffset (IN): Offset in the Cipher BLOCK (applicable and to be set
* for AES-128 CTR mode only)
* @alg (IN): Type of ciphering algorithm: AES/DES/3DES
* @mode (IN): Mode use when using AES algorithm: ECB/CBC/CTR
* Applicable when using AES algorithm only
* @op (IN): Type of operation: QCEDEV_OPER_DEC/QCEDEV_OPER_ENC or
* QCEDEV_OPER_ENC_NO_KEY/QCEDEV_OPER_DEC_NO_KEY
*
* If use_pmem is set to 0, the driver assumes that memory was not allocated
* via PMEM, and kernel will need to allocate memory and copy data from user
* space buffer (data_src/dta_dst) and process accordingly and copy data back
* to the user space buffer
*
* If use_pmem is set to 1, the driver assumes that memory was allocated via
* PMEM.
* The kernel driver will use the fd_src to determine the kernel virtual address
* base that maps to the user space virtual address base for the buffer
* allocated in user space.
* The final input/src and output/dst buffer pointer will be determined
* by adding the offsets to the kernel virtual addr.
*
* If use of hardware key is supported in the target, user can configure the
* key parameters (encklen, enckey) to use the hardware key.
* In order to use the hardware key, set encklen to 0 and set the enckey
* data array to 0.
*/
struct compat_qcedev_cipher_op_req {
uint8_t use_pmem;
union {
struct compat_qcedev_pmem_info pmem;
struct compat_qcedev_vbuf_info vbuf;
};
compat_ulong_t entries;
compat_ulong_t data_len;
uint8_t in_place_op;
uint8_t enckey[QCEDEV_MAX_KEY_SIZE];
compat_ulong_t encklen;
uint8_t iv[QCEDEV_MAX_IV_SIZE];
compat_ulong_t ivlen;
compat_ulong_t byteoffset;
enum qcedev_cipher_alg_enum alg;
enum qcedev_cipher_mode_enum mode;
enum qcedev_oper_enum op;
};
/**
* struct qcedev_sha_op_req - Holds the hashing request information
* @data (IN): Array of pointers to the data to be hashed
* @entries (IN): Number of buf_info entries in the data array
* @data_len (IN): Length of data to be hashed
* @digest (IN/OUT): Returns the hashed data information
* @diglen (OUT): Size of the hashed/digest data
* @authkey (IN): Pointer to authentication key for HMAC
* @authklen (IN): Size of the authentication key
* @alg (IN): Secure Hash algorithm
*/
struct compat_qcedev_sha_op_req {
struct compat_buf_info data[QCEDEV_MAX_BUFFERS];
compat_ulong_t entries;
compat_ulong_t data_len;
uint8_t digest[QCEDEV_MAX_SHA_DIGEST];
compat_ulong_t diglen;
compat_uptr_t authkey;
compat_ulong_t authklen;
enum qcedev_sha_alg_enum alg;
};
struct file;
extern long compat_qcedev_ioctl(struct file *file,
unsigned int cmd, unsigned long arg);
#define COMPAT_QCEDEV_IOCTL_ENC_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 1, struct compat_qcedev_cipher_op_req)
#define COMPAT_QCEDEV_IOCTL_DEC_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 2, struct compat_qcedev_cipher_op_req)
#define COMPAT_QCEDEV_IOCTL_SHA_INIT_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 3, struct compat_qcedev_sha_op_req)
#define COMPAT_QCEDEV_IOCTL_SHA_UPDATE_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 4, struct compat_qcedev_sha_op_req)
#define COMPAT_QCEDEV_IOCTL_SHA_FINAL_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 5, struct compat_qcedev_sha_op_req)
#define COMPAT_QCEDEV_IOCTL_GET_SHA_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 6, struct compat_qcedev_sha_op_req)
#define COMPAT_QCEDEV_IOCTL_LOCK_CE \
_IO(QCEDEV_IOC_MAGIC, 7)
#define COMPAT_QCEDEV_IOCTL_UNLOCK_CE \
_IO(QCEDEV_IOC_MAGIC, 8)
#define COMPAT_QCEDEV_IOCTL_GET_CMAC_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 9, struct compat_qcedev_sha_op_req)
#endif /* CONFIG_COMPAT */
#endif /* _UAPI_COMPAT_QCEDEV__H */

1769
drivers/crypto/msm/ice.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,159 @@
/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _QCOM_INLINE_CRYPTO_ENGINE_REGS_H_
#define _QCOM_INLINE_CRYPTO_ENGINE_REGS_H_
/* Register bits for ICE version */
#define ICE_CORE_CURRENT_MAJOR_VERSION 0x03
#define ICE_CORE_STEP_REV_MASK 0xFFFF
#define ICE_CORE_STEP_REV 0 /* bit 15-0 */
#define ICE_CORE_MAJOR_REV_MASK 0xFF000000
#define ICE_CORE_MAJOR_REV 24 /* bit 31-24 */
#define ICE_CORE_MINOR_REV_MASK 0xFF0000
#define ICE_CORE_MINOR_REV 16 /* bit 23-16 */
#define ICE_BIST_STATUS_MASK (0xF0000000) /* bits 28-31 */
#define ICE_FUSE_SETTING_MASK 0x1
#define ICE_FORCE_HW_KEY0_SETTING_MASK 0x2
#define ICE_FORCE_HW_KEY1_SETTING_MASK 0x4
/* QCOM ICE Registers from SWI */
#define QCOM_ICE_REGS_CONTROL 0x0000
#define QCOM_ICE_REGS_RESET 0x0004
#define QCOM_ICE_REGS_VERSION 0x0008
#define QCOM_ICE_REGS_FUSE_SETTING 0x0010
#define QCOM_ICE_REGS_PARAMETERS_1 0x0014
#define QCOM_ICE_REGS_PARAMETERS_2 0x0018
#define QCOM_ICE_REGS_PARAMETERS_3 0x001C
#define QCOM_ICE_REGS_PARAMETERS_4 0x0020
#define QCOM_ICE_REGS_PARAMETERS_5 0x0024
/* QCOM ICE v3.X only */
#define QCOM_ICE_GENERAL_ERR_STTS 0x0040
#define QCOM_ICE_INVALID_CCFG_ERR_STTS 0x0030
#define QCOM_ICE_GENERAL_ERR_MASK 0x0044
/* QCOM ICE v2.X only */
#define QCOM_ICE_REGS_NON_SEC_IRQ_STTS 0x0040
#define QCOM_ICE_REGS_NON_SEC_IRQ_MASK 0x0044
#define QCOM_ICE_REGS_NON_SEC_IRQ_CLR 0x0048
#define QCOM_ICE_REGS_STREAM1_ERROR_SYNDROME1 0x0050
#define QCOM_ICE_REGS_STREAM1_ERROR_SYNDROME2 0x0054
#define QCOM_ICE_REGS_STREAM2_ERROR_SYNDROME1 0x0058
#define QCOM_ICE_REGS_STREAM2_ERROR_SYNDROME2 0x005C
#define QCOM_ICE_REGS_STREAM1_BIST_ERROR_VEC 0x0060
#define QCOM_ICE_REGS_STREAM2_BIST_ERROR_VEC 0x0064
#define QCOM_ICE_REGS_STREAM1_BIST_FINISH_VEC 0x0068
#define QCOM_ICE_REGS_STREAM2_BIST_FINISH_VEC 0x006C
#define QCOM_ICE_REGS_BIST_STATUS 0x0070
#define QCOM_ICE_REGS_BYPASS_STATUS 0x0074
#define QCOM_ICE_REGS_ADVANCED_CONTROL 0x1000
#define QCOM_ICE_REGS_ENDIAN_SWAP 0x1004
#define QCOM_ICE_REGS_TEST_BUS_CONTROL 0x1010
#define QCOM_ICE_REGS_TEST_BUS_REG 0x1014
#define QCOM_ICE_REGS_STREAM1_COUNTERS1 0x1100
#define QCOM_ICE_REGS_STREAM1_COUNTERS2 0x1104
#define QCOM_ICE_REGS_STREAM1_COUNTERS3 0x1108
#define QCOM_ICE_REGS_STREAM1_COUNTERS4 0x110C
#define QCOM_ICE_REGS_STREAM1_COUNTERS5_MSB 0x1110
#define QCOM_ICE_REGS_STREAM1_COUNTERS5_LSB 0x1114
#define QCOM_ICE_REGS_STREAM1_COUNTERS6_MSB 0x1118
#define QCOM_ICE_REGS_STREAM1_COUNTERS6_LSB 0x111C
#define QCOM_ICE_REGS_STREAM1_COUNTERS7_MSB 0x1120
#define QCOM_ICE_REGS_STREAM1_COUNTERS7_LSB 0x1124
#define QCOM_ICE_REGS_STREAM1_COUNTERS8_MSB 0x1128
#define QCOM_ICE_REGS_STREAM1_COUNTERS8_LSB 0x112C
#define QCOM_ICE_REGS_STREAM1_COUNTERS9_MSB 0x1130
#define QCOM_ICE_REGS_STREAM1_COUNTERS9_LSB 0x1134
#define QCOM_ICE_REGS_STREAM2_COUNTERS1 0x1200
#define QCOM_ICE_REGS_STREAM2_COUNTERS2 0x1204
#define QCOM_ICE_REGS_STREAM2_COUNTERS3 0x1208
#define QCOM_ICE_REGS_STREAM2_COUNTERS4 0x120C
#define QCOM_ICE_REGS_STREAM2_COUNTERS5_MSB 0x1210
#define QCOM_ICE_REGS_STREAM2_COUNTERS5_LSB 0x1214
#define QCOM_ICE_REGS_STREAM2_COUNTERS6_MSB 0x1218
#define QCOM_ICE_REGS_STREAM2_COUNTERS6_LSB 0x121C
#define QCOM_ICE_REGS_STREAM2_COUNTERS7_MSB 0x1220
#define QCOM_ICE_REGS_STREAM2_COUNTERS7_LSB 0x1224
#define QCOM_ICE_REGS_STREAM2_COUNTERS8_MSB 0x1228
#define QCOM_ICE_REGS_STREAM2_COUNTERS8_LSB 0x122C
#define QCOM_ICE_REGS_STREAM2_COUNTERS9_MSB 0x1230
#define QCOM_ICE_REGS_STREAM2_COUNTERS9_LSB 0x1234
#define QCOM_ICE_STREAM1_PREMATURE_LBA_CHANGE (1L << 0)
#define QCOM_ICE_STREAM2_PREMATURE_LBA_CHANGE (1L << 1)
#define QCOM_ICE_STREAM1_NOT_EXPECTED_LBO (1L << 2)
#define QCOM_ICE_STREAM2_NOT_EXPECTED_LBO (1L << 3)
#define QCOM_ICE_STREAM1_NOT_EXPECTED_DUN (1L << 4)
#define QCOM_ICE_STREAM2_NOT_EXPECTED_DUN (1L << 5)
#define QCOM_ICE_STREAM1_NOT_EXPECTED_DUS (1L << 6)
#define QCOM_ICE_STREAM2_NOT_EXPECTED_DUS (1L << 7)
#define QCOM_ICE_STREAM1_NOT_EXPECTED_DBO (1L << 8)
#define QCOM_ICE_STREAM2_NOT_EXPECTED_DBO (1L << 9)
#define QCOM_ICE_STREAM1_NOT_EXPECTED_ENC_SEL (1L << 10)
#define QCOM_ICE_STREAM2_NOT_EXPECTED_ENC_SEL (1L << 11)
#define QCOM_ICE_STREAM1_NOT_EXPECTED_CONF_IDX (1L << 12)
#define QCOM_ICE_STREAM2_NOT_EXPECTED_CONF_IDX (1L << 13)
#define QCOM_ICE_STREAM1_NOT_EXPECTED_NEW_TRNS (1L << 14)
#define QCOM_ICE_STREAM2_NOT_EXPECTED_NEW_TRNS (1L << 15)
#define QCOM_ICE_NON_SEC_IRQ_MASK \
(QCOM_ICE_STREAM1_PREMATURE_LBA_CHANGE |\
QCOM_ICE_STREAM2_PREMATURE_LBA_CHANGE |\
QCOM_ICE_STREAM1_NOT_EXPECTED_LBO |\
QCOM_ICE_STREAM2_NOT_EXPECTED_LBO |\
QCOM_ICE_STREAM1_NOT_EXPECTED_DUN |\
QCOM_ICE_STREAM2_NOT_EXPECTED_DUN |\
QCOM_ICE_STREAM2_NOT_EXPECTED_DUN |\
QCOM_ICE_STREAM2_NOT_EXPECTED_DUS |\
QCOM_ICE_STREAM1_NOT_EXPECTED_DBO |\
QCOM_ICE_STREAM2_NOT_EXPECTED_DBO |\
QCOM_ICE_STREAM1_NOT_EXPECTED_ENC_SEL |\
QCOM_ICE_STREAM2_NOT_EXPECTED_ENC_SEL |\
QCOM_ICE_STREAM1_NOT_EXPECTED_CONF_IDX |\
QCOM_ICE_STREAM1_NOT_EXPECTED_NEW_TRNS |\
QCOM_ICE_STREAM2_NOT_EXPECTED_NEW_TRNS)
/* QCOM ICE registers from secure side */
#define QCOM_ICE_TEST_BUS_REG_SECURE_INTR (1L << 28)
#define QCOM_ICE_TEST_BUS_REG_NON_SECURE_INTR (1L << 2)
#define QCOM_ICE_LUT_KEYS_ICE_SEC_IRQ_STTS 0x2050
#define QCOM_ICE_LUT_KEYS_ICE_SEC_IRQ_MASK 0x2054
#define QCOM_ICE_LUT_KEYS_ICE_SEC_IRQ_CLR 0x2058
#define QCOM_ICE_STREAM1_PARTIALLY_SET_KEY_USED (1L << 0)
#define QCOM_ICE_STREAM2_PARTIALLY_SET_KEY_USED (1L << 1)
#define QCOM_ICE_QCOMC_DBG_OPEN_EVENT (1L << 30)
#define QCOM_ICE_KEYS_RAM_RESET_COMPLETED (1L << 31)
#define QCOM_ICE_SEC_IRQ_MASK \
(QCOM_ICE_STREAM1_PARTIALLY_SET_KEY_USED |\
QCOM_ICE_STREAM2_PARTIALLY_SET_KEY_USED |\
QCOM_ICE_QCOMC_DBG_OPEN_EVENT | \
QCOM_ICE_KEYS_RAM_RESET_COMPLETED)
#define qcom_ice_writel(ice, val, reg) \
writel_relaxed((val), (ice)->mmio + (reg))
#define qcom_ice_readl(ice, reg) \
readl_relaxed((ice)->mmio + (reg))
#endif /* _QCOM_INLINE_CRYPTO_ENGINE_REGS_H_ */

File diff suppressed because it is too large Load Diff

198
drivers/crypto/msm/qce.h Normal file
View File

@@ -0,0 +1,198 @@
/*
* QTI Crypto Engine driver API
*
* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __CRYPTO_MSM_QCE_H
#define __CRYPTO_MSM_QCE_H
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/crypto.h>
#include <crypto/algapi.h>
#include <crypto/aes.h>
#include <crypto/des.h>
#include <crypto/sha.h>
#include <crypto/aead.h>
#include <crypto/authenc.h>
#include <crypto/scatterwalk.h>
/* SHA digest size in bytes */
#define SHA256_DIGESTSIZE 32
#define SHA1_DIGESTSIZE 20
#define AES_CE_BLOCK_SIZE 16
/* key size in bytes */
#define HMAC_KEY_SIZE (SHA1_DIGESTSIZE) /* hmac-sha1 */
#define SHA_HMAC_KEY_SIZE 64
#define DES_KEY_SIZE 8
#define TRIPLE_DES_KEY_SIZE 24
#define AES128_KEY_SIZE 16
#define AES192_KEY_SIZE 24
#define AES256_KEY_SIZE 32
#define MAX_CIPHER_KEY_SIZE AES256_KEY_SIZE
/* iv length in bytes */
#define AES_IV_LENGTH 16
#define DES_IV_LENGTH 8
#define MAX_IV_LENGTH AES_IV_LENGTH
/* Maximum number of bytes per transfer */
#define QCE_MAX_OPER_DATA 0xFF00
/* Maximum Nonce bytes */
#define MAX_NONCE 16
/* Crypto clock control flags */
#define QCE_CLK_ENABLE_FIRST 1
#define QCE_BW_REQUEST_FIRST 2
#define QCE_CLK_DISABLE_FIRST 3
#define QCE_BW_REQUEST_RESET_FIRST 4
typedef void (*qce_comp_func_ptr_t)(void *areq,
unsigned char *icv, unsigned char *iv, int ret);
/* Cipher algorithms supported */
enum qce_cipher_alg_enum {
CIPHER_ALG_DES = 0,
CIPHER_ALG_3DES = 1,
CIPHER_ALG_AES = 2,
CIPHER_ALG_LAST
};
/* Hash and hmac algorithms supported */
enum qce_hash_alg_enum {
QCE_HASH_SHA1 = 0,
QCE_HASH_SHA256 = 1,
QCE_HASH_SHA1_HMAC = 2,
QCE_HASH_SHA256_HMAC = 3,
QCE_HASH_AES_CMAC = 4,
QCE_HASH_LAST
};
/* Cipher encryption/decryption operations */
enum qce_cipher_dir_enum {
QCE_ENCRYPT = 0,
QCE_DECRYPT = 1,
QCE_CIPHER_DIR_LAST
};
/* Cipher algorithms modes */
enum qce_cipher_mode_enum {
QCE_MODE_CBC = 0,
QCE_MODE_ECB = 1,
QCE_MODE_CTR = 2,
QCE_MODE_XTS = 3,
QCE_MODE_CCM = 4,
QCE_CIPHER_MODE_LAST
};
/* Cipher operation type */
enum qce_req_op_enum {
QCE_REQ_ABLK_CIPHER = 0,
QCE_REQ_ABLK_CIPHER_NO_KEY = 1,
QCE_REQ_AEAD = 2,
QCE_REQ_LAST
};
/* Algorithms/features supported in CE HW engine */
struct ce_hw_support {
bool sha1_hmac_20; /* Supports 20 bytes of HMAC key*/
bool sha1_hmac; /* supports max HMAC key of 64 bytes*/
bool sha256_hmac; /* supports max HMAC key of 64 bytes*/
bool sha_hmac; /* supports SHA1 and SHA256 MAX HMAC key of 64 bytes*/
bool cmac;
bool aes_key_192;
bool aes_xts;
bool aes_ccm;
bool ota;
bool aligned_only;
bool bam;
bool is_shared;
bool hw_key;
bool use_sw_aes_cbc_ecb_ctr_algo;
bool use_sw_aead_algo;
bool use_sw_aes_xts_algo;
bool use_sw_ahash_algo;
bool use_sw_hmac_algo;
bool use_sw_aes_ccm_algo;
bool clk_mgmt_sus_res;
bool req_bw_before_clk;
unsigned int ce_device;
unsigned int ce_hw_instance;
unsigned int max_request;
};
/* Sha operation parameters */
struct qce_sha_req {
qce_comp_func_ptr_t qce_cb; /* call back */
enum qce_hash_alg_enum alg; /* sha algorithm */
unsigned char *digest; /* sha digest */
struct scatterlist *src; /* pointer to scatter list entry */
uint32_t auth_data[4]; /* byte count */
unsigned char *authkey; /* auth key */
unsigned int authklen; /* auth key length */
bool first_blk; /* first block indicator */
bool last_blk; /* last block indicator */
unsigned int size; /* data length in bytes */
void *areq;
unsigned int flags;
};
struct qce_req {
enum qce_req_op_enum op; /* operation type */
qce_comp_func_ptr_t qce_cb; /* call back */
void *areq;
enum qce_cipher_alg_enum alg; /* cipher algorithms*/
enum qce_cipher_dir_enum dir; /* encryption? decryption? */
enum qce_cipher_mode_enum mode; /* algorithm mode */
enum qce_hash_alg_enum auth_alg;/* authentication algorithm for aead */
unsigned char *authkey; /* authentication key */
unsigned int authklen; /* authentication key kength */
unsigned int authsize; /* authentication key kength */
unsigned char nonce[MAX_NONCE];/* nonce for ccm mode */
unsigned char *assoc; /* Ptr to formatted associated data */
unsigned int assoclen; /* Formatted associated data length */
struct scatterlist *asg; /* Formatted associated data sg */
unsigned char *enckey; /* cipher key */
unsigned int encklen; /* cipher key length */
unsigned char *iv; /* initialization vector */
unsigned int ivsize; /* initialization vector size*/
unsigned int cryptlen; /* data length */
unsigned int use_pmem; /* is source of data PMEM allocated? */
struct qcedev_pmem_info *pmem; /* pointer to pmem_info structure*/
unsigned int flags;
};
struct qce_pm_table {
int (*suspend)(void *handle);
int (*resume)(void *handle);
};
extern struct qce_pm_table qce_pm_table;
void *qce_open(struct platform_device *pdev, int *rc);
int qce_close(void *handle);
int qce_aead_req(void *handle, struct qce_req *req);
int qce_ablk_cipher_req(void *handle, struct qce_req *req);
int qce_hw_support(void *handle, struct ce_hw_support *support);
int qce_process_sha_req(void *handle, struct qce_sha_req *s_req);
int qce_enable_clk(void *handle);
int qce_disable_clk(void *handle);
void qce_get_driver_stats(void *handle);
void qce_clear_driver_stats(void *handle);
#endif /* __CRYPTO_MSM_QCE_H */

6217
drivers/crypto/msm/qce50.c Normal file

File diff suppressed because it is too large Load Diff

245
drivers/crypto/msm/qce50.h Normal file
View File

@@ -0,0 +1,245 @@
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _DRIVERS_CRYPTO_MSM_QCE50_H_
#define _DRIVERS_CRYPTO_MSM_QCE50_H_
#include <linux/msm-sps.h>
/* MAX Data xfer block size between BAM and CE */
#define MAX_CE_BAM_BURST_SIZE 0x40
#define QCEBAM_BURST_SIZE MAX_CE_BAM_BURST_SIZE
#define GET_VIRT_ADDR(x) \
((uintptr_t)pce_dev->coh_vmem + \
((uintptr_t)x - (uintptr_t)pce_dev->coh_pmem))
#define GET_PHYS_ADDR(x) \
(phys_addr_t)(((uintptr_t)pce_dev->coh_pmem + \
((uintptr_t)x - (uintptr_t)pce_dev->coh_vmem)))
#define CRYPTO_REG_SIZE 4
#define NUM_OF_CRYPTO_AUTH_IV_REG 16
#define NUM_OF_CRYPTO_CNTR_IV_REG 4
#define NUM_OF_CRYPTO_AUTH_BYTE_COUNT_REG 4
#define CRYPTO_TOTAL_REGISTERS_DUMPED 26
#define CRYPTO_RESULT_DUMP_SIZE \
ALIGN((CRYPTO_TOTAL_REGISTERS_DUMPED * CRYPTO_REG_SIZE), \
QCEBAM_BURST_SIZE)
/* QCE max number of descriptor in a descriptor list */
#define QCE_MAX_NUM_DESC 128
#define SPS_MAX_PKT_SIZE (32 * 1024 - 64)
/* default bam ipc log level */
#define QCE_BAM_DEFAULT_IPC_LOGLVL 2
/* State of consumer/producer Pipe */
enum qce_pipe_st_enum {
QCE_PIPE_STATE_IDLE = 0,
QCE_PIPE_STATE_IN_PROG = 1,
QCE_PIPE_STATE_COMP = 2,
QCE_PIPE_STATE_LAST
};
enum qce_xfer_type_enum {
QCE_XFER_HASHING,
QCE_XFER_CIPHERING,
QCE_XFER_AEAD,
QCE_XFER_F8,
QCE_XFER_F9,
QCE_XFER_TYPE_LAST
};
struct qce_sps_ep_conn_data {
struct sps_pipe *pipe;
struct sps_connect connect;
struct sps_register_event event;
};
/* CE Result DUMP format*/
struct ce_result_dump_format {
uint32_t auth_iv[NUM_OF_CRYPTO_AUTH_IV_REG];
uint32_t auth_byte_count[NUM_OF_CRYPTO_AUTH_BYTE_COUNT_REG];
uint32_t encr_cntr_iv[NUM_OF_CRYPTO_CNTR_IV_REG];
uint32_t status;
uint32_t status2;
};
struct qce_cmdlist_info {
unsigned long cmdlist;
struct sps_command_element *crypto_cfg;
struct sps_command_element *encr_seg_cfg;
struct sps_command_element *encr_seg_size;
struct sps_command_element *encr_seg_start;
struct sps_command_element *encr_key;
struct sps_command_element *encr_xts_key;
struct sps_command_element *encr_cntr_iv;
struct sps_command_element *encr_ccm_cntr_iv;
struct sps_command_element *encr_mask;
struct sps_command_element *encr_xts_du_size;
struct sps_command_element *auth_seg_cfg;
struct sps_command_element *auth_seg_size;
struct sps_command_element *auth_seg_start;
struct sps_command_element *auth_key;
struct sps_command_element *auth_iv;
struct sps_command_element *auth_nonce_info;
struct sps_command_element *auth_bytecount;
struct sps_command_element *seg_size;
struct sps_command_element *go_proc;
ptrdiff_t size;
};
struct qce_cmdlistptr_ops {
struct qce_cmdlist_info cipher_aes_128_cbc_ctr;
struct qce_cmdlist_info cipher_aes_256_cbc_ctr;
struct qce_cmdlist_info cipher_aes_128_ecb;
struct qce_cmdlist_info cipher_aes_256_ecb;
struct qce_cmdlist_info cipher_aes_128_xts;
struct qce_cmdlist_info cipher_aes_256_xts;
struct qce_cmdlist_info cipher_des_cbc;
struct qce_cmdlist_info cipher_des_ecb;
struct qce_cmdlist_info cipher_3des_cbc;
struct qce_cmdlist_info cipher_3des_ecb;
struct qce_cmdlist_info auth_sha1;
struct qce_cmdlist_info auth_sha256;
struct qce_cmdlist_info auth_sha1_hmac;
struct qce_cmdlist_info auth_sha256_hmac;
struct qce_cmdlist_info auth_aes_128_cmac;
struct qce_cmdlist_info auth_aes_256_cmac;
struct qce_cmdlist_info aead_hmac_sha1_cbc_aes_128;
struct qce_cmdlist_info aead_hmac_sha1_cbc_aes_256;
struct qce_cmdlist_info aead_hmac_sha1_cbc_des;
struct qce_cmdlist_info aead_hmac_sha1_cbc_3des;
struct qce_cmdlist_info aead_hmac_sha256_cbc_aes_128;
struct qce_cmdlist_info aead_hmac_sha256_cbc_aes_256;
struct qce_cmdlist_info aead_hmac_sha256_cbc_des;
struct qce_cmdlist_info aead_hmac_sha256_cbc_3des;
struct qce_cmdlist_info aead_aes_128_ccm;
struct qce_cmdlist_info aead_aes_256_ccm;
struct qce_cmdlist_info cipher_null;
struct qce_cmdlist_info f8_kasumi;
struct qce_cmdlist_info f8_snow3g;
struct qce_cmdlist_info f9_kasumi;
struct qce_cmdlist_info f9_snow3g;
struct qce_cmdlist_info unlock_all_pipes;
};
struct qce_ce_cfg_reg_setting {
uint32_t crypto_cfg_be;
uint32_t crypto_cfg_le;
uint32_t encr_cfg_aes_cbc_128;
uint32_t encr_cfg_aes_cbc_256;
uint32_t encr_cfg_aes_ecb_128;
uint32_t encr_cfg_aes_ecb_256;
uint32_t encr_cfg_aes_xts_128;
uint32_t encr_cfg_aes_xts_256;
uint32_t encr_cfg_aes_ctr_128;
uint32_t encr_cfg_aes_ctr_256;
uint32_t encr_cfg_aes_ccm_128;
uint32_t encr_cfg_aes_ccm_256;
uint32_t encr_cfg_des_cbc;
uint32_t encr_cfg_des_ecb;
uint32_t encr_cfg_3des_cbc;
uint32_t encr_cfg_3des_ecb;
uint32_t encr_cfg_kasumi;
uint32_t encr_cfg_snow3g;
uint32_t auth_cfg_cmac_128;
uint32_t auth_cfg_cmac_256;
uint32_t auth_cfg_sha1;
uint32_t auth_cfg_sha256;
uint32_t auth_cfg_hmac_sha1;
uint32_t auth_cfg_hmac_sha256;
uint32_t auth_cfg_aes_ccm_128;
uint32_t auth_cfg_aes_ccm_256;
uint32_t auth_cfg_aead_sha1_hmac;
uint32_t auth_cfg_aead_sha256_hmac;
uint32_t auth_cfg_kasumi;
uint32_t auth_cfg_snow3g;
};
struct ce_bam_info {
uint32_t bam_irq;
uint32_t bam_mem;
void __iomem *bam_iobase;
uint32_t ce_device;
uint32_t ce_hw_instance;
uint32_t bam_ee;
unsigned int pipe_pair_index;
unsigned int src_pipe_index;
unsigned int dest_pipe_index;
unsigned long bam_handle;
int ce_burst_size;
uint32_t minor_version;
struct qce_sps_ep_conn_data producer;
struct qce_sps_ep_conn_data consumer;
};
/* SPS data structure with buffers, commandlists & commmand pointer lists */
struct ce_sps_data {
enum qce_pipe_st_enum producer_state; /* Producer pipe state */
int consumer_status; /* consumer pipe status */
int producer_status; /* producer pipe status */
struct sps_transfer in_transfer;
struct sps_transfer out_transfer;
struct qce_cmdlistptr_ops cmdlistptr;
uint32_t result_dump; /* reuslt dump virtual address */
uint32_t result_dump_null;
uint32_t result_dump_phy; /* result dump physical address (32 bits) */
uint32_t result_dump_null_phy;
uint32_t ignore_buffer; /* ignore buffer virtual address */
struct ce_result_dump_format *result; /* ponter to result dump */
struct ce_result_dump_format *result_null;
};
struct ce_request_info {
atomic_t in_use;
bool in_prog;
enum qce_xfer_type_enum xfer_type;
struct ce_sps_data ce_sps;
qce_comp_func_ptr_t qce_cb; /* qce callback function pointer */
void *user;
void *areq;
int assoc_nents;
struct scatterlist *asg; /* Formatted associated data sg */
int src_nents;
int dst_nents;
dma_addr_t phy_iv_in;
unsigned char dec_iv[16];
int dir;
enum qce_cipher_mode_enum mode;
dma_addr_t phy_ota_src;
dma_addr_t phy_ota_dst;
unsigned int ota_size;
unsigned int req_len;
};
struct qce_driver_stats {
int no_of_timeouts;
int no_of_dummy_reqs;
int current_mode;
int outstanding_reqs;
};
#endif /* _DRIVERS_CRYPTO_MSM_QCE50_H */

View File

@@ -0,0 +1,30 @@
/* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/* QTI Crypto Engine driver OTA APIi */
#ifndef __CRYPTO_MSM_QCE_OTA_H
#define __CRYPTO_MSM_QCE_OTA_H
#include <linux/platform_device.h>
#include <linux/qcota.h>
int qce_f8_req(void *handle, struct qce_f8_req *req,
void *cookie, qce_comp_func_ptr_t qce_cb);
int qce_f8_multi_pkt_req(void *handle, struct qce_f8_multi_pkt_req *req,
void *cookie, qce_comp_func_ptr_t qce_cb);
int qce_f9_req(void *handle, struct qce_f9_req *req,
void *cookie, qce_comp_func_ptr_t qce_cb);
#endif /* __CRYPTO_MSM_QCE_OTA_H */

2187
drivers/crypto/msm/qcedev.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,127 @@
/* QTI crypto Driver
*
* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __CRYPTO_MSM_QCEDEVI_H
#define __CRYPTO_MSM_QCEDEVI_H
#include <linux/interrupt.h>
#include <linux/cdev.h>
#include <crypto/hash.h>
#include <linux/platform_data/qcom_crypto_device.h>
#include <linux/fips_status.h>
#include "qce.h"
#define CACHE_LINE_SIZE 32
#define CE_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE
enum qcedev_crypto_oper_type {
QCEDEV_CRYPTO_OPER_CIPHER = 0,
QCEDEV_CRYPTO_OPER_SHA = 1,
QCEDEV_CRYPTO_OPER_LAST
};
struct qcedev_handle;
struct qcedev_cipher_req {
struct ablkcipher_request creq;
void *cookie;
};
struct qcedev_sha_req {
struct ahash_request sreq;
void *cookie;
};
struct qcedev_sha_ctxt {
uint32_t auth_data[4];
uint8_t digest[QCEDEV_MAX_SHA_DIGEST];
uint32_t diglen;
uint8_t trailing_buf[64];
uint32_t trailing_buf_len;
uint8_t first_blk;
uint8_t last_blk;
uint8_t authkey[QCEDEV_MAX_SHA_BLOCK_SIZE];
bool init_done;
};
struct qcedev_async_req {
struct list_head list;
struct completion complete;
enum qcedev_crypto_oper_type op_type;
union {
struct qcedev_cipher_op_req cipher_op_req;
struct qcedev_sha_op_req sha_op_req;
};
union {
struct qcedev_cipher_req cipher_req;
struct qcedev_sha_req sha_req;
};
struct qcedev_handle *handle;
int err;
};
/**********************************************************************
* Register ourselves as a char device to be able to access the dev driver
* from userspace.
*/
#define QCEDEV_DEV "qce"
struct qcedev_control {
/* CE features supported by platform */
struct msm_ce_hw_support platform_support;
uint32_t ce_lock_count;
uint32_t high_bw_req_count;
/* CE features/algorithms supported by HW engine*/
struct ce_hw_support ce_support;
uint32_t bus_scale_handle;
/* char device */
struct cdev cdev;
int minor;
/* qce handle */
void *qce;
/* platform device */
struct platform_device *pdev;
unsigned int magic;
struct list_head ready_commands;
struct qcedev_async_req *active_command;
spinlock_t lock;
struct tasklet_struct done_tasklet;
};
struct qcedev_handle {
/* qcedev control handle */
struct qcedev_control *cntl;
/* qce internal sha context*/
struct qcedev_sha_ctxt sha_ctxt;
};
void qcedev_cipher_req_cb(void *cookie, unsigned char *icv,
unsigned char *iv, int ret);
void qcedev_sha_req_cb(void *cookie, unsigned char *digest,
unsigned char *authdata, int ret);
#endif /* __CRYPTO_MSM_QCEDEVI_H */

5585
drivers/crypto/msm/qcrypto.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,528 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _DRIVERS_CRYPTO_MSM_QCRYPTOHW_50_H_
#define _DRIVERS_CRYPTO_MSM_QCRYPTOHW_50_H_
#define CRYPTO_BAM_CNFG_BITS_REG 0x0007C
#define CRYPTO_BAM_CD_ENABLE 27
#define CRYPTO_BAM_CD_ENABLE_MASK (1 << CRYPTO_BAM_CD_ENABLE)
#define QCE_AUTH_REG_BYTE_COUNT 4
#define CRYPTO_VERSION_REG 0x1A000
#define CRYPTO_DATA_IN0_REG 0x1A010
#define CRYPTO_DATA_IN1_REG 0x1A014
#define CRYPTO_DATA_IN2_REG 0x1A018
#define CRYPTO_DATA_IN3_REG 0x1A01C
#define CRYPTO_DATA_OUT0_REG 0x1A020
#define CRYPTO_DATA_OUT1_REG 0x1A024
#define CRYPTO_DATA_OUT2_REG 0x1A028
#define CRYPTO_DATA_OUT3_REG 0x1A02C
#define CRYPTO_STATUS_REG 0x1A100
#define CRYPTO_STATUS2_REG 0x1A104
#define CRYPTO_ENGINES_AVAIL 0x1A108
#define CRYPTO_FIFO_SIZES_REG 0x1A10C
#define CRYPTO_SEG_SIZE_REG 0x1A110
#define CRYPTO_GOPROC_REG 0x1A120
#define CRYPTO_GOPROC_QC_KEY_REG 0x1B000
#define CRYPTO_GOPROC_OEM_KEY_REG 0x1C000
#define CRYPTO_ENCR_SEG_CFG_REG 0x1A200
#define CRYPTO_ENCR_SEG_SIZE_REG 0x1A204
#define CRYPTO_ENCR_SEG_START_REG 0x1A208
#define CRYPTO_ENCR_KEY0_REG 0x1D000
#define CRYPTO_ENCR_KEY1_REG 0x1D004
#define CRYPTO_ENCR_KEY2_REG 0x1D008
#define CRYPTO_ENCR_KEY3_REG 0x1D00C
#define CRYPTO_ENCR_KEY4_REG 0x1D010
#define CRYPTO_ENCR_KEY5_REG 0x1D014
#define CRYPTO_ENCR_KEY6_REG 0x1D018
#define CRYPTO_ENCR_KEY7_REG 0x1D01C
#define CRYPTO_ENCR_XTS_KEY0_REG 0x1D020
#define CRYPTO_ENCR_XTS_KEY1_REG 0x1D024
#define CRYPTO_ENCR_XTS_KEY2_REG 0x1D028
#define CRYPTO_ENCR_XTS_KEY3_REG 0x1D02C
#define CRYPTO_ENCR_XTS_KEY4_REG 0x1D030
#define CRYPTO_ENCR_XTS_KEY5_REG 0x1D034
#define CRYPTO_ENCR_XTS_KEY6_REG 0x1D038
#define CRYPTO_ENCR_XTS_KEY7_REG 0x1D03C
#define CRYPTO_ENCR_PIPE0_KEY0_REG 0x1E000
#define CRYPTO_ENCR_PIPE0_KEY1_REG 0x1E004
#define CRYPTO_ENCR_PIPE0_KEY2_REG 0x1E008
#define CRYPTO_ENCR_PIPE0_KEY3_REG 0x1E00C
#define CRYPTO_ENCR_PIPE0_KEY4_REG 0x1E010
#define CRYPTO_ENCR_PIPE0_KEY5_REG 0x1E014
#define CRYPTO_ENCR_PIPE0_KEY6_REG 0x1E018
#define CRYPTO_ENCR_PIPE0_KEY7_REG 0x1E01C
#define CRYPTO_ENCR_PIPE1_KEY0_REG 0x1E020
#define CRYPTO_ENCR_PIPE1_KEY1_REG 0x1E024
#define CRYPTO_ENCR_PIPE1_KEY2_REG 0x1E028
#define CRYPTO_ENCR_PIPE1_KEY3_REG 0x1E02C
#define CRYPTO_ENCR_PIPE1_KEY4_REG 0x1E030
#define CRYPTO_ENCR_PIPE1_KEY5_REG 0x1E034
#define CRYPTO_ENCR_PIPE1_KEY6_REG 0x1E038
#define CRYPTO_ENCR_PIPE1_KEY7_REG 0x1E03C
#define CRYPTO_ENCR_PIPE2_KEY0_REG 0x1E040
#define CRYPTO_ENCR_PIPE2_KEY1_REG 0x1E044
#define CRYPTO_ENCR_PIPE2_KEY2_REG 0x1E048
#define CRYPTO_ENCR_PIPE2_KEY3_REG 0x1E04C
#define CRYPTO_ENCR_PIPE2_KEY4_REG 0x1E050
#define CRYPTO_ENCR_PIPE2_KEY5_REG 0x1E054
#define CRYPTO_ENCR_PIPE2_KEY6_REG 0x1E058
#define CRYPTO_ENCR_PIPE2_KEY7_REG 0x1E05C
#define CRYPTO_ENCR_PIPE3_KEY0_REG 0x1E060
#define CRYPTO_ENCR_PIPE3_KEY1_REG 0x1E064
#define CRYPTO_ENCR_PIPE3_KEY2_REG 0x1E068
#define CRYPTO_ENCR_PIPE3_KEY3_REG 0x1E06C
#define CRYPTO_ENCR_PIPE3_KEY4_REG 0x1E070
#define CRYPTO_ENCR_PIPE3_KEY5_REG 0x1E074
#define CRYPTO_ENCR_PIPE3_KEY6_REG 0x1E078
#define CRYPTO_ENCR_PIPE3_KEY7_REG 0x1E07C
#define CRYPTO_ENCR_PIPE0_XTS_KEY0_REG 0x1E200
#define CRYPTO_ENCR_PIPE0_XTS_KEY1_REG 0x1E204
#define CRYPTO_ENCR_PIPE0_XTS_KEY2_REG 0x1E208
#define CRYPTO_ENCR_PIPE0_XTS_KEY3_REG 0x1E20C
#define CRYPTO_ENCR_PIPE0_XTS_KEY4_REG 0x1E210
#define CRYPTO_ENCR_PIPE0_XTS_KEY5_REG 0x1E214
#define CRYPTO_ENCR_PIPE0_XTS_KEY6_REG 0x1E218
#define CRYPTO_ENCR_PIPE0_XTS_KEY7_REG 0x1E21C
#define CRYPTO_ENCR_PIPE1_XTS_KEY0_REG 0x1E220
#define CRYPTO_ENCR_PIPE1_XTS_KEY1_REG 0x1E224
#define CRYPTO_ENCR_PIPE1_XTS_KEY2_REG 0x1E228
#define CRYPTO_ENCR_PIPE1_XTS_KEY3_REG 0x1E22C
#define CRYPTO_ENCR_PIPE1_XTS_KEY4_REG 0x1E230
#define CRYPTO_ENCR_PIPE1_XTS_KEY5_REG 0x1E234
#define CRYPTO_ENCR_PIPE1_XTS_KEY6_REG 0x1E238
#define CRYPTO_ENCR_PIPE1_XTS_KEY7_REG 0x1E23C
#define CRYPTO_ENCR_PIPE2_XTS_KEY0_REG 0x1E240
#define CRYPTO_ENCR_PIPE2_XTS_KEY1_REG 0x1E244
#define CRYPTO_ENCR_PIPE2_XTS_KEY2_REG 0x1E248
#define CRYPTO_ENCR_PIPE2_XTS_KEY3_REG 0x1E24C
#define CRYPTO_ENCR_PIPE2_XTS_KEY4_REG 0x1E250
#define CRYPTO_ENCR_PIPE2_XTS_KEY5_REG 0x1E254
#define CRYPTO_ENCR_PIPE2_XTS_KEY6_REG 0x1E258
#define CRYPTO_ENCR_PIPE2_XTS_KEY7_REG 0x1E25C
#define CRYPTO_ENCR_PIPE3_XTS_KEY0_REG 0x1E260
#define CRYPTO_ENCR_PIPE3_XTS_KEY1_REG 0x1E264
#define CRYPTO_ENCR_PIPE3_XTS_KEY2_REG 0x1E268
#define CRYPTO_ENCR_PIPE3_XTS_KEY3_REG 0x1E26C
#define CRYPTO_ENCR_PIPE3_XTS_KEY4_REG 0x1E270
#define CRYPTO_ENCR_PIPE3_XTS_KEY5_REG 0x1E274
#define CRYPTO_ENCR_PIPE3_XTS_KEY6_REG 0x1E278
#define CRYPTO_ENCR_PIPE3_XTS_KEY7_REG 0x1E27C
#define CRYPTO_CNTR0_IV0_REG 0x1A20C
#define CRYPTO_CNTR1_IV1_REG 0x1A210
#define CRYPTO_CNTR2_IV2_REG 0x1A214
#define CRYPTO_CNTR3_IV3_REG 0x1A218
#define CRYPTO_CNTR_MASK_REG0 0x1A23C
#define CRYPTO_CNTR_MASK_REG1 0x1A238
#define CRYPTO_CNTR_MASK_REG2 0x1A234
#define CRYPTO_CNTR_MASK_REG 0x1A21C
#define CRYPTO_ENCR_CCM_INT_CNTR0_REG 0x1A220
#define CRYPTO_ENCR_CCM_INT_CNTR1_REG 0x1A224
#define CRYPTO_ENCR_CCM_INT_CNTR2_REG 0x1A228
#define CRYPTO_ENCR_CCM_INT_CNTR3_REG 0x1A22C
#define CRYPTO_ENCR_XTS_DU_SIZE_REG 0x1A230
#define CRYPTO_AUTH_SEG_CFG_REG 0x1A300
#define CRYPTO_AUTH_SEG_SIZE_REG 0x1A304
#define CRYPTO_AUTH_SEG_START_REG 0x1A308
#define CRYPTO_AUTH_KEY0_REG 0x1D040
#define CRYPTO_AUTH_KEY1_REG 0x1D044
#define CRYPTO_AUTH_KEY2_REG 0x1D048
#define CRYPTO_AUTH_KEY3_REG 0x1D04C
#define CRYPTO_AUTH_KEY4_REG 0x1D050
#define CRYPTO_AUTH_KEY5_REG 0x1D054
#define CRYPTO_AUTH_KEY6_REG 0x1D058
#define CRYPTO_AUTH_KEY7_REG 0x1D05C
#define CRYPTO_AUTH_KEY8_REG 0x1D060
#define CRYPTO_AUTH_KEY9_REG 0x1D064
#define CRYPTO_AUTH_KEY10_REG 0x1D068
#define CRYPTO_AUTH_KEY11_REG 0x1D06C
#define CRYPTO_AUTH_KEY12_REG 0x1D070
#define CRYPTO_AUTH_KEY13_REG 0x1D074
#define CRYPTO_AUTH_KEY14_REG 0x1D078
#define CRYPTO_AUTH_KEY15_REG 0x1D07C
#define CRYPTO_AUTH_PIPE0_KEY0_REG 0x1E800
#define CRYPTO_AUTH_PIPE0_KEY1_REG 0x1E804
#define CRYPTO_AUTH_PIPE0_KEY2_REG 0x1E808
#define CRYPTO_AUTH_PIPE0_KEY3_REG 0x1E80C
#define CRYPTO_AUTH_PIPE0_KEY4_REG 0x1E810
#define CRYPTO_AUTH_PIPE0_KEY5_REG 0x1E814
#define CRYPTO_AUTH_PIPE0_KEY6_REG 0x1E818
#define CRYPTO_AUTH_PIPE0_KEY7_REG 0x1E81C
#define CRYPTO_AUTH_PIPE0_KEY8_REG 0x1E820
#define CRYPTO_AUTH_PIPE0_KEY9_REG 0x1E824
#define CRYPTO_AUTH_PIPE0_KEY10_REG 0x1E828
#define CRYPTO_AUTH_PIPE0_KEY11_REG 0x1E82C
#define CRYPTO_AUTH_PIPE0_KEY12_REG 0x1E830
#define CRYPTO_AUTH_PIPE0_KEY13_REG 0x1E834
#define CRYPTO_AUTH_PIPE0_KEY14_REG 0x1E838
#define CRYPTO_AUTH_PIPE0_KEY15_REG 0x1E83C
#define CRYPTO_AUTH_PIPE1_KEY0_REG 0x1E880
#define CRYPTO_AUTH_PIPE1_KEY1_REG 0x1E884
#define CRYPTO_AUTH_PIPE1_KEY2_REG 0x1E888
#define CRYPTO_AUTH_PIPE1_KEY3_REG 0x1E88C
#define CRYPTO_AUTH_PIPE1_KEY4_REG 0x1E890
#define CRYPTO_AUTH_PIPE1_KEY5_REG 0x1E894
#define CRYPTO_AUTH_PIPE1_KEY6_REG 0x1E898
#define CRYPTO_AUTH_PIPE1_KEY7_REG 0x1E89C
#define CRYPTO_AUTH_PIPE1_KEY8_REG 0x1E8A0
#define CRYPTO_AUTH_PIPE1_KEY9_REG 0x1E8A4
#define CRYPTO_AUTH_PIPE1_KEY10_REG 0x1E8A8
#define CRYPTO_AUTH_PIPE1_KEY11_REG 0x1E8AC
#define CRYPTO_AUTH_PIPE1_KEY12_REG 0x1E8B0
#define CRYPTO_AUTH_PIPE1_KEY13_REG 0x1E8B4
#define CRYPTO_AUTH_PIPE1_KEY14_REG 0x1E8B8
#define CRYPTO_AUTH_PIPE1_KEY15_REG 0x1E8BC
#define CRYPTO_AUTH_PIPE2_KEY0_REG 0x1E900
#define CRYPTO_AUTH_PIPE2_KEY1_REG 0x1E904
#define CRYPTO_AUTH_PIPE2_KEY2_REG 0x1E908
#define CRYPTO_AUTH_PIPE2_KEY3_REG 0x1E90C
#define CRYPTO_AUTH_PIPE2_KEY4_REG 0x1E910
#define CRYPTO_AUTH_PIPE2_KEY5_REG 0x1E914
#define CRYPTO_AUTH_PIPE2_KEY6_REG 0x1E918
#define CRYPTO_AUTH_PIPE2_KEY7_REG 0x1E91C
#define CRYPTO_AUTH_PIPE2_KEY8_REG 0x1E920
#define CRYPTO_AUTH_PIPE2_KEY9_REG 0x1E924
#define CRYPTO_AUTH_PIPE2_KEY10_REG 0x1E928
#define CRYPTO_AUTH_PIPE2_KEY11_REG 0x1E92C
#define CRYPTO_AUTH_PIPE2_KEY12_REG 0x1E930
#define CRYPTO_AUTH_PIPE2_KEY13_REG 0x1E934
#define CRYPTO_AUTH_PIPE2_KEY14_REG 0x1E938
#define CRYPTO_AUTH_PIPE2_KEY15_REG 0x1E93C
#define CRYPTO_AUTH_PIPE3_KEY0_REG 0x1E980
#define CRYPTO_AUTH_PIPE3_KEY1_REG 0x1E984
#define CRYPTO_AUTH_PIPE3_KEY2_REG 0x1E988
#define CRYPTO_AUTH_PIPE3_KEY3_REG 0x1E98C
#define CRYPTO_AUTH_PIPE3_KEY4_REG 0x1E990
#define CRYPTO_AUTH_PIPE3_KEY5_REG 0x1E994
#define CRYPTO_AUTH_PIPE3_KEY6_REG 0x1E998
#define CRYPTO_AUTH_PIPE3_KEY7_REG 0x1E99C
#define CRYPTO_AUTH_PIPE3_KEY8_REG 0x1E9A0
#define CRYPTO_AUTH_PIPE3_KEY9_REG 0x1E9A4
#define CRYPTO_AUTH_PIPE3_KEY10_REG 0x1E9A8
#define CRYPTO_AUTH_PIPE3_KEY11_REG 0x1E9AC
#define CRYPTO_AUTH_PIPE3_KEY12_REG 0x1E9B0
#define CRYPTO_AUTH_PIPE3_KEY13_REG 0x1E9B4
#define CRYPTO_AUTH_PIPE3_KEY14_REG 0x1E9B8
#define CRYPTO_AUTH_PIPE3_KEY15_REG 0x1E9BC
#define CRYPTO_AUTH_IV0_REG 0x1A310
#define CRYPTO_AUTH_IV1_REG 0x1A314
#define CRYPTO_AUTH_IV2_REG 0x1A318
#define CRYPTO_AUTH_IV3_REG 0x1A31C
#define CRYPTO_AUTH_IV4_REG 0x1A320
#define CRYPTO_AUTH_IV5_REG 0x1A324
#define CRYPTO_AUTH_IV6_REG 0x1A328
#define CRYPTO_AUTH_IV7_REG 0x1A32C
#define CRYPTO_AUTH_IV8_REG 0x1A330
#define CRYPTO_AUTH_IV9_REG 0x1A334
#define CRYPTO_AUTH_IV10_REG 0x1A338
#define CRYPTO_AUTH_IV11_REG 0x1A33C
#define CRYPTO_AUTH_IV12_REG 0x1A340
#define CRYPTO_AUTH_IV13_REG 0x1A344
#define CRYPTO_AUTH_IV14_REG 0x1A348
#define CRYPTO_AUTH_IV15_REG 0x1A34C
#define CRYPTO_AUTH_INFO_NONCE0_REG 0x1A350
#define CRYPTO_AUTH_INFO_NONCE1_REG 0x1A354
#define CRYPTO_AUTH_INFO_NONCE2_REG 0x1A358
#define CRYPTO_AUTH_INFO_NONCE3_REG 0x1A35C
#define CRYPTO_AUTH_BYTECNT0_REG 0x1A390
#define CRYPTO_AUTH_BYTECNT1_REG 0x1A394
#define CRYPTO_AUTH_BYTECNT2_REG 0x1A398
#define CRYPTO_AUTH_BYTECNT3_REG 0x1A39C
#define CRYPTO_AUTH_EXP_MAC0_REG 0x1A3A0
#define CRYPTO_AUTH_EXP_MAC1_REG 0x1A3A4
#define CRYPTO_AUTH_EXP_MAC2_REG 0x1A3A8
#define CRYPTO_AUTH_EXP_MAC3_REG 0x1A3AC
#define CRYPTO_AUTH_EXP_MAC4_REG 0x1A3B0
#define CRYPTO_AUTH_EXP_MAC5_REG 0x1A3B4
#define CRYPTO_AUTH_EXP_MAC6_REG 0x1A3B8
#define CRYPTO_AUTH_EXP_MAC7_REG 0x1A3BC
#define CRYPTO_CONFIG_REG 0x1A400
#define CRYPTO_DEBUG_ENABLE_REG 0x1AF00
#define CRYPTO_DEBUG_REG 0x1AF04
/* Register bits */
#define CRYPTO_CORE_STEP_REV_MASK 0xFFFF
#define CRYPTO_CORE_STEP_REV 0 /* bit 15-0 */
#define CRYPTO_CORE_MAJOR_REV_MASK 0xFF000000
#define CRYPTO_CORE_MAJOR_REV 24 /* bit 31-24 */
#define CRYPTO_CORE_MINOR_REV_MASK 0xFF0000
#define CRYPTO_CORE_MINOR_REV 16 /* bit 23-16 */
/* status reg */
#define CRYPTO_MAC_FAILED 31
#define CRYPTO_DOUT_SIZE_AVAIL 26 /* bit 30-26 */
#define CRYPTO_DOUT_SIZE_AVAIL_MASK (0x1F << CRYPTO_DOUT_SIZE_AVAIL)
#define CRYPTO_DIN_SIZE_AVAIL 21 /* bit 21-25 */
#define CRYPTO_DIN_SIZE_AVAIL_MASK (0x1F << CRYPTO_DIN_SIZE_AVAIL)
#define CRYPTO_HSD_ERR 20
#define CRYPTO_ACCESS_VIOL 19
#define CRYPTO_PIPE_ACTIVE_ERR 18
#define CRYPTO_CFG_CHNG_ERR 17
#define CRYPTO_DOUT_ERR 16
#define CRYPTO_DIN_ERR 15
#define CRYPTO_AXI_ERR 14
#define CRYPTO_CRYPTO_STATE 10 /* bit 13-10 */
#define CRYPTO_CRYPTO_STATE_MASK (0xF << CRYPTO_CRYPTO_STATE)
#define CRYPTO_ENCR_BUSY 9
#define CRYPTO_AUTH_BUSY 8
#define CRYPTO_DOUT_INTR 7
#define CRYPTO_DIN_INTR 6
#define CRYPTO_OP_DONE_INTR 5
#define CRYPTO_ERR_INTR 4
#define CRYPTO_DOUT_RDY 3
#define CRYPTO_DIN_RDY 2
#define CRYPTO_OPERATION_DONE 1
#define CRYPTO_SW_ERR 0
/* status2 reg */
#define CRYPTO_AXI_EXTRA 1
#define CRYPTO_LOCKED 2
/* config reg */
#define CRYPTO_REQ_SIZE 17 /* bit 20-17 */
#define CRYPTO_REQ_SIZE_MASK (0xF << CRYPTO_REQ_SIZE)
#define CRYPTO_REQ_SIZE_ENUM_1_BEAT 0
#define CRYPTO_REQ_SIZE_ENUM_2_BEAT 1
#define CRYPTO_REQ_SIZE_ENUM_3_BEAT 2
#define CRYPTO_REQ_SIZE_ENUM_4_BEAT 3
#define CRYPTO_REQ_SIZE_ENUM_5_BEAT 4
#define CRYPTO_REQ_SIZE_ENUM_6_BEAT 5
#define CRYPTO_REQ_SIZE_ENUM_7_BEAT 6
#define CRYPTO_REQ_SIZE_ENUM_8_BEAT 7
#define CRYPTO_REQ_SIZE_ENUM_9_BEAT 8
#define CRYPTO_REQ_SIZE_ENUM_10_BEAT 9
#define CRYPTO_REQ_SIZE_ENUM_11_BEAT 10
#define CRYPTO_REQ_SIZE_ENUM_12_BEAT 11
#define CRYPTO_REQ_SIZE_ENUM_13_BEAT 12
#define CRYPTO_REQ_SIZE_ENUM_14_BEAT 13
#define CRYPTO_REQ_SIZE_ENUM_15_BEAT 14
#define CRYPTO_REQ_SIZE_ENUM_16_BEAT 15
#define CRYPTO_MAX_QUEUED_REQ 14 /* bit 16-14 */
#define CRYPTO_MAX_QUEUED_REQ_MASK (0x7 << CRYPTO_MAX_QUEUED_REQ)
#define CRYPTO_ENUM_1_QUEUED_REQS 0
#define CRYPTO_ENUM_2_QUEUED_REQS 1
#define CRYPTO_ENUM_3_QUEUED_REQS 2
#define CRYPTO_IRQ_ENABLES 10 /* bit 13-10 */
#define CRYPTO_IRQ_ENABLES_MASK (0xF << CRYPTO_IRQ_ENABLES)
#define CRYPTO_LITTLE_ENDIAN_MODE 9
#define CRYPTO_LITTLE_ENDIAN_MASK (1 << CRYPTO_LITTLE_ENDIAN_MODE)
#define CRYPTO_PIPE_SET_SELECT 5 /* bit 8-5 */
#define CRYPTO_PIPE_SET_SELECT_MASK (0xF << CRYPTO_PIPE_SET_SELECT)
#define CRYPTO_HIGH_SPD_EN_N 4
#define CRYPTO_MASK_DOUT_INTR 3
#define CRYPTO_MASK_DIN_INTR 2
#define CRYPTO_MASK_OP_DONE_INTR 1
#define CRYPTO_MASK_ERR_INTR 0
/* auth_seg_cfg reg */
#define CRYPTO_COMP_EXP_MAC 24
#define CRYPTO_COMP_EXP_MAC_DISABLED 0
#define CRYPTO_COMP_EXP_MAC_ENABLED 1
#define CRYPTO_F9_DIRECTION 23
#define CRYPTO_F9_DIRECTION_UPLINK 0
#define CRYPTO_F9_DIRECTION_DOWNLINK 1
#define CRYPTO_AUTH_NONCE_NUM_WORDS 20 /* bit 22-20 */
#define CRYPTO_AUTH_NONCE_NUM_WORDS_MASK \
(0x7 << CRYPTO_AUTH_NONCE_NUM_WORDS)
#define CRYPTO_USE_PIPE_KEY_AUTH 19
#define CRYPTO_USE_HW_KEY_AUTH 18
#define CRYPTO_FIRST 17
#define CRYPTO_LAST 16
#define CRYPTO_AUTH_POS 14 /* bit 15 .. 14*/
#define CRYPTO_AUTH_POS_MASK (0x3 << CRYPTO_AUTH_POS)
#define CRYPTO_AUTH_POS_BEFORE 0
#define CRYPTO_AUTH_POS_AFTER 1
#define CRYPTO_AUTH_SIZE 9 /* bits 13 .. 9*/
#define CRYPTO_AUTH_SIZE_MASK (0x1F << CRYPTO_AUTH_SIZE)
#define CRYPTO_AUTH_SIZE_SHA1 0
#define CRYPTO_AUTH_SIZE_SHA256 1
#define CRYPTO_AUTH_SIZE_ENUM_1_BYTES 0
#define CRYPTO_AUTH_SIZE_ENUM_2_BYTES 1
#define CRYPTO_AUTH_SIZE_ENUM_3_BYTES 2
#define CRYPTO_AUTH_SIZE_ENUM_4_BYTES 3
#define CRYPTO_AUTH_SIZE_ENUM_5_BYTES 4
#define CRYPTO_AUTH_SIZE_ENUM_6_BYTES 5
#define CRYPTO_AUTH_SIZE_ENUM_7_BYTES 6
#define CRYPTO_AUTH_SIZE_ENUM_8_BYTES 7
#define CRYPTO_AUTH_SIZE_ENUM_9_BYTES 8
#define CRYPTO_AUTH_SIZE_ENUM_10_BYTES 9
#define CRYPTO_AUTH_SIZE_ENUM_11_BYTES 10
#define CRYPTO_AUTH_SIZE_ENUM_12_BYTES 11
#define CRYPTO_AUTH_SIZE_ENUM_13_BYTES 12
#define CRYPTO_AUTH_SIZE_ENUM_14_BYTES 13
#define CRYPTO_AUTH_SIZE_ENUM_15_BYTES 14
#define CRYPTO_AUTH_SIZE_ENUM_16_BYTES 15
#define CRYPTO_AUTH_MODE 6 /* bit 8 .. 6*/
#define CRYPTO_AUTH_MODE_MASK (0x7 << CRYPTO_AUTH_MODE)
#define CRYPTO_AUTH_MODE_HASH 0
#define CRYPTO_AUTH_MODE_HMAC 1
#define CRYPTO_AUTH_MODE_CCM 0
#define CRYPTO_AUTH_MODE_CMAC 1
#define CRYPTO_AUTH_KEY_SIZE 3 /* bit 5 .. 3*/
#define CRYPTO_AUTH_KEY_SIZE_MASK (0x7 << CRYPTO_AUTH_KEY_SIZE)
#define CRYPTO_AUTH_KEY_SZ_AES128 0
#define CRYPTO_AUTH_KEY_SZ_AES256 2
#define CRYPTO_AUTH_ALG 0 /* bit 2 .. 0*/
#define CRYPTO_AUTH_ALG_MASK 7
#define CRYPTO_AUTH_ALG_NONE 0
#define CRYPTO_AUTH_ALG_SHA 1
#define CRYPTO_AUTH_ALG_AES 2
#define CRYPTO_AUTH_ALG_KASUMI 3
#define CRYPTO_AUTH_ALG_SNOW3G 4
#define CRYPTO_AUTH_ALG_ZUC 5
/* encr_xts_du_size reg */
#define CRYPTO_ENCR_XTS_DU_SIZE 0 /* bit 19-0 */
#define CRYPTO_ENCR_XTS_DU_SIZE_MASK 0xfffff
/* encr_seg_cfg reg */
#define CRYPTO_F8_KEYSTREAM_ENABLE 17/* bit */
#define CRYPTO_F8_KEYSTREAM_DISABLED 0
#define CRYPTO_F8_KEYSTREAM_ENABLED 1
#define CRYPTO_F8_DIRECTION 16 /* bit */
#define CRYPTO_F8_DIRECTION_UPLINK 0
#define CRYPTO_F8_DIRECTION_DOWNLINK 1
#define CRYPTO_USE_PIPE_KEY_ENCR 15 /* bit */
#define CRYPTO_USE_PIPE_KEY_ENCR_ENABLED 1
#define CRYPTO_USE_KEY_REGISTERS 0
#define CRYPTO_USE_HW_KEY_ENCR 14
#define CRYPTO_USE_KEY_REG 0
#define CRYPTO_USE_HW_KEY 1
#define CRYPTO_LAST_CCM 13
#define CRYPTO_LAST_CCM_XFR 1
#define CRYPTO_INTERM_CCM_XFR 0
#define CRYPTO_CNTR_ALG 11 /* bit 12-11 */
#define CRYPTO_CNTR_ALG_MASK (3 << CRYPTO_CNTR_ALG)
#define CRYPTO_CNTR_ALG_NIST 0
#define CRYPTO_ENCODE 10
#define CRYPTO_ENCR_MODE 6 /* bit 9-6 */
#define CRYPTO_ENCR_MODE_MASK (0xF << CRYPTO_ENCR_MODE)
/* only valid when AES */
#define CRYPTO_ENCR_MODE_ECB 0
#define CRYPTO_ENCR_MODE_CBC 1
#define CRYPTO_ENCR_MODE_CTR 2
#define CRYPTO_ENCR_MODE_XTS 3
#define CRYPTO_ENCR_MODE_CCM 4
#define CRYPTO_ENCR_KEY_SZ 3 /* bit 5-3 */
#define CRYPTO_ENCR_KEY_SZ_MASK (7 << CRYPTO_ENCR_KEY_SZ)
#define CRYPTO_ENCR_KEY_SZ_DES 0
#define CRYPTO_ENCR_KEY_SZ_3DES 1
#define CRYPTO_ENCR_KEY_SZ_AES128 0
#define CRYPTO_ENCR_KEY_SZ_AES256 2
#define CRYPTO_ENCR_ALG 0 /* bit 2-0 */
#define CRYPTO_ENCR_ALG_MASK (7 << CRYPTO_ENCR_ALG)
#define CRYPTO_ENCR_ALG_NONE 0
#define CRYPTO_ENCR_ALG_DES 1
#define CRYPTO_ENCR_ALG_AES 2
#define CRYPTO_ENCR_ALG_KASUMI 4
#define CRYPTO_ENCR_ALG_SNOW_3G 5
#define CRYPTO_ENCR_ALG_ZUC 6
/* goproc reg */
#define CRYPTO_GO 0
#define CRYPTO_CLR_CNTXT 1
#define CRYPTO_RESULTS_DUMP 2
/* F8 definition of CRYPTO_ENCR_CNTR1_IV1 REG */
#define CRYPTO_CNTR1_IV1_REG_F8_PKT_CNT 16 /* bit 31 - 16 */
#define CRYPTO_CNTR1_IV1_REG_F8_PKT_CNT_MASK \
(0xffff << CRYPTO_CNTR1_IV1_REG_F8_PKT_CNT)
#define CRYPTO_CNTR1_IV1_REG_F8_BEARER 0 /* bit 4 - 0 */
#define CRYPTO_CNTR1_IV1_REG_F8_BEARER_MASK \
(0x1f << CRYPTO_CNTR1_IV1_REG_F8_BEARER)
/* F9 definition of CRYPTO_AUTH_IV4 REG */
#define CRYPTO_AUTH_IV4_REG_F9_VALID_BIS 0 /* bit 2 - 0 */
#define CRYPTO_AUTH_IV4_REG_F9_VALID_BIS_MASK \
(0x7 << CRYPTO_AUTH_IV4_REG_F9_VALID_BIS)
/* engines_avail */
#define CRYPTO_ENCR_AES_SEL 0
#define CRYPTO_DES_SEL 1
#define CRYPTO_ENCR_SNOW3G_SEL 2
#define CRYPTO_ENCR_KASUMI_SEL 3
#define CRYPTO_SHA_SEL 4
#define CRYPTO_SHA512_SEL 5
#define CRYPTO_AUTH_AES_SEL 6
#define CRYPTO_AUTH_SNOW3G_SEL 7
#define CRYPTO_AUTH_KASUMI_SEL 8
#define CRYPTO_BAM_PIPE_SETS 9 /* bit 12 - 9 */
#define CRYPTO_AXI_WR_BEATS 13 /* bit 18 - 13 */
#define CRYPTO_AXI_RD_BEATS 19 /* bit 24 - 19 */
#define CRYPTO_ENCR_ZUC_SEL 26
#define CRYPTO_AUTH_ZUC_SEL 27
#define CRYPTO_ZUC_ENABLE 28
#endif /* _DRIVERS_CRYPTO_MSM_QCRYPTOHW_50_H_ */

View File

@@ -0,0 +1,24 @@
/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __QCOM_CRYPTO_DEVICE__H
#define __QCOM_CRYPTO_DEVICE__H
struct msm_ce_hw_support {
uint32_t ce_shared;
uint32_t shared_ce_resource;
uint32_t hw_key_support;
uint32_t sha_hmac;
void *bus_scale_table;
};
#endif /* __QCOM_CRYPTO_DEVICE__H */

66
include/linux/qcrypto.h Normal file
View File

@@ -0,0 +1,66 @@
/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _DRIVERS_CRYPTO_MSM_QCRYPTO_H_
#define _DRIVERS_CRYPTO_MSM_QCRYPTO_H_
#include <linux/crypto.h>
#include <crypto/hash.h>
#include <crypto/skcipher.h>
#define QCRYPTO_CTX_KEY_MASK 0x000000ff
#define QCRYPTO_CTX_USE_HW_KEY 0x00000001
#define QCRYPTO_CTX_USE_PIPE_KEY 0x00000002
#define QCRYPTO_CTX_XTS_MASK 0x0000ff00
#define QCRYPTO_CTX_XTS_DU_SIZE_512B 0x00000100
#define QCRYPTO_CTX_XTS_DU_SIZE_1KB 0x00000200
int qcrypto_cipher_set_device(struct ablkcipher_request *req, unsigned int dev);
int qcrypto_ahash_set_device(struct ahash_request *req, unsigned int dev);
/*int qcrypto_aead_set_device(struct aead_request *req, unsigned int dev);*/
int qcrypto_cipher_set_flag(struct skcipher_request *req, unsigned int flags);
int qcrypto_ahash_set_flag(struct ahash_request *req, unsigned int flags);
/*int qcrypto_aead_set_flag(struct aead_request *req, unsigned int flags);*/
int qcrypto_cipher_clear_flag(struct ablkcipher_request *req,
unsigned int flags);
int qcrypto_ahash_clear_flag(struct ahash_request *req, unsigned int flags);
/*int qcrypto_aead_clear_flag(struct aead_request *req, unsigned int flags);*/
struct crypto_engine_entry {
u32 hw_instance;
u32 ce_device;
int shared;
};
int qcrypto_get_num_engines(void);
void qcrypto_get_engine_list(size_t num_engines,
struct crypto_engine_entry *arr);
int qcrypto_cipher_set_device_hw(struct skcipher_request *req,
unsigned int fde_pfe,
unsigned int hw_inst);
struct qcrypto_func_set {
int (*cipher_set)(struct skcipher_request *req,
unsigned int fde_pfe,
unsigned int hw_inst);
int (*cipher_flag)(struct skcipher_request *req, unsigned int flags);
int (*get_num_engines)(void);
void (*get_engine_list)(size_t num_engines,
struct crypto_engine_entry *arr);
};
#endif /* _DRIVERS_CRYPTO_MSM_QCRYPTO_H */

View File

@@ -0,0 +1,33 @@
#ifndef _UAPI_FIPS_STATUS__H
#define _UAPI_FIPS_STATUS__H
#include <linux/types.h>
#include <linux/ioctl.h>
/**
* fips_status: global FIPS140-2 status
* @FIPS140_STATUS_NA:
* Not a FIPS140-2 compliant Build.
* The flag status won't
* change throughout
* the lifetime
* @FIPS140_STATUS_PASS_CRYPTO:
* KAT self tests are passed.
* @FIPS140_STATUS_QCRYPTO_ALLOWED:
* Integrity test is passed.
* @FIPS140_STATUS_PASS:
* All tests are passed and build
* is in FIPS140-2 mode
* @FIPS140_STATUS_FAIL:
* One of the test is failed.
* This will block all requests
* to crypto modules
*/
enum fips_status {
FIPS140_STATUS_NA = 0,
FIPS140_STATUS_PASS_CRYPTO = 1,
FIPS140_STATUS_QCRYPTO_ALLOWED = 2,
FIPS140_STATUS_PASS = 3,
FIPS140_STATUS_FAIL = 0xFF
};
#endif /* _UAPI_FIPS_STATUS__H */

257
include/uapi/linux/qcedev.h Normal file
View File

@@ -0,0 +1,257 @@
#ifndef _UAPI_QCEDEV__H
#define _UAPI_QCEDEV__H
#include <linux/types.h>
#include <linux/ioctl.h>
#include "fips_status.h"
#define QCEDEV_MAX_SHA_BLOCK_SIZE 64
#define QCEDEV_MAX_BEARER 31
#define QCEDEV_MAX_KEY_SIZE 64
#define QCEDEV_MAX_IV_SIZE 32
#define QCEDEV_MAX_BUFFERS 16
#define QCEDEV_MAX_SHA_DIGEST 32
#define QCEDEV_USE_PMEM 1
#define QCEDEV_NO_PMEM 0
#define QCEDEV_AES_KEY_128 16
#define QCEDEV_AES_KEY_192 24
#define QCEDEV_AES_KEY_256 32
/**
*qcedev_oper_enum: Operation types
* @QCEDEV_OPER_ENC: Encrypt
* @QCEDEV_OPER_DEC: Decrypt
* @QCEDEV_OPER_ENC_NO_KEY: Encrypt. Do not need key to be specified by
* user. Key already set by an external processor.
* @QCEDEV_OPER_DEC_NO_KEY: Decrypt. Do not need the key to be specified by
* user. Key already set by an external processor.
*/
enum qcedev_oper_enum {
QCEDEV_OPER_DEC = 0,
QCEDEV_OPER_ENC = 1,
QCEDEV_OPER_DEC_NO_KEY = 2,
QCEDEV_OPER_ENC_NO_KEY = 3,
QCEDEV_OPER_LAST
};
/**
*qcedev_oper_enum: Cipher algorithm types
* @QCEDEV_ALG_DES: DES
* @QCEDEV_ALG_3DES: 3DES
* @QCEDEV_ALG_AES: AES
*/
enum qcedev_cipher_alg_enum {
QCEDEV_ALG_DES = 0,
QCEDEV_ALG_3DES = 1,
QCEDEV_ALG_AES = 2,
QCEDEV_ALG_LAST
};
/**
*qcedev_cipher_mode_enum : AES mode
* @QCEDEV_AES_MODE_CBC: CBC
* @QCEDEV_AES_MODE_ECB: ECB
* @QCEDEV_AES_MODE_CTR: CTR
* @QCEDEV_AES_MODE_XTS: XTS
* @QCEDEV_AES_MODE_CCM: CCM
* @QCEDEV_DES_MODE_CBC: CBC
* @QCEDEV_DES_MODE_ECB: ECB
*/
enum qcedev_cipher_mode_enum {
QCEDEV_AES_MODE_CBC = 0,
QCEDEV_AES_MODE_ECB = 1,
QCEDEV_AES_MODE_CTR = 2,
QCEDEV_AES_MODE_XTS = 3,
QCEDEV_AES_MODE_CCM = 4,
QCEDEV_DES_MODE_CBC = 5,
QCEDEV_DES_MODE_ECB = 6,
QCEDEV_AES_DES_MODE_LAST
};
/**
*enum qcedev_sha_alg_enum : Secure Hashing Algorithm
* @QCEDEV_ALG_SHA1: Digest returned: 20 bytes (160 bits)
* @QCEDEV_ALG_SHA256: Digest returned: 32 bytes (256 bit)
* @QCEDEV_ALG_SHA1_HMAC: HMAC returned 20 bytes (160 bits)
* @QCEDEV_ALG_SHA256_HMAC: HMAC returned 32 bytes (256 bit)
* @QCEDEV_ALG_AES_CMAC: Configurable MAC size
*/
enum qcedev_sha_alg_enum {
QCEDEV_ALG_SHA1 = 0,
QCEDEV_ALG_SHA256 = 1,
QCEDEV_ALG_SHA1_HMAC = 2,
QCEDEV_ALG_SHA256_HMAC = 3,
QCEDEV_ALG_AES_CMAC = 4,
QCEDEV_ALG_SHA_ALG_LAST
};
/**
* struct buf_info - Buffer information
* @offset: Offset from the base address of the buffer
* (Used when buffer is allocated using PMEM)
* @vaddr: Virtual buffer address pointer
* @len: Size of the buffer
*/
struct buf_info {
union {
uint32_t offset;
uint8_t *vaddr;
};
uint32_t len;
};
/**
* struct qcedev_vbuf_info - Source and destination Buffer information
* @src: Array of buf_info for input/source
* @dst: Array of buf_info for output/destination
*/
struct qcedev_vbuf_info {
struct buf_info src[QCEDEV_MAX_BUFFERS];
struct buf_info dst[QCEDEV_MAX_BUFFERS];
};
/**
* struct qcedev_pmem_info - Stores PMEM buffer information
* @fd_src: Handle to /dev/adsp_pmem used to allocate
* memory for input/src buffer
* @src: Array of buf_info for input/source
* @fd_dst: Handle to /dev/adsp_pmem used to allocate
* memory for output/dst buffer
* @dst: Array of buf_info for output/destination
* @pmem_src_offset: The offset from input/src buffer
* (allocated by PMEM)
*/
struct qcedev_pmem_info {
int fd_src;
struct buf_info src[QCEDEV_MAX_BUFFERS];
int fd_dst;
struct buf_info dst[QCEDEV_MAX_BUFFERS];
};
/**
* struct qcedev_cipher_op_req - Holds the ciphering request information
* @use_pmem (IN): Flag to indicate if buffer source is PMEM
* QCEDEV_USE_PMEM/QCEDEV_NO_PMEM
* @pmem (IN): Stores PMEM buffer information.
* Refer struct qcedev_pmem_info
* @vbuf (IN/OUT): Stores Source and destination Buffer information
* Refer to struct qcedev_vbuf_info
* @data_len (IN): Total Length of input/src and output/dst in bytes
* @in_place_op (IN): Indicates whether the operation is inplace where
* source == destination
* When using PMEM allocated memory, must set this to 1
* @enckey (IN): 128 bits of confidentiality key
* enckey[0] bit 127-120, enckey[1] bit 119-112,..
* enckey[15] bit 7-0
* @encklen (IN): Length of the encryption key(set to 128 bits/16
* bytes in the driver)
* @iv (IN/OUT): Initialisation vector data
* This is updated by the driver, incremented by
* number of blocks encrypted/decrypted.
* @ivlen (IN): Length of the IV
* @byteoffset (IN): Offset in the Cipher BLOCK (applicable and to be set
* for AES-128 CTR mode only)
* @alg (IN): Type of ciphering algorithm: AES/DES/3DES
* @mode (IN): Mode use when using AES algorithm: ECB/CBC/CTR
* Apllicabel when using AES algorithm only
* @op (IN): Type of operation: QCEDEV_OPER_DEC/QCEDEV_OPER_ENC or
* QCEDEV_OPER_ENC_NO_KEY/QCEDEV_OPER_DEC_NO_KEY
*
*If use_pmem is set to 0, the driver assumes that memory was not allocated
* via PMEM, and kernel will need to allocate memory and copy data from user
* space buffer (data_src/dta_dst) and process accordingly and copy data back
* to the user space buffer
*
* If use_pmem is set to 1, the driver assumes that memory was allocated via
* PMEM.
* The kernel driver will use the fd_src to determine the kernel virtual address
* base that maps to the user space virtual address base for the buffer
* allocated in user space.
* The final input/src and output/dst buffer pointer will be determined
* by adding the offsets to the kernel virtual addr.
*
* If use of hardware key is supported in the target, user can configure the
* key parameters (encklen, enckey) to use the hardware key.
* In order to use the hardware key, set encklen to 0 and set the enckey
* data array to 0.
*/
struct qcedev_cipher_op_req {
uint8_t use_pmem;
union {
struct qcedev_pmem_info pmem;
struct qcedev_vbuf_info vbuf;
};
uint32_t entries;
uint32_t data_len;
uint8_t in_place_op;
uint8_t enckey[QCEDEV_MAX_KEY_SIZE];
uint32_t encklen;
uint8_t iv[QCEDEV_MAX_IV_SIZE];
uint32_t ivlen;
uint32_t byteoffset;
enum qcedev_cipher_alg_enum alg;
enum qcedev_cipher_mode_enum mode;
enum qcedev_oper_enum op;
};
/**
* struct qcedev_sha_op_req - Holds the hashing request information
* @data (IN): Array of pointers to the data to be hashed
* @entries (IN): Number of buf_info entries in the data array
* @data_len (IN): Length of data to be hashed
* @digest (IN/OUT): Returns the hashed data information
* @diglen (OUT): Size of the hashed/digest data
* @authkey (IN): Pointer to authentication key for HMAC
* @authklen (IN): Size of the authentication key
* @alg (IN): Secure Hash algorithm
*/
struct qcedev_sha_op_req {
struct buf_info data[QCEDEV_MAX_BUFFERS];
uint32_t entries;
uint32_t data_len;
uint8_t digest[QCEDEV_MAX_SHA_DIGEST];
uint32_t diglen;
uint8_t *authkey;
uint32_t authklen;
enum qcedev_sha_alg_enum alg;
};
/**
* struct qfips_verify_t - Holds data for FIPS Integrity test
* @kernel_size (IN): Size of kernel Image
* @kernel (IN): pointer to buffer containing the kernel Image
*/
struct qfips_verify_t {
unsigned int kernel_size;
void *kernel;
};
struct file;
#define QCEDEV_IOC_MAGIC 0x87
#define QCEDEV_IOCTL_ENC_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 1, struct qcedev_cipher_op_req)
#define QCEDEV_IOCTL_DEC_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 2, struct qcedev_cipher_op_req)
#define QCEDEV_IOCTL_SHA_INIT_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 3, struct qcedev_sha_op_req)
#define QCEDEV_IOCTL_SHA_UPDATE_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 4, struct qcedev_sha_op_req)
#define QCEDEV_IOCTL_SHA_FINAL_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 5, struct qcedev_sha_op_req)
#define QCEDEV_IOCTL_GET_SHA_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 6, struct qcedev_sha_op_req)
#define QCEDEV_IOCTL_LOCK_CE \
_IO(QCEDEV_IOC_MAGIC, 7)
#define QCEDEV_IOCTL_UNLOCK_CE \
_IO(QCEDEV_IOC_MAGIC, 8)
#define QCEDEV_IOCTL_GET_CMAC_REQ \
_IOWR(QCEDEV_IOC_MAGIC, 9, struct qcedev_sha_op_req)
#define QCEDEV_IOCTL_UPDATE_FIPS_STATUS \
_IOWR(QCEDEV_IOC_MAGIC, 10, enum fips_status)
#define QCEDEV_IOCTL_QUERY_FIPS_STATUS \
_IOR(QCEDEV_IOC_MAGIC, 11, enum fips_status)
#endif /* _UAPI_QCEDEV__H */

210
include/uapi/linux/qcota.h Normal file
View File

@@ -0,0 +1,210 @@
#ifndef _UAPI_QCOTA_H
#define _UAPI_QCOTA_H
#include <linux/types.h>
#include <linux/ioctl.h>
#define QCE_OTA_MAX_BEARER 31
#define OTA_KEY_SIZE 16 /* 128 bits of keys. */
enum qce_ota_dir_enum {
QCE_OTA_DIR_UPLINK = 0,
QCE_OTA_DIR_DOWNLINK = 1,
QCE_OTA_DIR_LAST
};
enum qce_ota_algo_enum {
QCE_OTA_ALGO_KASUMI = 0,
QCE_OTA_ALGO_SNOW3G = 1,
QCE_OTA_ALGO_LAST
};
/**
* struct qce_f8_req - qce f8 request
* @data_in: packets input data stream to be ciphered.
* If NULL, streaming mode operation.
* @data_out: ciphered packets output data.
* @data_len: length of data_in and data_out in bytes.
* @count_c: count-C, ciphering sequence number, 32 bit
* @bearer: 5 bit of radio bearer identifier.
* @ckey: 128 bits of confidentiality key,
* ckey[0] bit 127-120, ckey[1] bit 119-112,.., ckey[15] bit 7-0.
* @direction: uplink or donwlink.
* @algorithm: Kasumi, or Snow3G.
*
* If data_in is NULL, the engine will run in a special mode called
* key stream mode. In this special mode, the engine will generate
* key stream output for the number of bytes specified in the
* data_len, based on the input parameters of direction, algorithm,
* ckey, bearer, and count_c. The data_len is restricted to
* the length of multiple of 16 bytes. Application can then take the
* output stream, do a exclusive or to the input data stream, and
* generate the final cipher data stream.
*/
struct qce_f8_req {
uint8_t *data_in;
uint8_t *data_out;
uint16_t data_len;
uint32_t count_c;
uint8_t bearer;
uint8_t ckey[OTA_KEY_SIZE];
enum qce_ota_dir_enum direction;
enum qce_ota_algo_enum algorithm;
};
/**
* struct qce_f8_multi_pkt_req - qce f8 multiple packet request
* Muliptle packets with uniform size, and
* F8 ciphering parameters can be ciphered in a
* single request.
*
* @num_pkt: number of packets.
*
* @cipher_start: ciphering starts offset within a packet.
*
* @cipher_size: number of bytes to be ciphered within a packet.
*
* @qce_f8_req: description of the packet and F8 parameters.
* The following fields have special meaning for
* multiple packet operation,
*
* @data_len: data_len indicates the length of a packet.
*
* @data_in: packets are concatenated together in a byte
* stream started at data_in.
*
* @data_out: The returned ciphered output for multiple
* packets.
* Each packet ciphered output are concatenated
* together into a byte stream started at data_out.
* Note, each ciphered packet output area from
* offset 0 to cipher_start-1, and from offset
* cipher_size to data_len -1 are remained
* unaltered from packet input area.
* @count_c: count-C of the first packet, 32 bit.
*
*
* In one request, multiple packets can be ciphered, and output to the
* data_out stream.
*
* Packet data are laid out contiguously in sequence in data_in,
* and data_out area. Every packet is identical size.
* If the PDU is not byte aligned, set the data_len value of
* to the rounded up value of the packet size. Eg, PDU size of
* 253 bits, set the packet size to 32 bytes. Next packet starts on
* the next byte boundary.
*
* For each packet, data from offset 0 to cipher_start
* will be left unchanged and output to the data_out area.
* This area of the packet can be for the RLC header, which is not
* to be ciphered.
*
* The ciphering of a packet starts from offset cipher_start, for
* cipher_size bytes of data. Data starting from
* offset cipher_start + cipher_size to the end of packet will be left
* unchanged and output to the dataOut area.
*
* For each packet the input arguments of bearer, direction,
* ckey, algorithm have to be the same. count_c is the ciphering sequence
* number of the first packet. The 2nd packet's ciphering sequence
* number is assumed to be count_c + 1. The 3rd packet's ciphering sequence
* number is count_c + 2.....
*
*/
struct qce_f8_multi_pkt_req {
uint16_t num_pkt;
uint16_t cipher_start;
uint16_t cipher_size;
struct qce_f8_req qce_f8_req;
};
/**
* struct qce_f8_variable_multi_pkt_req - qce f8 multiple packet request
* Muliptle packets with variable size, and
* F8 ciphering parameters can be ciphered in a
* single request.
*
* @num_pkt: number of packets.
*
* @cipher_iov[]: array of iov of packets to be ciphered.
*
*
* @qce_f8_req: description of the packet and F8 parameters.
* The following fields have special meaning for
* multiple packet operation,
*
* @data_len: ignored.
*
* @data_in: ignored.
*
* @data_out: ignored.
*
* @count_c: count-C of the first packet, 32 bit.
*
*
* In one request, multiple packets can be ciphered.
*
* The i-th packet are defined in cipher_iov[i-1].
* The ciphering of i-th packet starts from offset 0 of the PDU specified
* by cipher_iov[i-1].addr, for cipher_iov[i-1].size bytes of data.
* If the PDU is not byte aligned, set the cipher_iov[i-1].size value
* to the rounded up value of the packet size. Eg, PDU size of
* 253 bits, set the packet size to 32 bytes.
*
* Ciphering are done in place. That is, the ciphering
* input and output data are both in cipher_iov[i-1].addr for the i-th
* packet.
*
* For each packet the input arguments of bearer, direction,
* ckey, algorithm have to be the same. count_c is the ciphering sequence
* number of the first packet. The 2nd packet's ciphering sequence
* number is assumed to be count_c + 1. The 3rd packet's ciphering sequence
* number is count_c + 2.....
*/
#define MAX_NUM_V_MULTI_PKT 20
struct cipher_iov {
unsigned char *addr;
unsigned short size;
};
struct qce_f8_variable_multi_pkt_req {
unsigned short num_pkt;
struct cipher_iov cipher_iov[MAX_NUM_V_MULTI_PKT];
struct qce_f8_req qce_f8_req;
};
/**
* struct qce_f9_req - qce f9 request
* @message: message
* @msize: message size in bytes (include the last partial byte).
* @last_bits: valid bits in the last byte of message.
* @mac_i: 32 bit message authentication code, to be returned.
* @fresh: random 32 bit number, one per user.
* @count_i: 32 bit count-I integrity sequence number.
* @direction: uplink or donwlink.
* @ikey: 128 bits of integrity key,
* ikey[0] bit 127-120, ikey[1] bit 119-112,.., ikey[15] bit 7-0.
* @algorithm: Kasumi, or Snow3G.
*/
struct qce_f9_req {
uint8_t *message;
uint16_t msize;
uint8_t last_bits;
uint32_t mac_i;
uint32_t fresh;
uint32_t count_i;
enum qce_ota_dir_enum direction;
uint8_t ikey[OTA_KEY_SIZE];
enum qce_ota_algo_enum algorithm;
};
#define QCOTA_IOC_MAGIC 0x85
#define QCOTA_F8_REQ _IOWR(QCOTA_IOC_MAGIC, 1, struct qce_f8_req)
#define QCOTA_F8_MPKT_REQ _IOWR(QCOTA_IOC_MAGIC, 2, struct qce_f8_multi_pkt_req)
#define QCOTA_F9_REQ _IOWR(QCOTA_IOC_MAGIC, 3, struct qce_f9_req)
#define QCOTA_F8_V_MPKT_REQ _IOWR(QCOTA_IOC_MAGIC, 4,\
struct qce_f8_variable_multi_pkt_req)
#endif /* _UAPI_QCOTA_H */