summaryrefslogtreecommitdiff
path: root/drivers/mxc/security/sahara2/include
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/security/sahara2/include')
-rw-r--r--drivers/mxc/security/sahara2/include/adaptor.h113
-rw-r--r--drivers/mxc/security/sahara2/include/diagnostic.h116
-rw-r--r--drivers/mxc/security/sahara2/include/fsl_platform.h161
-rw-r--r--drivers/mxc/security/sahara2/include/fsl_shw.h2515
-rw-r--r--drivers/mxc/security/sahara2/include/fsl_shw_keystore.h475
-rw-r--r--drivers/mxc/security/sahara2/include/linux_port.h1806
-rw-r--r--drivers/mxc/security/sahara2/include/platform_abstractions.h15
-rw-r--r--drivers/mxc/security/sahara2/include/portable_os.h1453
-rw-r--r--drivers/mxc/security/sahara2/include/sah_driver_common.h102
-rw-r--r--drivers/mxc/security/sahara2/include/sah_hardware_interface.h99
-rw-r--r--drivers/mxc/security/sahara2/include/sah_interrupt_handler.h42
-rw-r--r--drivers/mxc/security/sahara2/include/sah_kernel.h113
-rw-r--r--drivers/mxc/security/sahara2/include/sah_memory_mapper.h79
-rw-r--r--drivers/mxc/security/sahara2/include/sah_queue_manager.h63
-rw-r--r--drivers/mxc/security/sahara2/include/sah_status_manager.h228
-rw-r--r--drivers/mxc/security/sahara2/include/sahara.h2265
-rw-r--r--drivers/mxc/security/sahara2/include/sahara2_kernel.h49
-rw-r--r--drivers/mxc/security/sahara2/include/sf_util.h466
18 files changed, 10160 insertions, 0 deletions
diff --git a/drivers/mxc/security/sahara2/include/adaptor.h b/drivers/mxc/security/sahara2/include/adaptor.h
new file mode 100644
index 000000000000..4c2d2bd7b688
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/adaptor.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+* @file adaptor.h
+*
+* @brief The Adaptor component provides an interface to the device
+* driver.
+*
+* Intended to be used by the FSL SHW API, this can also be called directly
+*/
+
+#ifndef ADAPTOR_H
+#define ADAPTOR_H
+
+#include <sahara.h>
+
+/*!
+ * Structure passed during user ioctl() call to submit request.
+ */
+typedef struct sah_dar {
+ sah_Desc *desc_addr; /*!< head of descriptor chain */
+ uint32_t uco_flags; /*!< copy of fsl_shw_uco flags field */
+ uint32_t uco_user_ref; /*!< copy of fsl_shw_uco user_ref */
+ uint32_t result; /*!< result of descriptor chain request */
+ struct sah_dar *next; /*!< for driver use */
+} sah_dar_t;
+
+/*!
+ * Structure passed during user ioctl() call to Register a user
+ */
+typedef struct sah_register {
+ uint32_t pool_size; /*!< max number of outstanding requests possible */
+ uint32_t result; /*!< result of registration request */
+} sah_register_t;
+
+/*!
+ * Structure passed during ioctl() call to request SCC operation
+ */
+typedef struct scc_data {
+ uint32_t length; /*!< length of data */
+ uint8_t *in; /*!< input data */
+ uint8_t *out; /*!< output data */
+ unsigned direction; /*!< encrypt or decrypt */
+ fsl_shw_sym_mode_t crypto_mode; /*!< CBC or EBC */
+ uint8_t *init_vector; /*!< initialization vector or NULL */
+} scc_data_t;
+
+/*!
+ * Structure passed during user ioctl() calls to manage stored keys and
+ * stored-key slots.
+ */
+typedef struct scc_slot_t {
+ uint64_t ownerid; /*!< Owner's id to check/set permissions */
+ uint32_t key_length; /*!< Length of key */
+ uint32_t slot; /*!< Slot to operation on, or returned slot
+ number. */
+ uint8_t *key; /*!< User-memory pointer to key value */
+ fsl_shw_return_t code; /*!< API return code from operation */
+} scc_slot_t;
+
+/*
+ * Structure passed during user ioctl() calls to manage data stored in secure
+ * partitions.
+ */
+typedef struct scc_region_t {
+ uint32_t partition_base; /*!< User virtual address of the
+ partition base. */
+ uint32_t offset; /*!< Offset from the start of the
+ partition where the cleartext data
+ is located. */
+ uint32_t length; /*!< Length of the region to be
+ operated on */
+ uint8_t *black_data; /*!< User virtual address of any black
+ (encrypted) data. */
+ fsl_shw_cypher_mode_t cypher_mode; /*!< Cypher mode to use in an encryt/
+ decrypt operation. */
+ uint32_t IV[4]; /*!< Intialization vector to use in an
+ encrypt/decrypt operation. */
+ fsl_shw_return_t code; /*!< API return code from operation */
+} scc_region_t;
+
+/*
+ * Structure passed during user ioctl() calls to manage secure partitions.
+ */
+typedef struct scc_partition_info_t {
+ uint32_t user_base; /**< Userspace pointer to base of partition */
+ uint32_t permissions; /**< Permissions to give the partition (only
+ used in call to _DROP_PERMS) */
+ fsl_shw_partition_status_t status; /*!< Status of the partition */
+} scc_partition_info_t;
+
+fsl_shw_return_t adaptor_Exec_Descriptor_Chain(sah_Head_Desc * dar,
+ fsl_shw_uco_t * uco);
+fsl_shw_return_t sah_get_results(sah_results * arg, fsl_shw_uco_t * uco);
+fsl_shw_return_t sah_register(fsl_shw_uco_t * user_ctx);
+fsl_shw_return_t sah_deregister(fsl_shw_uco_t * user_ctx);
+fsl_shw_return_t get_capabilities(fsl_shw_uco_t * user_ctx,
+ fsl_shw_pco_t *capabilities);
+
+#endif /* ADAPTOR_H */
+
+/* End of adaptor.h */
diff --git a/drivers/mxc/security/sahara2/include/diagnostic.h b/drivers/mxc/security/sahara2/include/diagnostic.h
new file mode 100644
index 000000000000..94db9bfe3a8a
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/diagnostic.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+* @file diagnostic.h
+*
+* @brief Macros for outputting kernel and user space diagnostics.
+*/
+
+#ifndef DIAGNOSTIC_H
+#define DIAGNOSTIC_H
+
+#ifndef __KERNEL__ /* linux flag */
+#include <stdio.h>
+#endif
+#include "fsl_platform.h"
+
+#if defined(FSL_HAVE_SAHARA2) || defined(FSL_HAVE_SAHARA4)
+#define DEV_NAME "sahara"
+#elif defined(FSL_HAVE_RNGA) || defined(FSL_HAVE_RNGB) || \
+ defined(FSL_HAVE_RNGC)
+#define DEV_NAME "shw"
+#endif
+
+/*!
+********************************************************************
+* @brief This macro logs diagnostic messages to stderr.
+*
+* @param diag String that must be logged, char *.
+*
+* @return void
+*
+*/
+//#if defined DIAG_SECURITY_FUNC || defined DIAG_ADAPTOR
+#define LOG_DIAG(diag) \
+({ \
+ const char* fname = strrchr(__FILE__, '/'); \
+ \
+ sah_Log_Diag(fname ? fname+1 : __FILE__, __LINE__, diag); \
+})
+
+#ifdef __KERNEL__
+
+#define LOG_DIAG_ARGS(fmt, ...) \
+({ \
+ const char* fname = strrchr(__FILE__, '/'); \
+ os_printk(KERN_ALERT "%s:%i: " fmt "\n", \
+ fname ? fname+1 : __FILE__, \
+ __LINE__, \
+ __VA_ARGS__); \
+})
+
+#else
+
+#define LOG_DIAG_ARGS(fmt, ...) \
+({ \
+ const char* fname = strrchr(__FILE__, '/'); \
+ printf("%s:%i: " fmt "\n", \
+ fname ? fname+1 : __FILE__, \
+ __LINE__, \
+ __VA_ARGS__); \
+})
+
+#ifndef __KERNEL__
+void sah_Log_Diag(char *source_name, int source_line, char *diag);
+#endif
+#endif /* if define DIAG_SECURITY_FUNC ... */
+
+#ifdef __KERNEL__
+/*!
+********************************************************************
+* @brief This macro logs kernel diagnostic messages to the kernel
+* log.
+*
+* @param diag String that must be logged, char *.
+*
+* @return As for printf()
+*/
+#if 0
+#if defined(DIAG_DRV_IF) || defined(DIAG_DRV_QUEUE) || \
+ defined(DIAG_DRV_STATUS) || defined(DIAG_DRV_INTERRUPT) || \
+ defined(DIAG_MEM) || defined(DIAG_SECURITY_FUNC) || defined(DIAG_ADAPTOR)
+#endif
+#endif
+
+#define LOG_KDIAG_ARGS(fmt, ...) \
+({ \
+ os_printk (KERN_ALERT "%s (%s:%i): " fmt "\n", \
+ DEV_NAME, strrchr(__FILE__, '/')+1, __LINE__, __VA_ARGS__); \
+})
+
+#define LOG_KDIAG(diag) \
+ os_printk (KERN_ALERT "%s (%s:%i): %s\n", \
+ DEV_NAME, strrchr(__FILE__, '/')+1, __LINE__, diag);
+
+#define sah_Log_Diag(n, l, d) \
+ os_printk(KERN_ALERT "%s:%i: %s\n", n, l, d)
+
+#else /* not KERNEL */
+
+#define sah_Log_Diag(n, l, d) \
+ printf("%s:%i: %s\n", n, l, d)
+
+#endif /* __KERNEL__ */
+
+#endif /* DIAGNOSTIC_H */
diff --git a/drivers/mxc/security/sahara2/include/fsl_platform.h b/drivers/mxc/security/sahara2/include/fsl_platform.h
new file mode 100644
index 000000000000..b55bd6cd9a5e
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/fsl_platform.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file fsl_platform.h
+ *
+ * Header file to isolate code which might be platform-dependent
+ */
+
+#ifndef FSL_PLATFORM_H
+#define FSL_PLATFORM_H
+
+#ifdef __KERNEL__
+#include "portable_os.h"
+#endif
+
+#if defined(FSL_PLATFORM_OTHER)
+
+/* Have Makefile or other method of setting FSL_HAVE_* flags */
+
+#elif defined(CONFIG_ARCH_MX3) /* i.MX31 */
+
+#define FSL_HAVE_SCC
+#define FSL_HAVE_RTIC
+#define FSL_HAVE_RNGA
+
+#elif defined(CONFIG_ARCH_MX21)
+
+#define FSL_HAVE_HAC
+#define FSL_HAVE_RNGA
+#define FSL_HAVE_SCC
+
+#elif defined(CONFIG_ARCH_MX25)
+
+#define FSL_HAVE_SCC
+#define FSL_HAVE_RNGB
+#define FSL_HAVE_RTIC3
+#define FSL_HAVE_DRYICE
+
+#elif defined(CONFIG_ARCH_MX27)
+
+#define FSL_HAVE_SAHARA2
+#define SUBMIT_MULTIPLE_DARS
+#define FSL_HAVE_RTIC
+#define FSL_HAVE_SCC
+#define ALLOW_LLO_DESCRIPTORS
+
+#elif defined(CONFIG_ARCH_MX35)
+
+#define FSL_HAVE_SCC
+#define FSL_HAVE_RNGC
+#define FSL_HAVE_RTIC
+
+#elif defined(CONFIG_ARCH_MX37)
+
+#define FSL_HAVE_SCC2
+#define FSL_HAVE_RNGC
+#define FSL_HAVE_RTIC2
+#define FSL_HAVE_SRTC
+
+#elif defined(CONFIG_ARCH_MX5)
+
+#define FSL_HAVE_SCC2
+#define FSL_HAVE_SAHARA4
+#define FSL_HAVE_RTIC3
+#define FSL_HAVE_SRTC
+#define NO_RESEED_WORKAROUND
+#define NEED_CTR_WORKAROUND
+#define USE_S2_CCM_ENCRYPT_CHAIN
+#define USE_S2_CCM_DECRYPT_CHAIN
+#define ALLOW_LLO_DESCRIPTORS
+
+#elif defined(CONFIG_ARCH_MXC91131)
+
+#define FSL_HAVE_SCC
+#define FSL_HAVE_RNGC
+#define FSL_HAVE_HAC
+
+#elif defined(CONFIG_ARCH_MXC91221)
+
+#define FSL_HAVE_SCC
+#define FSL_HAVE_RNGC
+#define FSL_HAVE_RTIC2
+
+#elif defined(CONFIG_ARCH_MXC91231)
+
+#define FSL_HAVE_SAHARA2
+#define FSL_HAVE_RTIC
+#define FSL_HAVE_SCC
+#define NO_OUTPUT_1K_CROSSING
+
+#elif defined(CONFIG_ARCH_MXC91311)
+
+#define FSL_HAVE_SCC
+#define FSL_HAVE_RNGC
+
+#elif defined(CONFIG_ARCH_MXC91314)
+
+#define FSL_HAVE_SCC
+#define FSL_HAVE_SAHAR4
+#define FSL_HAVE_RTIC3
+#define NO_RESEED_WORKAROUND
+#define NEED_CTR_WORKAROUND
+#define USE_S2_CCM_ENCRYPT_CHAIN
+#define USE_S2_CCM_DECRYPT_CHAIN
+#define ALLOW_LLO_DESCRIPTORS
+
+#elif defined(CONFIG_ARCH_MXC91321)
+
+#define FSL_HAVE_SAHARA2
+#define FSL_HAVE_RTIC
+#define FSL_HAVE_SCC
+#define SCC_CLOCK_NOT_GATED
+#define NO_OUTPUT_1K_CROSSING
+
+#elif defined(CONFIG_ARCH_MXC92323)
+
+#define FSL_HAVE_SCC2
+#define FSL_HAVE_SAHARA4
+#define FSL_HAVE_PKHA
+#define FSL_HAVE_RTIC2
+#define NO_1K_CROSSING
+#define NO_RESEED_WORKAROUND
+#define NEED_CTR_WORKAROUND
+#define USE_S2_CCM_ENCRYPT_CHAIN
+#define USE_S2_CCM_DECRYPT_CHAIN
+#define ALLOW_LLO_DESCRIPTORS
+
+
+#elif defined(CONFIG_ARCH_MXC91331)
+
+#define FSL_HAVE_SCC
+#define FSL_HAVE_RNGA
+#define FSL_HAVE_HAC
+#define FSL_HAVE_RTIC
+
+#elif defined(CONFIG_8548)
+
+#define FSL_HAVE_SEC2x
+
+#elif defined(CONFIG_MPC8374)
+
+#define FSL_HAVE_SEC3x
+
+#else
+
+#error UNKNOWN_PLATFORM
+
+#endif /* platform checks */
+
+#endif /* FSL_PLATFORM_H */
diff --git a/drivers/mxc/security/sahara2/include/fsl_shw.h b/drivers/mxc/security/sahara2/include/fsl_shw.h
new file mode 100644
index 000000000000..a52d420c721e
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/fsl_shw.h
@@ -0,0 +1,2515 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * NOTE TO MAINTAINERS: Although this header file is *the* header file to be
+ * #include'd by FSL SHW programs, it does not itself make any definitions for
+ * the API. Instead, it uses the fsl_platform.h file and / or compiler
+ * environment variables to determine which actual driver header file to
+ * include. This allows different implementations to contain different
+ * implementations of the various objects, macros, etc., or even to change
+ * which functions are macros and which are not.
+ */
+
+/*!
+ * @file fsl_shw.h
+ *
+ * @brief Definition of the Freescale Security Hardware API.
+ *
+ * See @ref index for an overview of the API.
+ */
+
+/*!
+ * @if USE_MAINPAGE
+ * @mainpage Common API for Freescale Security Hardware (FSL SHW API)
+ * @endif
+ *
+ * @section intro_sec Introduction
+ *
+ * This is the interface definition for the Freescale Security Hardware API
+ * (FSL SHW API) for User Mode and Kernel Mode to access Freescale Security
+ * Hardware components for cryptographic acceleration. The API is intended to
+ * provide cross-platform access to security hardware components of Freescale.
+ *
+ * This documentation has not been approved, and should not be taken to
+ * mean anything definite about future direction.
+ *
+ * Some example code is provided to give some idea of usage of this API.
+ *
+ * Note: This first version has been defined around the capabilities of the
+ * Sahara2 cryptographic accelerator, and may be expanded in the future to
+ * provide support for other platforms. The Platform Capabilities Object is
+ * intended as a way to allow programs to adapt to different platforms.
+ *
+ * The i.MX25 is an example of a platform without a SAHARA but yet has
+ * capabilities supported by this API. These include #fsl_shw_get_random() and
+ * #fsl_shw_add_entropy(), and the use of Triple-DES (TDEA) cipher algorithm
+ * (with no checking of key parity supported) in ECB and CBC modes with @ref
+ * sym_sec. See also the @ref di_sec for information on key handling, and @ref
+ * td_sec for detection of Tamper Events. Only the random functions are
+ * available from user space on this platform.
+ *
+ * @section usr_ctx The User Context
+ *
+ * The User Context Object (#fsl_shw_uco_t) controls the interaction between
+ * the user program and the API. It is initialized as part of user
+ * registration (#fsl_shw_register_user()), and is part of every interaction
+ * thereafter.
+ *
+ * @section pf_sec Platform Capabilities
+ *
+ * Since this API is not tied to one specific type of hardware or even one
+ * given version of a given type of hardware, the platform capabilities object
+ * could be used by a portable program to make choices about using software
+ * instead of hardware for certain operations.
+ *
+ * See the #fsl_shw_pco_t, returned by #fsl_shw_get_capabilities().
+ *
+ * @ref pcoops are provided to query its contents.
+ *
+ *
+ * @section sym_sec Symmetric-Key Encryption and Decryption
+ *
+ * Symmetric-Key encryption support is provided for the block cipher algorithms
+ * AES, DES, and Triple DES. Modes supported are #FSL_SYM_MODE_ECB,
+ * #FSL_SYM_MODE_CBC, and #FSL_SYM_MODE_CTR, though not necessarily all modes
+ * for all algorithms. There is also support for the stream cipher algorithm
+ * commonly known as ARC4.
+ *
+ * Encryption and decryption are performed by using the functions
+ * #fsl_shw_symmetric_encrypt() and #fsl_shw_symmetric_decrypt(), respectively.
+ * There are two objects which provide information about the operation of these
+ * functions. They are the #fsl_shw_sko_t, to provide key and algorithm
+ * information; and the #fsl_shw_scco_t, to provide (and store) initial context
+ * or counter value information.
+ *
+ * CCM is not supported by these functions. For information CCM support, see
+ * @ref cmb_sec.
+ *
+ *
+ * @section hash_sec Cryptographic Hashing
+ *
+ * Hashing is performed by fsl_shw_hash(). Control of the function is through
+ * flags in the #fsl_shw_hco_t. The algorithms which are
+ * supported are listed in #fsl_shw_hash_alg_t.
+ *
+ * The hashing function works on octet streams. If a user application needs to
+ * hash a bitstream, it will need to do its own padding of the last block.
+ *
+ *
+ * @section hmac_sec Hashed Message Authentication Codes
+ *
+ * An HMAC is a method of combining a hash and a key so that a message cannot
+ * be faked by a third party.
+ *
+ * The #fsl_shw_hmac() can be used by itself for one-shot or multi-step
+ * operations, or in combination with #fsl_shw_hmac_precompute() to provide the
+ * ability to compute and save the beginning hashes from a key one time, and
+ * then use #fsl_shw_hmac() to calculate an HMAC on each message as it is
+ * processed.
+ *
+ * The maximum key length which is directly supported by this API is 64 octets.
+ * If a longer key size is needed for HMAC, the user will have to hash the key
+ * and present the digest value as the key to be used by the HMAC functions.
+ *
+ *
+ * @section rnd_sec Random Numbers
+ *
+ * Support is available for acquiring random values from a
+ * cryptographically-strong random number generator. See
+ * #fsl_shw_get_random(). The function #fsl_shw_add_entropy() may be used to
+ * add entropy to the random number generator.
+ *
+ *
+ * @section cmb_sec Combined Cipher and Authentication
+ *
+ * Some schemes require that messages be encrypted and that they also have an
+ * authentication code associated with the message. The function
+ * #fsl_shw_gen_encrypt() will generate the authentication code and encrypt the
+ * message.
+ *
+ * Upon receipt of such a message, the message must be decrypted and the
+ * authentication code validated. The function
+ * #fsl_shw_auth_decrypt() will perform these steps.
+ *
+ * Only AES-CCM is supported.
+ *
+ *
+ * @section wrap_sec Wrapped Keys
+ *
+ * On platforms with a Secure Memory, the function #fsl_shw_establish_key() can
+ * be used to place a key into the System Keystore. This key then can be used
+ * directly by the cryptographic hardware. It later then be wrapped
+ * (cryptographically obscured) by #fsl_shw_extract_key() and stored for later
+ * use. If a software key (#FSL_SKO_KEY_SW_KEY) was established, then its
+ * value can be retrieved with a call to #fsl_shw_read_key().
+ *
+ * The wrapping and unwrapping functions provide security against unauthorized
+ * use and detection of tampering.
+ *
+ * The functions can also be used with a User Keystore.
+ *
+ * @section smalloc_sec Secure Memory Allocation
+ *
+ * On platforms with multiple partitions of Secure Memory, the function
+ * #fsl_shw_smalloc() can be used to acquire a partition for private use. The
+ * function #fsl_shw_diminish_perms() can then be used to revoke specific
+ * permissions on the partition, and #fsl_shw_sfree() can be used to release the
+ * partition.
+ *
+ * @section keystore_sec User Keystore
+ *
+ * User Keystore functionality is defined in fsl_shw_keystore.h. See @ref
+ * user_keystore for details. This is not supported on platforms without SCC2.
+ *
+ * @section di_sec Hardware key-select extensions - DryIce
+ *
+ * Some platforms have a component called DryIce which allows the software to
+ * control which key will be used by the secure memory encryption hardware.
+ * The choices are the secret per-chip Fused (IIM) Key, an unknown, hardware-
+ * generated Random Key, a software-written Programmed Key, or the IIM Key in
+ * combination with one of the others. #fsl_shw_pco_check_pk_supported() can
+ * be used to determine whether this feature is available on the platform.
+ * The rest of this section will explain the symmetric ciphering and key
+ * operations which are available on such a platform.
+ *
+ * The function #fsl_shw_sko_init_pf_key() will set up a Secret Key Object to
+ * refer to one of the system's platform keys. All keys which reference a
+ * platform key must use this initialization function, including a user-
+ * provided key value. Keys which are intended for software encryption must
+ * use #fsl_shw_sko_init().
+ *
+ * To change the setting of the Programmed Key of the DryIce module,
+ * #fsl_shw_establish_key() must be called with a platform key object of type
+ * #FSL_SHW_PF_KEY_PRG or #FSL_SHW_PF_KEY_IIM_PRG. The key will be go
+ * into the PK register of DryIce and not to the keystore. Any symmetric
+ * operation which references either #FSL_SHW_PF_KEY_PRG or
+ * #FSL_SHW_PF_KEY_IIM_PRG will use the current PK value (possibly modified by
+ * the secret fused IIM key). Before the Flatform Key can be changed, a call to
+ * #fsl_shw_release_key() or #fsl_shw_extract_key() must be made. Neither
+ * function will change the value in the PK registers, and further ciphering
+ * can take place.
+ *
+ * When #fsl_shw_establish_key() is called to change the PK value, a plaintext
+ * key can be passed in with the #FSL_KEY_WRAP_ACCEPT argument or a previously
+ * wrapped key can be passed in with the #FSL_KEY_WRAP_UNWRAP argument. If
+ * #FSL_KEY_WRAP_CREATE is passed in, then a random value will be loaded into
+ * the PK register. The PK value can be wrapped by a call to
+ * #fsl_shw_extract_key() for later use with the #FSL_KEY_WRAP_UNWRAP argument.
+ *
+ * As an alternative to using only the fused key for @ref wrap_sec,
+ * #fsl_shw_uco_set_wrap_key() can be used to select either the random key or
+ * the random key with the fused key as the key which will be used to protect
+ * the one-time value used to wrap the key. This allows for these
+ * wrapped keys to be dependent upon and therefore unrecoverable after a tamper
+ * event causes the erasure of the DryIce Random Key register.
+ *
+ * The software can request that the hardware generate a (new) Random Key for
+ * DryIce by calling #fsl_shw_gen_random_pf_key().
+ *
+ *
+ * @section td_sec Device Tamper-Detection
+ *
+ * Some platforms have a component which can detect certain types of tampering
+ * with the hardware. #fsl_shw_read_tamper_event() API will allow the
+ * retrieval of the type of event which caused a tamper-detection failure.
+ *
+ */
+
+/*! @defgroup glossary Glossary
+ *
+ * @li @b AES - Advanced Encryption Standard - An NIST-created block cipher
+ * originally knowns as Rijndael.
+ * @li @b ARC4 - ARCFOUR - An S-Box-based OFB mode stream cipher.
+ * @li @b CBC - Cipher-Block Chaining - Each encrypted block is XORed with the
+ * result of the previous block's encryption.
+ * @li @b CCM - A way of combining CBC and CTR to perform cipher and
+ * authentication.
+ * @li @b ciphertext - @a plaintext which has been encrypted in some fashion.
+ * @li @b context - Information on the state of a cryptographic operation,
+ * excluding any key. This could include IV, Counter Value, or SBox.
+ * @li @b CTR - A mode where a counter value is encrypted and then XORed with
+ * the data. After each block, the counter value is incremented.
+ * @li @b DES - Data Encryption Standard - An 8-octet-block cipher.
+ * @li @b ECB - Electronic Codebook - A straight encryption/decryption of the
+ * data.
+ * @li @b hash - A cryptographically strong one-way function performed on data.
+ * @li @b HMAC - Hashed Message Authentication Code - A key-dependent one-way
+ * hash result, used to verify authenticity of a message. The equation
+ * for an HMAC is hash((K + A) || hash((K + B) || msg)), where K is the
+ * key, A is the constant for the outer hash, B is the constant for the
+ * inner hash, and hash is the hashing function (MD5, SHA256, etc).
+ * @li @b IPAD - In an HMAC operation, the context generated by XORing the key
+ * with a constant and then hashing that value as the first block of the
+ * inner hash.
+ * @li @b IV - An "Initial Vector" or @a context for modes like CBC.
+ * @li @b MAC - A Message Authentication Code. HMAC, hashing, and CCM all
+ * produce a MAC.
+ * @li @b mode - A way of using a cryptographic algorithm. See ECB, CBC, etc.
+ * @li @b MD5 - Message Digest 5 - A one-way hash function.
+ * @li @b plaintext - Data which has not been encrypted, or has been decrypted
+ * from @a ciphertext.
+ * @li @b OPAD - In an HMAC operation, the context generated by XORing the key
+ * with a constant and then hashing that value as the first block of the
+ * outer hash.
+ * @li @b SHA - Secure Hash Algorithm - A one-way hash function.
+ * @li @b TDES - AKA @b 3DES - Triple Data Encryption Standard - A method of
+ * using two or three keys and DES to perform three operations (encrypt
+ * decrypt encrypt) to create a new algorithm.
+ * @li @b XOR - Exclusive-OR. A Boolean arithmetic function.
+ * @li @b Wrapped value - A (key) which has been encrypted into an opaque datum
+ * which cannot be unwrapped (decrypted) for use except by an authorized
+ * user. Once created, the key is never visible, but may be used for
+ * other cryptographic operations.
+ */
+
+#ifndef FSL_SHW_H
+#define FSL_SHW_H
+
+/* Set FSL_HAVE_* flags */
+
+#include "fsl_platform.h"
+
+#ifndef API_DOC
+
+#if defined(FSL_HAVE_SAHARA2) || defined(FSL_HAVE_SAHARA4)
+
+#include "sahara.h"
+
+#else
+
+#if defined(FSL_HAVE_RNGA) || defined(FSL_HAVE_RNGB) || defined(FSL_HAVE_RNGC)
+
+#include "rng_driver.h"
+
+#else
+
+#error FSL_SHW_API_platform_not_recognized
+
+#endif
+
+#endif /* HAVE SAHARA */
+
+#else /* API_DOC */
+
+#include <inttypes.h> /* for uint32_t, etc. */
+#include <stdio.h> /* Mainly for definition of NULL !! */
+
+/* These groups will appear in the order in which they are defined. */
+
+/*!
+ * @defgroup strgrp Objects
+ *
+ * These objects are used to pass information into and out of the API. Through
+ * flags and other settings, they control the behavior of the @ref opfuns.
+ *
+ * They are manipulated and queried by use of the various access functions.
+ * There are different sets defined for each object. See @ref objman.
+ */
+
+/*!
+ * @defgroup consgrp Enumerations and other Constants
+ *
+ * This collection of symbols comprise the values which can be passed into
+ * various functions to control how the API will work.
+ */
+
+/*! @defgroup opfuns Operational Functions
+ *
+ * These functions request that the underlying hardware perform cryptographic
+ * operations. They are the heart of the API.
+ */
+
+/****** Organization the Object Operations under one group ! **********/
+/*! @defgroup objman Object-Manipulation Operations
+ *
+ */
+/*! @addtogroup objman
+ @{ */
+/*!
+ * @defgroup pcoops Platform Context Object Operations
+ *
+ * The Platform Context object is "read-only", so only query operations are
+ * provided for it. It is returned by the #fsl_shw_get_capabilities()
+ * function.
+ */
+
+/*! @defgroup ucoops User Context Operations
+ *
+ * These operations should be the only access to the #fsl_shw_uco_t
+ * type/struct, as the internal members of the object are subject to change.
+ * The #fsl_shw_uco_init() function must be called before any other use of the
+ * object.
+ */
+
+/*!
+ * @defgroup rops Result Object Operations
+ *
+ * As the Result Object contains the result of one of the @ref opfuns. The
+ * manipulations provided are query-only. No initialization is needed for this
+ * object.
+ */
+
+/*!
+ * @defgroup skoops Secret Key Object Operations
+ *
+ * These operations should be the only access to the #fsl_shw_sko_t
+ * type/struct, as the internal members of that object are subject to change.
+ */
+
+/*!
+ * @defgroup ksoops Keystore Object Operations
+ *
+ * These operations should be the only access to the #fsl_shw_kso_t
+ * type/struct, as the internal members of that object are subject to change.
+ */
+
+/*!
+ * @defgroup hcops Hash Context Object Operations
+ *
+ * These operations should be the only access to the #fsl_shw_hco_t
+ * type/struct, as the internal members of that object are subject to change.
+ */
+
+/*!
+ * @defgroup hmcops HMAC Context Object Operations
+ *
+ * These operations should be the only access to the #fsl_shw_hmco_t
+ * type/struct, as the internal members of that object are subject to change.
+ */
+
+/*!
+ * @defgroup sccops Symmetric Cipher Context Operations
+ *
+ * These operations should be the only access to the #fsl_shw_scco_t
+ * type/struct, as the internal members of that object are subject to change
+ */
+
+/*! @defgroup accoops Authentication-Cipher Context Object Operations
+ *
+ * These functions operate on a #fsl_shw_acco_t. Their purpose is to set
+ * flags, fields, etc., in order to control the operation of
+ * #fsl_shw_gen_encrypt() and #fsl_shw_auth_decrypt().
+ */
+
+ /* @} *//************ END GROUPING of Object Manipulations *****************/
+
+/*! @defgroup miscfuns Miscellaneous Functions
+ *
+ * These functions are neither @ref opfuns nor @ref objman. Their behavior
+ * does not depend upon the flags in the #fsl_shw_uco_t, yet they may involve
+ * more interaction with the library and the kernel than simply querying an
+ * object.
+ */
+
+/******************************************************************************
+ * Enumerations
+ *****************************************************************************/
+/*! @addtogroup consgrp
+ @{ */
+
+/*!
+ * Flags for the state of the User Context Object (#fsl_shw_uco_t).
+ *
+ * These flags describe how the @ref opfuns will operate.
+ */
+typedef enum fsl_shw_user_ctx_flags_t {
+ /*!
+ * API will block the caller until operation completes. The result will be
+ * available in the return code. If this is not set, user will have to get
+ * results using #fsl_shw_get_results().
+ */
+ FSL_UCO_BLOCKING_MODE,
+ /*!
+ * User wants callback (at the function specified with
+ * #fsl_shw_uco_set_callback()) when the operation completes. This flag is
+ * valid only if #FSL_UCO_BLOCKING_MODE is not set.
+ */
+ FSL_UCO_CALLBACK_MODE,
+ /*! Do not free descriptor chain after driver (adaptor) finishes */
+ FSL_UCO_SAVE_DESC_CHAIN,
+ /*!
+ * User has made at least one request with callbacks requested, so API is
+ * ready to handle others.
+ */
+ FSL_UCO_CALLBACK_SETUP_COMPLETE,
+ /*!
+ * (virtual) pointer to descriptor chain is completely linked with physical
+ * (DMA) addresses, ready for the hardware. This flag should not be used
+ * by FSL SHW API programs.
+ */
+ FSL_UCO_CHAIN_PREPHYSICALIZED,
+ /*!
+ * The user has changed the context but the changes have not been copied to
+ * the kernel driver.
+ */
+ FSL_UCO_CONTEXT_CHANGED,
+ /*! Internal Use. This context belongs to a user-mode API user. */
+ FSL_UCO_USERMODE_USER,
+} fsl_shw_user_ctx_flags_t;
+
+/*!
+ * Return code for FSL_SHW library.
+ *
+ * These codes may be returned from a function call. In non-blocking mode,
+ * they will appear as the status in a Result Object.
+ */
+typedef enum fsl_shw_return_t {
+ /*!
+ * No error. As a function return code in Non-blocking mode, this may
+ * simply mean that the operation was accepted for eventual execution.
+ */
+ FSL_RETURN_OK_S = 0,
+ /*! Failure for non-specific reason. */
+ FSL_RETURN_ERROR_S,
+ /*!
+ * Operation failed because some resource was not able to be allocated.
+ */
+ FSL_RETURN_NO_RESOURCE_S,
+ /*! Crypto algorithm unrecognized or improper. */
+ FSL_RETURN_BAD_ALGORITHM_S,
+ /*! Crypto mode unrecognized or improper. */
+ FSL_RETURN_BAD_MODE_S,
+ /*! Flag setting unrecognized or inconsistent. */
+ FSL_RETURN_BAD_FLAG_S,
+ /*! Improper or unsupported key length for algorithm. */
+ FSL_RETURN_BAD_KEY_LENGTH_S,
+ /*! Improper parity in a (DES, TDES) key. */
+ FSL_RETURN_BAD_KEY_PARITY_S,
+ /*!
+ * Improper or unsupported data length for algorithm or internal buffer.
+ */
+ FSL_RETURN_BAD_DATA_LENGTH_S,
+ /*! Authentication / Integrity Check code check failed. */
+ FSL_RETURN_AUTH_FAILED_S,
+ /*! A memory error occurred. */
+ FSL_RETURN_MEMORY_ERROR_S,
+ /*! An error internal to the hardware occurred. */
+ FSL_RETURN_INTERNAL_ERROR_S,
+ /*! ECC detected Point at Infinity */
+ FSL_RETURN_POINT_AT_INFINITY_S,
+ /*! ECC detected No Point at Infinity */
+ FSL_RETURN_POINT_NOT_AT_INFINITY_S,
+ /*! GCD is One */
+ FSL_RETURN_GCD_IS_ONE_S,
+ /*! GCD is not One */
+ FSL_RETURN_GCD_IS_NOT_ONE_S,
+ /*! Candidate is Prime */
+ FSL_RETURN_PRIME_S,
+ /*! Candidate is not Prime */
+ FSL_RETURN_NOT_PRIME_S,
+ /*! N register loaded improperly with even value */
+ FSL_RETURN_EVEN_MODULUS_ERROR_S,
+ /*! Divisor is zero. */
+ FSL_RETURN_DIVIDE_BY_ZERO_ERROR_S,
+ /*! Bad Exponent or Scalar value for Point Multiply */
+ FSL_RETURN_BAD_EXPONENT_ERROR_S,
+ /*! RNG hardware problem. */
+ FSL_RETURN_OSCILLATOR_ERROR_S,
+ /*! RNG hardware problem. */
+ FSL_RETURN_STATISTICS_ERROR_S,
+} fsl_shw_return_t;
+
+/*!
+ * Algorithm Identifier.
+ *
+ * Selection of algorithm will determine how large the block size of the
+ * algorithm is. Context size is the same length unless otherwise specified.
+ * Selection of algorithm also affects the allowable key length.
+ */
+typedef enum fsl_shw_key_alg_t {
+ FSL_KEY_ALG_HMAC, /*!< Key will be used to perform an HMAC. Key
+ size is 1 to 64 octets. Block size is 64
+ octets. */
+ FSL_KEY_ALG_AES, /*!< Advanced Encryption Standard (Rijndael).
+ Block size is 16 octets. Key size is 16
+ octets. (The single choice of key size is a
+ Sahara platform limitation.) */
+ FSL_KEY_ALG_DES, /*!< Data Encryption Standard. Block size is
+ 8 octets. Key size is 8 octets. */
+ FSL_KEY_ALG_TDES, /*!< 2- or 3-key Triple DES. Block size is 8
+ octets. Key size is 16 octets for 2-key
+ Triple DES, and 24 octets for 3-key. */
+ FSL_KEY_ALG_ARC4 /*!< ARC4. No block size. Context size is 259
+ octets. Allowed key size is 1-16 octets.
+ (The choices for key size are a Sahara
+ platform limitation.) */
+} fsl_shw_key_alg_t;
+
+/*!
+ * Mode selector for Symmetric Ciphers.
+ *
+ * The selection of mode determines how a cryptographic algorithm will be
+ * used to process the plaintext or ciphertext.
+ *
+ * For all modes which are run block-by-block (that is, all but
+ * #FSL_SYM_MODE_STREAM), any partial operations must be performed on a text
+ * length which is multiple of the block size. Except for #FSL_SYM_MODE_CTR,
+ * these block-by-block algorithms must also be passed a total number of octets
+ * which is a multiple of the block size.
+ *
+ * In modes which require that the total number of octets of data be a multiple
+ * of the block size (#FSL_SYM_MODE_ECB and #FSL_SYM_MODE_CBC), and the user
+ * has a total number of octets which are not a multiple of the block size, the
+ * user must perform any necessary padding to get to the correct data length.
+ */
+typedef enum fsl_shw_sym_mode_t {
+ /*!
+ * Stream. There is no associated block size. Any request to process data
+ * may be of any length. This mode is only for ARC4 operations, and is
+ * also the only mode used for ARC4.
+ */
+ FSL_SYM_MODE_STREAM,
+
+ /*!
+ * Electronic Codebook. Each block of data is encrypted/decrypted. The
+ * length of the data stream must be a multiple of the block size. This
+ * mode may be used for DES, 3DES, and AES. The block size is determined
+ * by the algorithm.
+ */
+ FSL_SYM_MODE_ECB,
+ /*!
+ * Cipher-Block Chaining. Each block of data is encrypted/decrypted and
+ * then "chained" with the previous block by an XOR function. Requires
+ * context to start the XOR (previous block). This mode may be used for
+ * DES, 3DES, and AES. The block size is determined by the algorithm.
+ */
+ FSL_SYM_MODE_CBC,
+ /*!
+ * Counter. The counter is encrypted, then XORed with a block of data.
+ * The counter is then incremented (using modulus arithmetic) for the next
+ * block. The final operation may be non-multiple of block size. This mode
+ * may be used for AES. The block size is determined by the algorithm.
+ */
+ FSL_SYM_MODE_CTR,
+} fsl_shw_sym_mode_t;
+
+/*!
+ * Algorithm selector for Cryptographic Hash functions.
+ *
+ * Selection of algorithm determines how large the context and digest will be.
+ * Context is the same size as the digest (resulting hash), unless otherwise
+ * specified.
+ */
+typedef enum fsl_shw_hash_alg_t {
+ FSL_HASH_ALG_MD5, /*!< MD5 algorithm. Digest is 16 octets. */
+ FSL_HASH_ALG_SHA1, /*!< SHA-1 (aka SHA or SHA-160) algorithm.
+ Digest is 20 octets. */
+ FSL_HASH_ALG_SHA224, /*!< SHA-224 algorithm. Digest is 28 octets,
+ though context is 32 octets. */
+ FSL_HASH_ALG_SHA256 /*!< SHA-256 algorithm. Digest is 32
+ octets. */
+} fsl_shw_hash_alg_t;
+
+/*!
+ * The type of Authentication-Cipher function which will be performed.
+ */
+typedef enum fsl_shw_acc_mode_t {
+ /*!
+ * CBC-MAC for Counter. Requires context and modulus. Final operation may
+ * be non-multiple of block size. This mode may be used for AES.
+ */
+ FSL_ACC_MODE_CCM,
+ /*!
+ * SSL mode. Not supported. Combines HMAC and encrypt (or decrypt).
+ * Needs one key object for encryption, another for the HMAC. The usual
+ * hashing and symmetric encryption algorithms are supported.
+ */
+ FSL_ACC_MODE_SSL,
+} fsl_shw_acc_mode_t;
+
+/*!
+ * The operation which controls the behavior of #fsl_shw_establish_key().
+ *
+ * These values are passed to #fsl_shw_establish_key().
+ */
+typedef enum fsl_shw_key_wrap_t {
+ FSL_KEY_WRAP_CREATE, /*!< Generate a key from random values. */
+ FSL_KEY_WRAP_ACCEPT, /*!< Use the provided clear key. */
+ FSL_KEY_WRAP_UNWRAP /*!< Unwrap a previously wrapped key. */
+} fsl_shw_key_wrap_t;
+
+/* REQ-S2LRD-PINTFC-COA-HCO-001 */
+/*!
+ * Flags which control a Hash operation.
+ *
+ * These may be combined by ORing them together. See #fsl_shw_hco_set_flags()
+ * and #fsl_shw_hco_clear_flags().
+ */
+typedef enum fsl_shw_hash_ctx_flags_t {
+ FSL_HASH_FLAGS_INIT = 1, /*!< Context is empty. Hash is started
+ from scratch, with a message-processed
+ count of zero. */
+ FSL_HASH_FLAGS_SAVE = 2, /*!< Retrieve context from hardware after
+ hashing. If used with the
+ #FSL_HASH_FLAGS_FINALIZE flag, the final
+ digest value will be saved in the
+ object. */
+ FSL_HASH_FLAGS_LOAD = 4, /*!< Place context into hardware before
+ hashing. */
+ FSL_HASH_FLAGS_FINALIZE = 8, /*!< PAD message and perform final digest
+ operation. If user message is
+ pre-padded, this flag should not be
+ used. */
+} fsl_shw_hash_ctx_flags_t;
+
+/*!
+ * Flags which control an HMAC operation.
+ *
+ * These may be combined by ORing them together. See #fsl_shw_hmco_set_flags()
+ * and #fsl_shw_hmco_clear_flags().
+ */
+typedef enum fsl_shw_hmac_ctx_flags_t {
+ FSL_HMAC_FLAGS_INIT = 1, /*!< Message context is empty. HMAC is
+ started from scratch (with key) or from
+ precompute of inner hash, depending on
+ whether
+ #FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT is
+ set. */
+ FSL_HMAC_FLAGS_SAVE = 2, /*!< Retrieve ongoing context from hardware
+ after hashing. If used with the
+ #FSL_HMAC_FLAGS_FINALIZE flag, the final
+ digest value (HMAC) will be saved in the
+ object. */
+ FSL_HMAC_FLAGS_LOAD = 4, /*!< Place ongoing context into hardware
+ before hashing. */
+ FSL_HMAC_FLAGS_FINALIZE = 8, /*!< PAD message and perform final HMAC
+ operations of inner and outer hashes. */
+ FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT = 16 /*!< This means that the context
+ contains precomputed inner and outer
+ hash values. */
+} fsl_shw_hmac_ctx_flags_t;
+
+/*!
+ * Flags to control use of the #fsl_shw_scco_t.
+ *
+ * These may be ORed together to get the desired effect.
+ * See #fsl_shw_scco_set_flags() and #fsl_shw_scco_clear_flags()
+ */
+typedef enum fsl_shw_sym_ctx_flags_t {
+ /*!
+ * Context is empty. In ARC4, this means that the S-Box needs to be
+ * generated from the key. In #FSL_SYM_MODE_CBC mode, this allows an IV of
+ * zero to be specified. In #FSL_SYM_MODE_CTR mode, it means that an
+ * initial CTR value of zero is desired.
+ */
+ FSL_SYM_CTX_INIT = 1,
+ /*!
+ * Load context from object into hardware before running cipher. In
+ * #FSL_SYM_MODE_CTR mode, this would refer to the Counter Value.
+ */
+ FSL_SYM_CTX_LOAD = 2,
+ /*!
+ * Save context from hardware into object after running cipher. In
+ * #FSL_SYM_MODE_CTR mode, this would refer to the Counter Value.
+ */
+ FSL_SYM_CTX_SAVE = 4,
+ /*!
+ * Context (SBox) is to be unwrapped and wrapped on each use.
+ * This flag is unsupported.
+ * */
+ FSL_SYM_CTX_PROTECT = 8,
+} fsl_shw_sym_ctx_flags_t;
+
+/*!
+ * Flags which describe the state of the #fsl_shw_sko_t.
+ *
+ * These may be ORed together to get the desired effect.
+ * See #fsl_shw_sko_set_flags() and #fsl_shw_sko_clear_flags()
+ */
+typedef enum fsl_shw_key_flags_t {
+ FSL_SKO_KEY_IGNORE_PARITY = 1, /*!< If algorithm is DES or 3DES, do not
+ validate the key parity bits. */
+ FSL_SKO_KEY_PRESENT = 2, /*!< Clear key is present in the object. */
+ FSL_SKO_KEY_ESTABLISHED = 4, /*!< Key has been established for use. This
+ feature is not available for all
+ platforms, nor for all algorithms and
+ modes. */
+ FSL_SKO_KEY_SW_KEY = 8, /*!< This key is for software use, and can
+ be copied out of a keystore by its owner.
+ The default is that they key is available
+ only for hardware (or security driver)
+ use. */
+} fsl_shw_key_flags_t;
+
+/*!
+ * Type of value which is associated with an established key.
+ */
+typedef uint64_t key_userid_t;
+
+/*!
+ * Flags which describe the state of the #fsl_shw_acco_t.
+ *
+ * The @a FSL_ACCO_CTX_INIT and @a FSL_ACCO_CTX_FINALIZE flags, when used
+ * together, provide for a one-shot operation.
+ */
+typedef enum fsl_shw_auth_ctx_flags_t {
+ FSL_ACCO_CTX_INIT = 1, /*!< Initialize Context(s) */
+ FSL_ACCO_CTX_LOAD = 2, /*!< Load intermediate context(s).
+ This flag is unsupported. */
+ FSL_ACCO_CTX_SAVE = 4, /*!< Save intermediate context(s).
+ This flag is unsupported. */
+ FSL_ACCO_CTX_FINALIZE = 8, /*!< Create MAC during this operation. */
+ FSL_ACCO_NIST_CCM = 16, /*!< Formatting of CCM input data is
+ performed by calls to
+ #fsl_shw_ccm_nist_format_ctr_and_iv() and
+ #fsl_shw_ccm_nist_update_ctr_and_iv(). */
+} fsl_shw_auth_ctx_flags_t;
+
+/*!
+ * Modulus Selector for CTR modes.
+ *
+ * The incrementing of the Counter value may be modified by a modulus. If no
+ * modulus is needed or desired for AES, use #FSL_CTR_MOD_128.
+ */
+typedef enum fsl_shw_ctr_mod_t {
+ FSL_CTR_MOD_8, /*!< Run counter with modulus of 2^8. */
+ FSL_CTR_MOD_16, /*!< Run counter with modulus of 2^16. */
+ FSL_CTR_MOD_24, /*!< Run counter with modulus of 2^24. */
+ FSL_CTR_MOD_32, /*!< Run counter with modulus of 2^32. */
+ FSL_CTR_MOD_40, /*!< Run counter with modulus of 2^40. */
+ FSL_CTR_MOD_48, /*!< Run counter with modulus of 2^48. */
+ FSL_CTR_MOD_56, /*!< Run counter with modulus of 2^56. */
+ FSL_CTR_MOD_64, /*!< Run counter with modulus of 2^64. */
+ FSL_CTR_MOD_72, /*!< Run counter with modulus of 2^72. */
+ FSL_CTR_MOD_80, /*!< Run counter with modulus of 2^80. */
+ FSL_CTR_MOD_88, /*!< Run counter with modulus of 2^88. */
+ FSL_CTR_MOD_96, /*!< Run counter with modulus of 2^96. */
+ FSL_CTR_MOD_104, /*!< Run counter with modulus of 2^104. */
+ FSL_CTR_MOD_112, /*!< Run counter with modulus of 2^112. */
+ FSL_CTR_MOD_120, /*!< Run counter with modulus of 2^120. */
+ FSL_CTR_MOD_128 /*!< Run counter with modulus of 2^128. */
+} fsl_shw_ctr_mod_t;
+
+/*!
+ * Permissions flags for Secure Partitions
+ *
+ * They currently map directly to the SCC2 hardware values, but this is not
+ * guarinteed behavior.
+ */
+typedef enum fsl_shw_permission_t {
+/*! SCM Access Permission: Do not zeroize/deallocate partition on SMN Fail state */
+ FSL_PERM_NO_ZEROIZE,
+/*! SCM Access Permission: Enforce trusted key read in */
+ FSL_PERM_TRUSTED_KEY_READ,
+/*! SCM Access Permission: Ignore Supervisor/User mode in permission determination */
+ FSL_PERM_HD_S,
+/*! SCM Access Permission: Allow Read Access to Host Domain */
+ FSL_PERM_HD_R,
+/*! SCM Access Permission: Allow Write Access to Host Domain */
+ FSL_PERM_HD_W,
+/*! SCM Access Permission: Allow Execute Access to Host Domain */
+ FSL_PERM_HD_X,
+/*! SCM Access Permission: Allow Read Access to Trusted Host Domain */
+ FSL_PERM_TH_R,
+/*! SCM Access Permission: Allow Write Access to Trusted Host Domain */
+ FSL_PERM_TH_W,
+/*! SCM Access Permission: Allow Read Access to Other/World Domain */
+ FSL_PERM_OT_R,
+/*! SCM Access Permission: Allow Write Access to Other/World Domain */
+ FSL_PERM_OT_W,
+/*! SCM Access Permission: Allow Execute Access to Other/World Domain */
+ FSL_PERM_OT_X,
+} fsl_shw_permission_t;
+
+/*!
+ * Select the cypher mode to use for partition cover/uncover operations.
+ *
+ * They currently map directly to the values used in the SCC2 driver, but this
+ * is not guarinteed behavior.
+ */
+typedef enum fsl_shw_cypher_mode_t {
+ FSL_SHW_CYPHER_MODE_ECB, /*!< ECB mode */
+ FSL_SHW_CYPHER_MODE_CBC, /*!< CBC mode */
+} fsl_shw_cypher_mode_t;
+
+/*!
+ * Which platform key should be presented for cryptographic use.
+ */
+typedef enum fsl_shw_pf_key_t {
+ FSL_SHW_PF_KEY_IIM, /*!< Present fused IIM key */
+ FSL_SHW_PF_KEY_PRG, /*!< Present Program key */
+ FSL_SHW_PF_KEY_IIM_PRG, /*!< Present IIM ^ Program key */
+ FSL_SHW_PF_KEY_IIM_RND, /*!< Present Random key */
+ FSL_SHW_PF_KEY_RND, /*!< Present IIM ^ Random key */
+} fsl_shw_pf_key_t;
+
+/*!
+ * The various security tamper events
+ */
+typedef enum fsl_shw_tamper_t {
+ FSL_SHW_TAMPER_NONE, /*!< No error detected */
+ FSL_SHW_TAMPER_WTD, /*!< wire-mesh tampering det */
+ FSL_SHW_TAMPER_ETBD, /*!< ext tampering det: input B */
+ FSL_SHW_TAMPER_ETAD, /*!< ext tampering det: input A */
+ FSL_SHW_TAMPER_EBD, /*!< external boot detected */
+ FSL_SHW_TAMPER_SAD, /*!< security alarm detected */
+ FSL_SHW_TAMPER_TTD, /*!< temperature tampering det */
+ FSL_SHW_TAMPER_CTD, /*!< clock tampering det */
+ FSL_SHW_TAMPER_VTD, /*!< voltage tampering det */
+ FSL_SHW_TAMPER_MCO, /*!< monotonic counter overflow */
+ FSL_SHW_TAMPER_TCO, /*!< time counter overflow */
+} fsl_shw_tamper_t;
+
+/*! @} *//* consgrp */
+
+/******************************************************************************
+ * Data Structures
+ *****************************************************************************/
+/*! @addtogroup strgrp
+ @{ */
+
+/* REQ-S2LRD-PINTFC-COA-IBO-001 */
+/*!
+ * Application Initialization Object
+ *
+ * This object, the operations on it, and its interaction with the driver are
+ * TBD.
+ */
+typedef struct fsl_sho_ibo_t {
+} fsl_sho_ibo_t;
+
+/* REQ-S2LRD-PINTFC-COA-UCO-001 */
+/*!
+ * User Context Object
+ *
+ * This object must be initialized by a call to #fsl_shw_uco_init(). It must
+ * then be passed to #fsl_shw_register_user() before it can be used in any
+ * calls besides those in @ref ucoops.
+ *
+ * It contains the user's configuration for the API, for instance whether an
+ * operation should block, or instead should call back the user upon completion
+ * of the operation.
+ *
+ * See @ref ucoops for further information.
+ */
+typedef struct fsl_shw_uco_t { /* fsl_shw_user_context_object */
+} fsl_shw_uco_t;
+
+/* REQ-S2LRD-PINTFC-API-GEN-006 ?? */
+/*!
+ * Result Object
+ *
+ * This object will contain success and failure information about a specific
+ * cryptographic request which has been made.
+ *
+ * No direct access to its members should be made by programs. Instead, the
+ * object should be manipulated using the provided functions. See @ref rops.
+ */
+typedef struct fsl_shw_result_t { /* fsl_shw_result */
+} fsl_shw_result_t;
+
+/*!
+ * Keystore Object
+ *
+ * This object holds the context of a user keystore, including the functions
+ * that define the interface and pointers to where the key data is stored. The
+ * user must supply a set of functions to handle keystore management, including
+ * slot allocation, deallocation, etc. A default keystore manager is provided
+ * as part of the API.
+ *
+ * No direct access to its members should be made by programs. Instead, the
+ * object should be manipulated using the provided functions. See @ref ksoops.
+ */
+typedef struct fsl_shw_kso_t { /* fsl_shw_keystore_object */
+} fsl_shw_kso_t;
+
+/* REQ-S2LRD-PINTFC-COA-SKO-001 */
+/*!
+ * Secret Key Object
+ *
+ * This object contains a key for a cryptographic operation, and information
+ * about its current state, its intended usage, etc. It may instead contain
+ * information about a protected key, or an indication to use a platform-
+ * specific secret key.
+ *
+ * No direct access to its members should be made by programs. Instead, the
+ * object should be manipulated using the provided functions. See @ref skoops.
+ */
+typedef struct fsl_shw_sko_t { /* fsl_shw_secret_key_object */
+} fsl_shw_sko_t;
+
+/* REQ-S2LRD-PINTFC-COA-CO-001 */
+/*!
+ * Platform Capabilities Object
+ *
+ * This object will contain information about the cryptographic features of the
+ * platform which the program is running on.
+ *
+ * No direct access to its members should be made by programs. Instead, the
+ * object should be manipulated using the provided functions.
+ *
+ * See @ref pcoops.
+ */
+typedef struct fsl_shw_pco_t { /* fsl_shw_platform_capabilities_object */
+} fsl_shw_pco_t;
+
+/* REQ-S2LRD-PINTFC-COA-HCO-001 */
+/*!
+ * Hash Context Object
+ *
+ * This object contains information to control hashing functions.
+
+ * No direct access to its members should be made by programs. Instead, the
+ * object should be manipulated using the provided functions. See @ref hcops.
+ */
+typedef struct fsl_shw_hco_t { /* fsl_shw_hash_context_object */
+} fsl_shw_hco_t;
+
+/*!
+ * HMAC Context Object
+ *
+ * This object contains information to control HMAC functions.
+
+ * No direct access to its members should be made by programs. Instead, the
+ * object should be manipulated using the provided functions. See @ref hmcops.
+ */
+typedef struct fsl_shw_hmco_t { /* fsl_shw_hmac_context_object */
+} fsl_shw_hmco_t;
+
+/* REQ-S2LRD-PINTFC-COA-SCCO-001 */
+/*!
+ * Symmetric Cipher Context Object
+ *
+ * This object contains information to control Symmetric Ciphering encrypt and
+ * decrypt functions in #FSL_SYM_MODE_STREAM (ARC4), #FSL_SYM_MODE_ECB,
+ * #FSL_SYM_MODE_CBC, and #FSL_SYM_MODE_CTR modes and the
+ * #fsl_shw_symmetric_encrypt() and #fsl_shw_symmetric_decrypt() functions.
+ * CCM mode is controlled with the #fsl_shw_acco_t object.
+ *
+ * No direct access to its members should be made by programs. Instead, the
+ * object should be manipulated using the provided functions. See @ref sccops.
+ */
+typedef struct fsl_shw_scco_t { /* fsl_shw_symmetric_cipher_context_object */
+} fsl_shw_scco_t;
+
+/*!
+ * Authenticate-Cipher Context Object
+
+ * An object for controlling the function of, and holding information about,
+ * data for the authenticate-cipher functions, #fsl_shw_gen_encrypt() and
+ * #fsl_shw_auth_decrypt().
+ *
+ * No direct access to its members should be made by programs. Instead, the
+ * object should be manipulated using the provided functions. See @ref
+ * accoops.
+ */
+typedef struct fsl_shw_acco_t { /* fsl_shw_authenticate_cipher_context_object */
+} fsl_shw_acco_t;
+ /*! @} *//* strgrp */
+
+/******************************************************************************
+ * Access Macros for Objects
+ *****************************************************************************/
+/*! @addtogroup pcoops
+ @{ */
+
+/*!
+ * Get FSL SHW API version
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @param[out] major A pointer to where the major version
+ * of the API is to be stored.
+ * @param[out] minor A pointer to where the minor version
+ * of the API is to be stored.
+ */
+void fsl_shw_pco_get_version(const fsl_shw_pco_t * pc_info,
+ uint32_t * major, uint32_t * minor);
+
+/*!
+ * Get underlying driver version.
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @param[out] major A pointer to where the major version
+ * of the driver is to be stored.
+ * @param[out] minor A pointer to where the minor version
+ * of the driver is to be stored.
+ */
+void fsl_shw_pco_get_driver_version(const fsl_shw_pco_t * pc_info,
+ uint32_t * major, uint32_t * minor);
+
+/*!
+ * Get list of symmetric algorithms supported.
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @param[out] algorithms A pointer to where to store the location of
+ * the list of algorithms.
+ * @param[out] algorithm_count A pointer to where to store the number of
+ * algorithms in the list at @a algorithms.
+ */
+void fsl_shw_pco_get_sym_algorithms(const fsl_shw_pco_t * pc_info,
+ fsl_shw_key_alg_t * algorithms[],
+ uint8_t * algorithm_count);
+
+/*!
+ * Get list of symmetric modes supported.
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @param[out] modes A pointer to where to store the location of
+ * the list of modes.
+ * @param[out] mode_count A pointer to where to store the number of
+ * algorithms in the list at @a modes.
+ */
+void fsl_shw_pco_get_sym_modes(const fsl_shw_pco_t * pc_info,
+ fsl_shw_sym_mode_t * modes[],
+ uint8_t * mode_count);
+
+/*!
+ * Get list of hash algorithms supported.
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @param[out] algorithms A pointer which will be set to the list of
+ * algorithms.
+ * @param[out] algorithm_count The number of algorithms in the list at @a
+ * algorithms.
+ */
+void fsl_shw_pco_get_hash_algorithms(const fsl_shw_pco_t * pc_info,
+ fsl_shw_hash_alg_t * algorithms[],
+ uint8_t * algorithm_count);
+
+/*!
+ * Determine whether the combination of a given symmetric algorithm and a given
+ * mode is supported.
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @param algorithm A Symmetric Cipher algorithm.
+ * @param mode A Symmetric Cipher mode.
+ *
+ * @return 0 if combination is not supported, non-zero if supported.
+ */
+int fsl_shw_pco_check_sym_supported(const fsl_shw_pco_t * pc_info,
+ fsl_shw_key_alg_t algorithm,
+ fsl_shw_sym_mode_t mode);
+
+/*!
+ * Determine whether a given Encryption-Authentication mode is supported.
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @param mode The Authentication mode.
+ *
+ * @return 0 if mode is not supported, non-zero if supported.
+ */
+int fsl_shw_pco_check_auth_supported(const fsl_shw_pco_t * pc_info,
+ fsl_shw_acc_mode_t mode);
+
+/*!
+ * Determine whether Black Keys (key establishment / wrapping) is supported.
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ *
+ * @return 0 if wrapping is not supported, non-zero if supported.
+ */
+int fsl_shw_pco_check_black_key_supported(const fsl_shw_pco_t * pc_info);
+
+/*!
+ * Get FSL SHW SCC driver version
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @param[out] major A pointer to where the major version
+ * of the SCC driver is to be stored.
+ * @param[out] minor A pointer to where the minor version
+ * of the SCC driver is to be stored.
+ */
+void fsl_shw_pco_get_scc_driver_version(const fsl_shw_pco_t * pc_info,
+ uint32_t * major, uint32_t * minor);
+
+/*!
+ * Get SCM hardware version
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @return The SCM hardware version
+ */
+uint32_t fsl_shw_pco_get_scm_version(const fsl_shw_pco_t * pc_info);
+
+/*!
+ * Get SMN hardware version
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @return The SMN hardware version
+ */
+uint32_t fsl_shw_pco_get_smn_version(const fsl_shw_pco_t * pc_info);
+
+/*!
+ * Get the size of an SCM block, in bytes
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @return The size of an SCM block, in bytes.
+ */
+uint32_t fsl_shw_pco_get_scm_block_size(const fsl_shw_pco_t * pc_info);
+
+/*!
+ * Get size of Black and Red RAM memory
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ * @param[out] black_size A pointer to where the size of the Black RAM, in
+ * blocks, is to be placed.
+ * @param[out] red_size A pointer to where the size of the Red RAM, in
+ * blocks, is to be placed.
+ */
+void fsl_shw_pco_get_smn_size(const fsl_shw_pco_t * pc_info,
+ uint32_t * black_size, uint32_t * red_size);
+
+/*!
+ * Determine whether Secure Partitions are supported
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ *
+ * @return 0 if secure partitions are not supported, non-zero if supported.
+ */
+int fsl_shw_pco_check_spo_supported(const fsl_shw_pco_t * pc_info);
+
+/*!
+ * Get the size of a Secure Partitions
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ *
+ * @return Partition size, in bytes. 0 if Secure Partitions not supported.
+ */
+uint32_t fsl_shw_pco_get_spo_size_bytes(const fsl_shw_pco_t * pc_info);
+
+/*!
+ * Get the number of Secure Partitions on this platform
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ *
+ * @return Number of partitions. 0 if Secure Partitions not supported. Note
+ * that this returns the total number of partitions, though
+ * not all may be available to the user.
+ */
+uint32_t fsl_shw_pco_get_spo_count(const fsl_shw_pco_t * pc_info);
+
+/*!
+ * Determine whether Platform Key features are available
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ *
+ * @return 1 if Programmed Key features are available, otherwise zero.
+ */
+int fsl_shw_pco_check_pk_supported(const fsl_shw_pco_t * pc_info);
+
+/*!
+ * Determine whether Software Key features are available
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ *
+ * @return 1 if Software key features are available, otherwise zero.
+ */
+int fsl_shw_pco_check_sw_keys_supported(const fsl_shw_pco_t * pc_info);
+
+/*! @} *//* pcoops */
+
+/*! @addtogroup ucoops
+ @{ */
+
+/*!
+ * Initialize a User Context Object.
+ *
+ * This function must be called before performing any other operation with the
+ * Object. It sets the User Context Object to initial values, and set the size
+ * of the results pool. The mode will be set to a default of
+ * #FSL_UCO_BLOCKING_MODE.
+ *
+ * When using non-blocking operations, this sets the maximum number of
+ * operations which can be outstanding. This number includes the counts of
+ * operations waiting to start, operation(s) being performed, and results which
+ * have not been retrieved.
+ *
+ * Changes to this value are ignored once user registration has completed. It
+ * should be set to 1 if only blocking operations will ever be performed.
+ *
+ * @param user_ctx The User Context object to operate on.
+ * @param pool_size The maximum number of operations which can be
+ * outstanding.
+ */
+void fsl_shw_uco_init(fsl_shw_uco_t * user_ctx, uint16_t pool_size);
+
+/*!
+ * Set the User Reference for the User Context.
+ *
+ * @param user_ctx The User Context object to operate on.
+ * @param reference A value which will be passed back with a result.
+ */
+void fsl_shw_uco_set_reference(fsl_shw_uco_t * user_ctx, uint32_t reference);
+
+/*!
+ * Set the callback routine for the User Context.
+ *
+ * Note that the callback routine may be called when no results are available,
+ * and possibly even when no requests are outstanding.
+ *
+ *
+ * @param user_ctx The User Context object to operate on.
+ * @param callback_fn The function the API will invoke when an operation
+ * completes.
+ */
+void fsl_shw_uco_set_callback(fsl_shw_uco_t * user_ctx,
+ void (*callback_fn) (fsl_shw_uco_t * uco));
+
+/*!
+ * Set flags in the User Context.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param user_ctx The User Context object to operate on.
+ * @param flags ORed values from #fsl_shw_user_ctx_flags_t.
+ */
+void fsl_shw_uco_set_flags(fsl_shw_uco_t * user_ctx, uint32_t flags);
+
+/*!
+ * Clear flags in the User Context.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param user_ctx The User Context object to operate on.
+ * @param flags ORed values from #fsl_shw_user_ctx_flags_t.
+ */
+void fsl_shw_uco_clear_flags(fsl_shw_uco_t * user_ctx, uint32_t flags);
+
+/*!
+ * Select a key for the key-wrap key for key wrapping/unwrapping
+ *
+ * Without a call to this function, default is FSL_SHW_PF_KEY_IIM. The wrap
+ * key is used to encrypt and decrypt the per-key random secret which is used
+ * to calculate the key which will encrypt/decrypt the user's key.
+ *
+ * @param user_ctx The User Context object to operate on.
+ * @param pf_key Which key to use. Valid choices are
+ * #FSL_SHW_PF_KEY_IIM, #FSL_SHW_PF_KEY_RND, and
+ * #FSL_SHW_PF_KEY_IIM_RND.
+ */
+void fsl_shw_uco_set_wrap_key(fsl_shw_uco_t * user_ctx,
+ fsl_shw_pf_key_t pf_key);
+
+ /*! @} *//* ucoops */
+
+/*! @addtogroup rops
+ @{ */
+
+/*!
+ * Retrieve the status code from a Result Object.
+ *
+ * @param result The result object to query.
+ *
+ * @return The status of the request.
+ */
+fsl_shw_return_t fsl_shw_ro_get_status(fsl_shw_result_t * result);
+
+/*!
+ * Retrieve the reference value from a Result Object.
+ *
+ * @param result The result object to query.
+ *
+ * @return The reference associated with the request.
+ */
+uint32_t fsl_shw_ro_get_reference(fsl_shw_result_t * result);
+
+ /* @} *//* rops */
+
+/*! @addtogroup skoops
+ @{ */
+
+/*!
+ * Initialize a Secret Key Object.
+ *
+ * This function or #fsl_shw_sko_init_pf_key() must be called before performing
+ * any other operation with the Object.
+ *
+ * @param key_info The Secret Key Object to be initialized.
+ * @param algorithm DES, AES, etc.
+ *
+ */
+void fsl_shw_sko_init(fsl_shw_sko_t * key_info, fsl_shw_key_alg_t algorithm);
+
+/*!
+ * Initialize a Secret Key Object to use a Platform Key register.
+ *
+ * This function or #fsl_shw_sko_init() must be called before performing any
+ * other operation with the Object. #fsl_shw_sko_set_key() does not work on
+ * a key object initialized in this way.
+ *
+ * If this function is used to initialize the key object, but no key is
+ * established with the key object, then the object will refer strictly to the
+ * key value specified by the @c pf_key selection.
+ *
+ * If the pf key is #FSL_SHW_PF_KEY_PRG or #FSL_SHW_PF_KEY_IIM_PRG, then the
+ * key object may be used with #fsl_shw_establish_key() to change the Program
+ * Key value. When the pf key is neither #FSL_SHW_PF_KEY_PRG nor
+ * #FSL_SHW_PF_KEY_IIM_PRG, it is an error to call #fsl_shw_establish_key().
+ *
+ * @param key_info The Secret Key Object to be initialized.
+ * @param algorithm DES, AES, etc.
+ * @param pf_key Which platform key is referenced.
+ */
+void fsl_shw_sko_init_pf_key(fsl_shw_sko_t * key_info,
+ fsl_shw_key_alg_t algorithm,
+ fsl_shw_pf_key_t pf_key);
+
+/*!
+ * Store a cleartext key in the key object.
+ *
+ * This has the side effect of setting the #FSL_SKO_KEY_PRESENT flag. It should
+ * not be used if there is a key established with the key object. If there is,
+ * a call to #fsl_shw_release_key() should be made first.
+ *
+ * @param key_object A variable of type #fsl_shw_sko_t.
+ * @param key A pointer to the beginning of the key.
+ * @param key_length The length, in octets, of the key. The value should be
+ * appropriate to the key size supported by the algorithm.
+ * 64 octets is the absolute maximum value allowed for this
+ * call.
+ */
+void fsl_shw_sko_set_key(fsl_shw_sko_t * key_object,
+ const uint8_t * key, uint16_t key_length);
+
+/*!
+ * Set a size for the key.
+ *
+ * This function would normally be used when the user wants the key to be
+ * generated from a random source.
+ *
+ * @param key_object A variable of type #fsl_shw_sko_t.
+ * @param key_length The length, in octets, of the key. The value should be
+ * appropriate to the key size supported by the algorithm.
+ * 64 octets is the absolute maximum value allowed for this
+ * call.
+ */
+void fsl_shw_sko_set_key_length(fsl_shw_sko_t * key_object,
+ uint16_t key_length);
+
+/*!
+ * Set the User ID associated with the key.
+ *
+ * @param key_object A variable of type #fsl_shw_sko_t.
+ * @param userid The User ID to identify authorized users of the key.
+ */
+void fsl_shw_sko_set_user_id(fsl_shw_sko_t * key_object, key_userid_t userid);
+
+/*!
+ * Set the keystore that the key will be stored in.
+ *
+ * @param key_object A variable of type #fsl_shw_sko_t.
+ * @param keystore The keystore to place the key in. This is a variable of
+ * type #fsl_shw_kso_t.
+ */
+void fsl_shw_sko_set_keystore(fsl_shw_sko_t * key_object,
+ fsl_shw_kso_t * keystore);
+
+/*!
+ * Set the establish key handle into a key object.
+ *
+ * The @a userid field will be used to validate the access to the unwrapped
+ * key. This feature is not available for all platforms, nor for all
+ * algorithms and modes.
+ *
+ * The #FSL_SKO_KEY_ESTABLISHED will be set (and the #FSL_SKO_KEY_PRESENT
+ * flag will be cleared).
+ *
+ * @param key_object A variable of type #fsl_shw_sko_t.
+ * @param userid The User ID to verify this user is an authorized user of
+ * the key.
+ * @param handle A @a handle from #fsl_shw_sko_get_established_info.
+ */
+void fsl_shw_sko_set_established_info(fsl_shw_sko_t * key_object,
+ key_userid_t userid, uint32_t handle);
+
+/*!
+ * Extract the algorithm from a key object.
+ *
+ * @param key_info The Key Object to be queried.
+ * @param[out] algorithm A pointer to the location to store the algorithm.
+ */
+void fsl_shw_sko_get_algorithm(const fsl_shw_sko_t * key_info,
+ fsl_shw_key_alg_t * algorithm);
+
+/*!
+ * Retrieve the cleartext key from a key object that is stored in a user
+ * keystore.
+ *
+ * @param skobject The Key Object to be queried.
+ * @param[out] skkey A pointer to the location to store the key. NULL
+ * if the key is not stored in a user keystore.
+ */
+void fsl_shw_sko_get_key(const fsl_shw_sko_t * skobject, void *skkey);
+
+/*!
+ * Retrieve the established-key handle from a key object.
+ *
+ * @param key_object A variable of type #fsl_shw_sko_t.
+ * @param handle The location to store the @a handle of the unwrapped
+ * key.
+ */
+void fsl_shw_sko_get_established_info(fsl_shw_sko_t * key_object,
+ uint32_t * handle);
+
+/*!
+ * Determine the size of a wrapped key based upon the cleartext key's length.
+ *
+ * This function can be used to calculate the number of octets that
+ * #fsl_shw_extract_key() will write into the location at @a covered_key.
+ *
+ * If zero is returned at @a length, this means that the key length in
+ * @a key_info is not supported.
+ *
+ * @param key_info Information about a key to be wrapped.
+ * @param length Location to store the length of a wrapped
+ * version of the key in @a key_info.
+ */
+void fsl_shw_sko_calculate_wrapped_size(const fsl_shw_sko_t * key_info,
+ uint32_t * length);
+
+/*!
+ * Set some flags in the key object.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param key_object A variable of type #fsl_shw_sko_t.
+ * @param flags (One or more) ORed members of #fsl_shw_key_flags_t which
+ * are to be set.
+ */
+void fsl_shw_sko_set_flags(fsl_shw_sko_t * key_object, uint32_t flags);
+
+/*!
+ * Clear some flags in the key object.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param key_object A variable of type #fsl_shw_sko_t.
+ * @param flags (One or more) ORed members of #fsl_shw_key_flags_t which
+ * are to be reset.
+ */
+void fsl_shw_sko_clear_flags(fsl_shw_sko_t * key_object, uint32_t flags);
+
+ /*! @} *//* end skoops */
+
+/*****************************************************************************/
+
+/*! @addtogroup hcops
+ @{ */
+
+/*****************************************************************************/
+/* REQ-S2LRD-PINTFC-API-BASIC-HASH-004 - partially */
+/*!
+ * Initialize a Hash Context Object.
+ *
+ * This function must be called before performing any other operation with the
+ * Object. It sets the current message length and hash algorithm in the hash
+ * context object.
+ *
+ * @param hash_ctx The hash context to operate upon.
+ * @param algorithm The hash algorithm to be used (#FSL_HASH_ALG_MD5,
+ * #FSL_HASH_ALG_SHA256, etc).
+ *
+ */
+void fsl_shw_hco_init(fsl_shw_hco_t * hash_ctx, fsl_shw_hash_alg_t algorithm);
+
+/*****************************************************************************/
+/* REQ-S2LRD-PINTFC-API-BASIC-HASH-001 */
+/* REQ-S2LRD-PINTFC-API-BASIC-HASH-002 */
+/*!
+ * Get the current hash value and message length from the hash context object.
+ *
+ * The algorithm must have already been specified. See #fsl_shw_hco_init().
+ *
+ * @param hash_ctx The hash context to query.
+ * @param[out] digest Pointer to the location of @a length octets where to
+ * store a copy of the current value of the digest.
+ * @param length Number of octets of hash value to copy.
+ * @param[out] msg_length Pointer to the location to store the number of octets
+ * already hashed.
+ */
+void fsl_shw_hco_get_digest(const fsl_shw_hco_t * hash_ctx, uint8_t * digest,
+ uint8_t length, uint32_t * msg_length);
+
+/*****************************************************************************/
+/* REQ-S2LRD-PINTFC-API-BASIC-HASH-002 - partially */
+/*!
+ * Get the hash algorithm from the hash context object.
+ *
+ * @param hash_ctx The hash context to query.
+ * @param[out] algorithm Pointer to where the algorithm is to be stored.
+ */
+void fsl_shw_hco_get_info(const fsl_shw_hco_t * hash_ctx,
+ fsl_shw_hash_alg_t * algorithm);
+
+/*****************************************************************************/
+/* REQ-S2LRD-PINTFC-API-BASIC-HASH-003 */
+/* REQ-S2LRD-PINTFC-API-BASIC-HASH-004 */
+/*!
+ * Set the current hash value and message length in the hash context object.
+ *
+ * The algorithm must have already been specified. See #fsl_shw_hco_init().
+ *
+ * @param hash_ctx The hash context to operate upon.
+ * @param context Pointer to buffer of appropriate length to copy into
+ * the hash context object.
+ * @param msg_length The number of octets of the message which have
+ * already been hashed.
+ *
+ */
+void fsl_shw_hco_set_digest(fsl_shw_hco_t * hash_ctx, const uint8_t * context,
+ uint32_t msg_length);
+
+/*!
+ * Set flags in a Hash Context Object.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param hash_ctx The hash context to be operated on.
+ * @param flags The flags to be set in the context. These can be ORed
+ * members of #fsl_shw_hash_ctx_flags_t.
+ */
+void fsl_shw_hco_set_flags(fsl_shw_hco_t * hash_ctx, uint32_t flags);
+
+/*!
+ * Clear flags in a Hash Context Object.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param hash_ctx The hash context to be operated on.
+ * @param flags The flags to be reset in the context. These can be ORed
+ * members of #fsl_shw_hash_ctx_flags_t.
+ */
+void fsl_shw_hco_clear_flags(fsl_shw_hco_t * hash_ctx, uint32_t flags);
+
+ /*! @} *//* end hcops */
+
+/*****************************************************************************/
+
+/*! @addtogroup hmcops
+ @{ */
+
+/*!
+ * Initialize an HMAC Context Object.
+ *
+ * This function must be called before performing any other operation with the
+ * Object. It sets the current message length and hash algorithm in the HMAC
+ * context object.
+ *
+ * @param hmac_ctx The HMAC context to operate upon.
+ * @param algorithm The hash algorithm to be used (#FSL_HASH_ALG_MD5,
+ * #FSL_HASH_ALG_SHA256, etc).
+ *
+ */
+void fsl_shw_hmco_init(fsl_shw_hmco_t * hmac_ctx, fsl_shw_hash_alg_t algorithm);
+
+/*!
+ * Set flags in an HMAC Context Object.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param hmac_ctx The HMAC context to be operated on.
+ * @param flags The flags to be set in the context. These can be ORed
+ * members of #fsl_shw_hmac_ctx_flags_t.
+ */
+void fsl_shw_hmco_set_flags(fsl_shw_hmco_t * hmac_ctx, uint32_t flags);
+
+/*!
+ * Clear flags in an HMAC Context Object.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param hmac_ctx The HMAC context to be operated on.
+ * @param flags The flags to be reset in the context. These can be ORed
+ * members of #fsl_shw_hmac_ctx_flags_t.
+ */
+void fsl_shw_hmco_clear_flags(fsl_shw_hmco_t * hmac_ctx, uint32_t flags);
+
+/*! @} */
+
+/*****************************************************************************/
+
+/*! @addtogroup sccops
+ @{ */
+
+/*!
+ * Initialize a Symmetric Cipher Context Object.
+ *
+ * This function must be called before performing any other operation with the
+ * Object. This will set the @a mode and @a algorithm and initialize the
+ * Object.
+ *
+ * @param sym_ctx The context object to operate on.
+ * @param algorithm The cipher algorithm this context will be used with.
+ * @param mode #FSL_SYM_MODE_CBC, #FSL_SYM_MODE_ECB, etc.
+ *
+ */
+void fsl_shw_scco_init(fsl_shw_scco_t * sym_ctx,
+ fsl_shw_key_alg_t algorithm, fsl_shw_sym_mode_t mode);
+
+/*!
+ * Set the flags for a Symmetric Cipher Context.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param sym_ctx The context object to operate on.
+ * @param flags The flags to reset (one or more values from
+ * #fsl_shw_sym_ctx_flags_t ORed together).
+ *
+ */
+void fsl_shw_scco_set_flags(fsl_shw_scco_t * sym_ctx, uint32_t flags);
+
+/*!
+ * Clear some flags in a Symmetric Cipher Context Object.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param sym_ctx The context object to operate on.
+ * @param flags The flags to reset (one or more values from
+ * #fsl_shw_sym_ctx_flags_t ORed together).
+ *
+ */
+void fsl_shw_scco_clear_flags(fsl_shw_scco_t * sym_ctx, uint32_t flags);
+
+/*!
+ * Set the Context (IV) for a Symmetric Cipher Context.
+ *
+ * This is to set the context/IV for #FSL_SYM_MODE_CBC mode, or to set the
+ * context (the S-Box and pointers) for ARC4. The full context size will
+ * be copied.
+ *
+ * @param sym_ctx The context object to operate on.
+ * @param context A pointer to the buffer which contains the context.
+ *
+ */
+void fsl_shw_scco_set_context(fsl_shw_scco_t * sym_ctx, uint8_t * context);
+
+/*!
+ * Get the Context for a Symmetric Cipher Context.
+ *
+ * This is to retrieve the context/IV for #FSL_SYM_MODE_CBC mode, or to
+ * retrieve context (the S-Box and pointers) for ARC4. The full context
+ * will be copied.
+ *
+ * @param sym_ctx The context object to operate on.
+ * @param[out] context Pointer to location where context will be stored.
+ */
+void fsl_shw_scco_get_context(const fsl_shw_scco_t * sym_ctx,
+ uint8_t * context);
+
+/*!
+ * Set the Counter Value for a Symmetric Cipher Context.
+ *
+ * This will set the Counter Value for CTR mode.
+ *
+ * @param sym_ctx The context object to operate on.
+ * @param counter The starting counter value. The number of octets.
+ * copied will be the block size for the algorithm.
+ * @param modulus The modulus for controlling the incrementing of the counter.
+ *
+ */
+void fsl_shw_scco_set_counter_info(fsl_shw_scco_t * sym_ctx,
+ const uint8_t * counter,
+ fsl_shw_ctr_mod_t modulus);
+
+/*!
+ * Get the Counter Value for a Symmetric Cipher Context.
+ *
+ * This will retrieve the Counter Value is for CTR mode.
+ *
+ * @param sym_ctx The context object to query.
+ * @param[out] counter Pointer to location to store the current counter
+ * value. The number of octets copied will be the
+ * block size for the algorithm.
+ * @param[out] modulus Pointer to location to store the modulus.
+ *
+ */
+void fsl_shw_scco_get_counter_info(const fsl_shw_scco_t * sym_ctx,
+ uint8_t * counter,
+ fsl_shw_ctr_mod_t * modulus);
+
+ /*! @} *//* end sccops */
+
+/*****************************************************************************/
+
+/*! @addtogroup accoops
+ @{ */
+
+/*!
+ * Initialize a Authentication-Cipher Context.
+ *
+ * @param auth_object Pointer to object to operate on.
+ * @param mode The mode for this object (only #FSL_ACC_MODE_CCM
+ * supported).
+ */
+void fsl_shw_acco_init(fsl_shw_acco_t * auth_object, fsl_shw_acc_mode_t mode);
+
+/*!
+ * Set the flags for a Authentication-Cipher Context.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param auth_object Pointer to object to operate on.
+ * @param flags The flags to set (one or more from
+ * #fsl_shw_auth_ctx_flags_t ORed together).
+ *
+ */
+void fsl_shw_acco_set_flags(fsl_shw_acco_t * auth_object, uint32_t flags);
+
+/*!
+ * Clear some flags in a Authentication-Cipher Context Object.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param auth_object Pointer to object to operate on.
+ * @param flags The flags to reset (one or more from
+ * #fsl_shw_auth_ctx_flags_t ORed together).
+ *
+ */
+void fsl_shw_acco_clear_flags(fsl_shw_acco_t * auth_object, uint32_t flags);
+
+/*!
+ * Set up the Authentication-Cipher Object for CCM mode.
+ *
+ * This will set the @a auth_object for CCM mode and save the @a ctr,
+ * and @a mac_length. This function can be called instead of
+ * #fsl_shw_acco_init().
+ *
+ * The parameter @a ctr is Counter Block 0, (counter value 0), which is for the
+ * MAC.
+ *
+ * @param auth_object Pointer to object to operate on.
+ * @param algorithm Cipher algorithm. Only AES is supported.
+ * @param ctr The initial counter value.
+ * @param mac_length The number of octets used for the MAC. Valid values are
+ * 4, 6, 8, 10, 12, 14, and 16.
+ */
+void fsl_shw_acco_set_ccm(fsl_shw_acco_t * auth_object,
+ fsl_shw_key_alg_t algorithm,
+ const uint8_t * ctr, uint8_t mac_length);
+
+/*!
+ * Format the First Block (IV) & Initial Counter Value per NIST CCM.
+ *
+ * This function will also set the IV and CTR values per Appendix A of NIST
+ * Special Publication 800-38C (May 2004). It will also perform the
+ * #fsl_shw_acco_set_ccm() operation with information derived from this set of
+ * parameters.
+ *
+ * Note this function assumes the algorithm is AES. It initializes the
+ * @a auth_object by setting the mode to #FSL_ACC_MODE_CCM and setting the
+ * flags to be #FSL_ACCO_NIST_CCM.
+ *
+ * @param auth_object Pointer to object to operate on.
+ * @param t_length The number of octets used for the MAC. Valid values are
+ * 4, 6, 8, 10, 12, 14, and 16.
+ * @param ad_length Number of octets of Associated Data (may be zero).
+ * @param q_length A value for the size of the length of @a q field. Valid
+ * values are 1-8.
+ * @param n The Nonce (packet number or other changing value). Must
+ * be (15 - @a q_length) octets long.
+ * @param q The value of Q (size of the payload in octets).
+ *
+ */
+void fsl_shw_ccm_nist_format_ctr_and_iv(fsl_shw_acco_t * auth_object,
+ uint8_t t_length,
+ uint32_t ad_length,
+ uint8_t q_length,
+ const uint8_t * n, uint32_t q);
+
+/*!
+ * Update the First Block (IV) & Initial Counter Value per NIST CCM.
+ *
+ * This function will set the IV and CTR values per Appendix A of NIST Special
+ * Publication 800-38C (May 2004).
+ *
+ * Note this function assumes that #fsl_shw_ccm_nist_format_ctr_and_iv() has
+ * previously been called on the @a auth_object.
+ *
+ * @param auth_object Pointer to object to operate on.
+ * @param n The Nonce (packet number or other changing value). Must
+ * be (15 - @a q_length) octets long.
+ * @param q The value of Q (size of the payload in octets).
+ *
+ */
+void fsl_shw_ccm_nist_update_ctr_and_iv(fsl_shw_acco_t * auth_object,
+ const uint8_t * n, uint32_t q);
+
+ /* @} *//* accoops */
+
+/******************************************************************************
+ * Library functions
+ *****************************************************************************/
+
+/*! @addtogroup miscfuns
+ @{ */
+
+/* REQ-S2LRD-PINTFC-API-GEN-003 */
+/*!
+ * Determine the hardware security capabilities of this platform.
+ *
+ * Though a user context object is passed into this function, it will always
+ * act in a non-blocking manner.
+ *
+ * @param user_ctx The user context which will be used for the query.
+ *
+ * @return A pointer to the capabilities object.
+ */
+extern fsl_shw_pco_t *fsl_shw_get_capabilities(fsl_shw_uco_t * user_ctx);
+
+/* REQ-S2LRD-PINTFC-API-GEN-004 */
+/*!
+ * Create an association between the user and the provider of the API.
+ *
+ * @param user_ctx The user context which will be used for this association.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_register_user(fsl_shw_uco_t * user_ctx);
+
+/* REQ-S2LRD-PINTFC-API-GEN-005 */
+/*!
+ * Destroy the association between the user and the provider of the API.
+ *
+ * @param user_ctx The user context which is no longer needed.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_deregister_user(fsl_shw_uco_t * user_ctx);
+
+/* REQ-S2LRD-PINTFC-API-GEN-006 */
+/*!
+ * Retrieve results from earlier operations.
+ *
+ * @param user_ctx The user's context.
+ * @param result_size The number of array elements of @a results.
+ * @param[in,out] results Pointer to first of the (array of) locations to
+ * store results.
+ * @param[out] result_count Pointer to store the number of results which
+ * were returned.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_get_results(fsl_shw_uco_t * user_ctx,
+ uint16_t result_size,
+ fsl_shw_result_t results[],
+ uint16_t * result_count);
+
+/*!
+ * Allocate a block of secure memory
+ *
+ * @param user_ctx User context
+ * @param size Memory size (octets). Note: currently only
+ * supports only single-partition sized blocks.
+ * @param UMID User Mode ID to use when registering the
+ * partition.
+ * @param permissions Permissions to initialize the partition with.
+ * Can be made by ORing flags from the
+ * #fsl_shw_permission_t.
+ *
+ * @return Address of the allocated memory. NULL if the
+ * call was not successful.
+ */
+extern void *fsl_shw_smalloc(fsl_shw_uco_t * user_ctx,
+ uint32_t size,
+ const uint8_t * UMID, uint32_t permissions);
+
+/*!
+ * Free a block of secure memory that was allocated with #fsl_shw_smalloc
+ *
+ * @param user_ctx User context
+ * @param address Address of the block of secure memory to be
+ * released.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_sfree(fsl_shw_uco_t * user_ctx, void *address);
+
+/*!
+ * Diminish the permissions of a block of secure memory. Note that permissions
+ * can only be revoked.
+ *
+ * @param user_ctx User context
+ * @param address Base address of the secure memory to work with
+ * @param permissions Permissions to initialize the partition with.
+ * Can be made by ORing flags from the
+ * #fsl_shw_permission_t.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_diminish_perms(fsl_shw_uco_t * user_ctx,
+ void *address,
+ uint32_t permissions);
+
+/*!
+ * @brief Encrypt a region of secure memory using the hardware secret key
+ *
+ * @param user_ctx User context
+ * @param partition_base Base address of the partition
+ * @param offset_bytes Offset of data from the partition base
+ * @param byte_count Length of the data to encrypt
+ * @param black_data Location to store the encrypted data
+ * @param IV IV to use for the encryption routine
+ * @param cypher_mode Cyphering mode to use, specified by type
+ * #fsl_shw_cypher_mode_t
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t
+do_scc_encrypt_region(fsl_shw_uco_t * user_ctx,
+ void *partition_base, uint32_t offset_bytes,
+ uint32_t byte_count, uint8_t * black_data,
+ uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode);
+
+/*!
+ * @brief Decrypt a region of secure memory using the hardware secret key
+ *
+ * @param user_ctx User context
+ * @param partition_base Base address of the partition
+ * @param offset_bytes Offset of data from the partition base
+ * @param byte_count Length of the data to encrypt
+ * @param black_data Location to store the encrypted data
+ * @param IV IV to use for the encryption routine
+ * @param cypher_mode Cyphering mode to use, specified by type
+ * #fsl_shw_cypher_mode_t
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t
+do_scc_decrypt_region(fsl_shw_uco_t * user_ctx,
+ void *partition_base, uint32_t offset_bytes,
+ uint32_t byte_count, const uint8_t * black_data,
+ uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode);
+
+ /*! @} *//* miscfuns */
+
+/*! @addtogroup opfuns
+ @{ */
+
+/* REQ-S2LRD-PINTFC-API-BASIC-SYM-002 */
+/* PINTFC-API-BASIC-SYM-ARC4-001 */
+/* PINTFC-API-BASIC-SYM-ARC4-002 */
+/*!
+ * Encrypt a stream of data with a symmetric-key algorithm.
+ *
+ * In ARC4, and also in #FSL_SYM_MODE_CBC and #FSL_SYM_MODE_CTR modes, the
+ * flags of the @a sym_ctx object will control part of the operation of this
+ * function. The #FSL_SYM_CTX_INIT flag means that there is no context info in
+ * the object. The #FSL_SYM_CTX_LOAD means to use information in the
+ * @a sym_ctx at the start of the operation, and the #FSL_SYM_CTX_SAVE flag
+ * means to update the object's context information after the operation has
+ * been performed.
+ *
+ * All of the data for an operation can be run through at once using the
+ * #FSL_SYM_CTX_INIT or #FSL_SYM_CTX_LOAD flags, as appropriate, and then using
+ * a @a length for the whole of the data.
+ *
+ * If a #FSL_SYM_CTX_SAVE flag were added, an additional call to the function
+ * would "pick up" where the previous call left off, allowing the user to
+ * perform the larger function in smaller steps.
+ *
+ * In #FSL_SYM_MODE_CBC and #FSL_SYM_MODE_ECB modes, the @a length must always
+ * be a multiple of the block size for the algorithm being used. For proper
+ * operation in #FSL_SYM_MODE_CTR mode, the @a length must be a multiple of the
+ * block size until the last operation on the total octet stream.
+ *
+ * Some users of ARC4 may want to compute the context (S-Box and pointers) from
+ * the key before any data is available. This may be done by running this
+ * function with a @a length of zero, with the init & save flags flags on in
+ * the @a sym_ctx. Subsequent operations would then run as normal with the
+ * load and save flags. Note that they key object is still required.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param key_info Key and algorithm being used for this operation.
+ * @param[in,out] sym_ctx Info on cipher mode, state of the cipher.
+ * @param length Length, in octets, of the pt (and ct).
+ * @param pt pointer to plaintext to be encrypted.
+ * @param[out] ct pointer to where to store the resulting ciphertext.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ *
+ */
+extern fsl_shw_return_t fsl_shw_symmetric_encrypt(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ fsl_shw_scco_t * sym_ctx,
+ uint32_t length,
+ const uint8_t * pt,
+ uint8_t * ct);
+
+/* PINTFC-API-BASIC-SYM-002 */
+/* PINTFC-API-BASIC-SYM-ARC4-001 */
+/* PINTFC-API-BASIC-SYM-ARC4-002 */
+/*!
+ * Decrypt a stream of data with a symmetric-key algorithm.
+ *
+ * In ARC4, and also in #FSL_SYM_MODE_CBC and #FSL_SYM_MODE_CTR modes, the
+ * flags of the @a sym_ctx object will control part of the operation of this
+ * function. The #FSL_SYM_CTX_INIT flag means that there is no context info in
+ * the object. The #FSL_SYM_CTX_LOAD means to use information in the
+ * @a sym_ctx at the start of the operation, and the #FSL_SYM_CTX_SAVE flag
+ * means to update the object's context information after the operation has
+ * been performed.
+ *
+ * All of the data for an operation can be run through at once using the
+ * #FSL_SYM_CTX_INIT or #FSL_SYM_CTX_LOAD flags, as appropriate, and then using
+ * a @a length for the whole of the data.
+ *
+ * If a #FSL_SYM_CTX_SAVE flag were added, an additional call to the function
+ * would "pick up" where the previous call left off, allowing the user to
+ * perform the larger function in smaller steps.
+ *
+ * In #FSL_SYM_MODE_CBC and #FSL_SYM_MODE_ECB modes, the @a length must always
+ * be a multiple of the block size for the algorithm being used. For proper
+ * operation in #FSL_SYM_MODE_CTR mode, the @a length must be a multiple of the
+ * block size until the last operation on the total octet stream.
+ *
+ * Some users of ARC4 may want to compute the context (S-Box and pointers) from
+ * the key before any data is available. This may be done by running this
+ * function with a @a length of zero, with the #FSL_SYM_CTX_INIT &
+ * #FSL_SYM_CTX_SAVE flags on in the @a sym_ctx. Subsequent operations would
+ * then run as normal with the load & save flags. Note that they key object is
+ * still required.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param key_info The key and algorithm being used in this operation.
+ * @param[in,out] sym_ctx Info on cipher mode, state of the cipher.
+ * @param length Length, in octets, of the ct (and pt).
+ * @param ct pointer to ciphertext to be decrypted.
+ * @param[out] pt pointer to where to store the resulting plaintext.
+ *
+ * @return A return code of type #fsl_shw_return_t
+ *
+ */
+extern fsl_shw_return_t fsl_shw_symmetric_decrypt(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ fsl_shw_scco_t * sym_ctx,
+ uint32_t length,
+ const uint8_t * ct,
+ uint8_t * pt);
+
+/* REQ-S2LRD-PINTFC-API-BASIC-HASH-005 */
+/*!
+ * Hash a stream of data with a cryptographic hash algorithm.
+ *
+ * The flags in the @a hash_ctx control the operation of this function.
+ *
+ * Hashing functions work on 64 octets of message at a time. Therefore, when
+ * any partial hashing of a long message is performed, the message @a length of
+ * each segment must be a multiple of 64. When ready to
+ * #FSL_HASH_FLAGS_FINALIZE the hash, the @a length may be any value.
+ *
+ * With the #FSL_HASH_FLAGS_INIT and #FSL_HASH_FLAGS_FINALIZE flags on, a
+ * one-shot complete hash, including padding, will be performed. The @a length
+ * may be any value.
+ *
+ * The first octets of a data stream can be hashed by setting the
+ * #FSL_HASH_FLAGS_INIT and #FSL_HASH_FLAGS_SAVE flags. The @a length must be
+ * a multiple of 64.
+ *
+ * The flag #FSL_HASH_FLAGS_LOAD is used to load a context previously saved by
+ * #FSL_HASH_FLAGS_SAVE. The two in combination will allow a (multiple-of-64
+ * octets) 'middle sequence' of the data stream to be hashed with the
+ * beginning. The @a length must again be a multiple of 64.
+ *
+ * Since the flag #FSL_HASH_FLAGS_LOAD is used to load a context previously
+ * saved by #FSL_HASH_FLAGS_SAVE, the #FSL_HASH_FLAGS_LOAD and
+ * #FSL_HASH_FLAGS_FINALIZE flags, used together, can be used to finish the
+ * stream. The @a length may be any value.
+ *
+ * If the user program wants to do the padding for the hash, it can leave off
+ * the #FSL_HASH_FLAGS_FINALIZE flag. The @a length must then be a multiple of
+ * 64 octets.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param[in,out] hash_ctx Hashing algorithm and state of the cipher.
+ * @param msg Pointer to the data to be hashed.
+ * @param length Length, in octets, of the @a msg.
+ * @param[out] result If not null, pointer to where to store the hash
+ * digest.
+ * @param result_len Number of octets to store in @a result.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_hash(fsl_shw_uco_t * user_ctx,
+ fsl_shw_hco_t * hash_ctx,
+ const uint8_t * msg,
+ uint32_t length,
+ uint8_t * result, uint32_t result_len);
+
+/* REQ-S2LRD-PINTFC-API-BASIC-HMAC-001 */
+/*!
+ * Precompute the Key hashes for an HMAC operation.
+ *
+ * This function may be used to calculate the inner and outer precomputes,
+ * which are the hash contexts resulting from hashing the XORed key for the
+ * 'inner hash' and the 'outer hash', respectively, of the HMAC function.
+ *
+ * After execution of this function, the @a hmac_ctx will contain the
+ * precomputed inner and outer contexts, so that they may be used by
+ * #fsl_shw_hmac(). The flags of @a hmac_ctx will be updated with
+ * #FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT to mark their presence. In addition, the
+ * #FSL_HMAC_FLAGS_INIT flag will be set.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param key_info The key being used in this operation. Key must be
+ * 1 to 64 octets long.
+ * @param[in,out] hmac_ctx The context which controls, by its flags and
+ * algorithm, the operation of this function.
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_hmac_precompute(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ fsl_shw_hmco_t * hmac_ctx);
+
+/* REQ-S2LRD-PINTFC-API-BASIC-HMAC-002 */
+/*!
+ * Continue, finalize, or one-shot an HMAC operation.
+ *
+ * There are a number of ways to use this function. The flags in the
+ * @a hmac_ctx object will determine what operations occur.
+ *
+ * If #FSL_HMAC_FLAGS_INIT is set, then the hash will be started either from
+ * the @a key_info, or from the precomputed inner hash value in the
+ * @a hmac_ctx, depending on the value of #FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT.
+ *
+ * If, instead, #FSL_HMAC_FLAGS_LOAD is set, then the hash will be continued
+ * from the ongoing inner hash computation in the @a hmac_ctx.
+ *
+ * If #FSL_HMAC_FLAGS_FINALIZE are set, then the @a msg will be padded, hashed,
+ * the outer hash will be performed, and the @a result will be generated.
+ *
+ * If the #FSL_HMAC_FLAGS_SAVE flag is set, then the (ongoing or final) digest
+ * value will be stored in the ongoing inner hash computation field of the @a
+ * hmac_ctx.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param key_info If #FSL_HMAC_FLAGS_INIT is set in the @a hmac_ctx,
+ * this is the key being used in this operation, and the
+ * IPAD. If #FSL_HMAC_FLAGS_INIT is set in the @a
+ * hmac_ctx and @a key_info is NULL, then
+ * #fsl_shw_hmac_precompute() has been used to populate
+ * the @a inner_precompute and @a outer_precompute
+ * contexts. If #FSL_HMAC_FLAGS_INIT is not set, this
+ * parameter is ignored.
+
+ * @param[in,out] hmac_ctx The context which controls, by its flags and
+ * algorithm, the operation of this function.
+ * @param msg Pointer to the message to be hashed.
+ * @param length Length, in octets, of the @a msg.
+ * @param[out] result Pointer, of @a result_len octets, to where to
+ * store the HMAC.
+ * @param result_len Length of @a result buffer.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_hmac(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ fsl_shw_hmco_t * hmac_ctx,
+ const uint8_t * msg,
+ uint32_t length,
+ uint8_t * result, uint32_t result_len);
+
+/* REQ-S2LRD-PINTFC-API-BASIC-RNG-002 */
+/*!
+ * Get random data.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param length The number of octets of @a data being requested.
+ * @param[out] data A pointer to a location of @a length octets to where
+ * random data will be returned.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_get_random(fsl_shw_uco_t * user_ctx,
+ uint32_t length, uint8_t * data);
+
+/* REQ-S2LRD-PINTFC-API-BASIC-RNG-002 */
+/*!
+ * Add entropy to random number generator.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param length Number of bytes at @a data.
+ * @param data Entropy to add to random number generator.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_add_entropy(fsl_shw_uco_t * user_ctx,
+ uint32_t length, uint8_t * data);
+
+/*!
+ * Perform Generation-Encryption by doing a Cipher and a Hash.
+ *
+ * Generate the authentication value @a auth_value as well as encrypt the @a
+ * payload into @a ct (the ciphertext). This is a one-shot function, so all of
+ * the @a auth_data and the total message @a payload must passed in one call.
+ * This also means that the flags in the @a auth_ctx must be #FSL_ACCO_CTX_INIT
+ * and #FSL_ACCO_CTX_FINALIZE.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param auth_ctx Controlling object for Authenticate-decrypt.
+ * @param cipher_key_info The key being used for the cipher part of this
+ * operation. In CCM mode, this key is used for
+ * both parts.
+ * @param auth_key_info The key being used for the authentication part
+ * of this operation. In CCM mode, this key is
+ * ignored and may be NULL.
+ * @param auth_data_length Length, in octets, of @a auth_data.
+ * @param auth_data Data to be authenticated but not encrypted.
+ * @param payload_length Length, in octets, of @a payload.
+ * @param payload Pointer to the plaintext to be encrypted.
+ * @param[out] ct Pointer to the where the encrypted @a payload
+ * will be stored. Must be @a payload_length
+ * octets long.
+ * @param[out] auth_value Pointer to where the generated authentication
+ * field will be stored. Must be as many octets as
+ * indicated by MAC length in the @a function_ctx.
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_gen_encrypt(fsl_shw_uco_t * user_ctx,
+ fsl_shw_acco_t * auth_ctx,
+ fsl_shw_sko_t * cipher_key_info,
+ fsl_shw_sko_t * auth_key_info,
+ uint32_t auth_data_length,
+ const uint8_t * auth_data,
+ uint32_t payload_length,
+ const uint8_t * payload,
+ uint8_t * ct, uint8_t * auth_value);
+
+/*!
+ * Perform Authentication-Decryption in Cipher + Hash.
+ *
+ * This function will perform a one-shot decryption of a data stream as well as
+ * authenticate the authentication value. This is a one-shot function, so all
+ * of the @a auth_data and the total message @a payload must passed in one
+ * call. This also means that the flags in the @a auth_ctx must be
+ * #FSL_ACCO_CTX_INIT and #FSL_ACCO_CTX_FINALIZE.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param auth_ctx Controlling object for Authenticate-decrypt.
+ * @param cipher_key_info The key being used for the cipher part of this
+ * operation. In CCM mode, this key is used for
+ * both parts.
+ * @param auth_key_info The key being used for the authentication part
+ * of this operation. In CCM mode, this key is
+ * ignored and may be NULL.
+ * @param auth_data_length Length, in octets, of @a auth_data.
+ * @param auth_data Data to be authenticated but not decrypted.
+ * @param payload_length Length, in octets, of @a ct and @a pt.
+ * @param ct Pointer to the encrypted input stream.
+ * @param auth_value The (encrypted) authentication value which will
+ * be authenticated. This is the same data as the
+ * (output) @a auth_value argument to
+ * #fsl_shw_gen_encrypt().
+ * @param[out] payload Pointer to where the plaintext resulting from
+ * the decryption will be stored.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_auth_decrypt(fsl_shw_uco_t * user_ctx,
+ fsl_shw_acco_t * auth_ctx,
+ fsl_shw_sko_t * cipher_key_info,
+ fsl_shw_sko_t * auth_key_info,
+ uint32_t auth_data_length,
+ const uint8_t * auth_data,
+ uint32_t payload_length,
+ const uint8_t * ct,
+ const uint8_t * auth_value,
+ uint8_t * payload);
+
+/*!
+ * Establish the key in a protected location, which can be the system keystore,
+ * user keystore, or (on platforms that support it) as a Platform Key.
+ *
+ * By default, keys initialized with #fsl_shw_sko_init() will be placed into
+ * the system keystore. The user can cause the key to be established in a
+ * user keystore by first calling #fsl_shw_sko_set_keystore() on the key.
+ * Normally, keys in the system keystore can only be used for hardware
+ * encrypt or decrypt operations, however if the #FSL_SKO_KEY_SW_KEY flag is
+ * applied using #fsl_shw_sko_set_flags(), the key will be established as a
+ * software key, which can then be read out using #fsl_shw_read_key().
+ *
+ * Keys initialized with #fsl_shw_sko_init_pf_key() are established as a
+ * Platform Key. Their use is covered in @ref di_sec.
+ *
+ * This function only needs to be used when unwrapping a key, setting up a key
+ * which could be wrapped with a later call to #fsl_shw_extract_key(), or
+ * setting up a key as a Platform Key. Normal cleartext keys can simply be
+ * placed into #fsl_shw_sko_t key objects with #fsl_shw_sko_set_key() and used
+ * directly.
+ *
+ * The maximum key size supported for wrapped/unwrapped keys is 32 octets.
+ * (This is the maximum reasonable key length on Sahara - 32 octets for an HMAC
+ * key based on SHA-256.) The key size is determined by the @a key_info. The
+ * expected length of @a key can be determined by
+ * #fsl_shw_sko_calculate_wrapped_size()
+ *
+ * The protected key will not be available for use until this operation
+ * successfully completes.
+ *
+ * This feature is not available for all platforms, nor for all algorithms and
+ * modes.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param[in,out] key_info The information about the key to be which will
+ * be established. In the create case, the key
+ * length must be set.
+ * @param establish_type How @a key will be interpreted to establish a
+ * key for use.
+ * @param key If @a establish_type is #FSL_KEY_WRAP_UNWRAP,
+ * this is the location of a wrapped key. If
+ * @a establish_type is #FSL_KEY_WRAP_CREATE, this
+ * parameter can be @a NULL. If @a establish_type
+ * is #FSL_KEY_WRAP_ACCEPT, this is the location
+ * of a plaintext key.
+ */
+extern fsl_shw_return_t fsl_shw_establish_key(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ fsl_shw_key_wrap_t establish_type,
+ const uint8_t * key);
+
+/*!
+ * Read the key value from a key object.
+ *
+ * Only a key marked as a software key (#FSL_SKO_KEY_SW_KEY) can be read with
+ * this call. It has no effect on the status of the key store.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param key_info The referenced key.
+ * @param[out] key The location to store the key value.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_read_key(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ uint8_t * key);
+
+/*!
+ * Wrap a key and retrieve the wrapped value.
+ *
+ * A wrapped key is a key that has been cryptographically obscured. It is
+ * only able to be used with keys that have been established by
+ * #fsl_shw_establish_key().
+ *
+ * For keys established in the system or user keystore, this function will
+ * also release the key (see #fsl_shw_release_key()) so that it must be re-
+ * established before reuse. This function will not release keys that are
+ * established as a Platform Key, so a call to #fsl_shw_release_key() is
+ * necessary to release those keys.
+ *
+ * This feature is not available for all platforms, nor for all algorithms and
+ * modes.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param key_info The information about the key to be deleted.
+ * @param[out] covered_key The location to store the wrapped key.
+ * (This size is based upon the maximum key size
+ * of 32 octets).
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_extract_key(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ uint8_t * covered_key);
+
+/*!
+ * De-establish a key so that it can no longer be accessed.
+ *
+ * The key will need to be re-established before it can again be used.
+ *
+ * This feature is not available for all platforms, nor for all algorithms and
+ * modes.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ * @param key_info The information about the key to be deleted.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_release_key(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info);
+
+/*!
+ * Cause the hardware to create a new random key for use by the secure memory
+ * encryption hardware.
+ *
+ * Have the hardware use the secure hardware random number generator to load a
+ * new secret key into the system's Random Key register.
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_gen_random_pf_key(fsl_shw_uco_t * user_ctx);
+
+/*!
+ * Retrieve the detected tamper event.
+ *
+ * Note that if more than one event was detected, this routine will only ever
+ * return one of them.
+ *
+ * @param[in] user_ctx A user context from #fsl_shw_register_user().
+ * @param[out] tamperp Location to store the tamper information.
+ * @param[out] timestampp Locate to store timestamp from hardwhare when
+ * an event was detected.
+ *
+ *
+ * @return A return code of type #fsl_shw_return_t (for instance, if the platform
+ * is not in a fail state.
+ */
+extern fsl_shw_return_t fsl_shw_read_tamper_event(fsl_shw_uco_t * user_ctx,
+ fsl_shw_tamper_t * tamperp,
+ uint64_t * timestampp);
+
+/*! @} *//* opfuns */
+
+/* Insert example code into the API documentation. */
+
+/*!
+ * @example apitest.c
+ */
+
+/*!
+ * @example sym.c
+ */
+
+/*!
+ * @example rand.c
+ */
+
+/*!
+ * @example hash.c
+ */
+
+/*!
+ * @example hmac1.c
+ */
+
+/*!
+ * @example hmac2.c
+ */
+
+/*!
+ * @example gen_encrypt.c
+ */
+
+/*!
+ * @example auth_decrypt.c
+ */
+
+/*!
+ * @example wrapped_key.c
+ */
+
+/*!
+ * @example smalloc.c
+ */
+
+/*!
+ * @example user_keystore.c
+ */
+
+/*!
+ * @example dryice.c
+ */
+
+#endif /* API_DOC */
+
+#endif /* FSL_SHW_H */
diff --git a/drivers/mxc/security/sahara2/include/fsl_shw_keystore.h b/drivers/mxc/security/sahara2/include/fsl_shw_keystore.h
new file mode 100644
index 000000000000..4af6b782af6b
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/fsl_shw_keystore.h
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+
+#ifndef FSL_SHW_KEYSTORE_H
+#define FSL_SHW_KEYSTORE_H
+
+/*!
+ * @file fsl_shw_keystore.h
+ *
+ * @brief Definition of the User Keystore API.
+ *
+ */
+
+/*! \page user_keystore User Keystore API
+ *
+ * Definition of the User Keystore API.
+ *
+ * On platforms with multiple partitions of Secure Memory, the Keystore Object
+ * (#fsl_shw_kso_t) is provided to allow users to manage a private keystore for
+ * use in software cryptographic routines. The user can define a custom set of
+ * methods for managing their keystore, or use a default keystore handler. The
+ * keystore is established by #fsl_shw_establish_keystore(), and released by
+ * #fsl_shw_release_keystore(). The intent of this design is to make the
+ * keystore implementation as flexible as possible.
+ *
+ * See @ref keystore_api for the generic keystore API, and @ref
+ * default_keystore for the default keystore implementation.
+ *
+ */
+
+/*!
+ * @defgroup keystore_api User Keystore API
+ *
+ * Keystore API
+ *
+ * These functions define the generic keystore API, which can be used in
+ * conjunction with a keystore implementation backend to support a user
+ * keystore.
+ */
+
+/*!
+ * @defgroup default_keystore Default Keystore Implementation
+ *
+ * Default Keystore Implementation
+ *
+ * These functions define the default keystore implementation, which is used
+ * for the system keystore and for user keystores initialized by
+ * #fsl_shw_init_keystore_default(). They can be used as-is or as a reference
+ * for creating a custom keystore handler. It uses an entire Secure Memory
+ * partition, divided in to equal slots of length #KEYSTORE_SLOT_SIZE. These
+ * functions are not intended to be used directly- all user interaction with
+ * the keystore should be through the @ref keystore_api and the Wrapped Key
+ * interface.
+ *
+ * The current implementation is designed to work with both SCC and SCC2.
+ * Differences between the two versions are noted below.
+ */
+
+/*! @addtogroup keystore_api
+ @{ */
+
+#ifndef KEYSTORE_SLOT_SIZE
+/*! Size of each key slot, in octets. This sets an upper bound on the size
+ * of a key that can placed in the keystore.
+ */
+#define KEYSTORE_SLOT_SIZE 32
+#endif
+
+/*!
+ * Initialize a Keystore Object.
+ *
+ * This function must be called before performing any other operation with the
+ * Object. It allows the user to associate a custom keystore interface by
+ * specifying the correct set of functions that will be used to perform actions
+ * on the keystore object. To use the default keystore handler, the function
+ * #fsl_shw_init_keystore_default() can be used instead.
+ *
+ * @param keystore The Keystore object to operate on.
+ * @param data_init Keystore initialization function. This function is
+ * responsible for initializing the keystore. A
+ * user-defined object can be assigned to the user_data
+ * pointer, and will be passed to any function acting on
+ * that keystore. It is called during
+ * #fsl_shw_establish_keystore().
+ * @param data_cleanup Keystore cleanup function. This function cleans up
+ * any data structures associated with the keyboard. It
+ * is called by #fsl_shw_release_keystore().
+ * @param slot_alloc Slot allocation function. This function allocates a
+ * key slot, potentially based on size and owner id. It
+ * is called by #fsl_shw_establish_key().
+ * @param slot_dealloc Slot deallocation function.
+ * @param slot_verify_access Function to verify that a given Owner ID
+ * credential matches the given slot.
+ * @param slot_get_address For SCC2: Get the virtual address (kernel or
+ * userspace) of the data stored in the slot.
+ * For SCC: Get the physical address of the data
+ * stored in the slot.
+ * @param slot_get_base For SCC2: Get the (virtual) base address of the
+ * partition that the slot is located on.
+ * For SCC: Not implemented.
+ * @param slot_get_offset For SCC2: Get the offset from the start of the
+ * partition that the slot data is located at (in
+ * octets)
+ * For SCC: Not implemented.
+ * @param slot_get_slot_size Get the size of the key slot, in octets.
+ */
+extern void fsl_shw_init_keystore(fsl_shw_kso_t * keystore,
+ fsl_shw_return_t(*data_init) (fsl_shw_uco_t *
+ user_ctx,
+ void
+ **user_data),
+ void (*data_cleanup) (fsl_shw_uco_t *
+ user_ctx,
+ void **user_data),
+ fsl_shw_return_t(*slot_alloc) (void
+ *user_data,
+ uint32_t size,
+ uint64_t
+ owner_id,
+ uint32_t *
+ slot),
+ fsl_shw_return_t(*slot_dealloc) (void
+ *user_data,
+ uint64_t
+ owner_id,
+ uint32_t
+ slot),
+ fsl_shw_return_t(*slot_verify_access) (void
+ *user_data,
+ uint64_t
+ owner_id,
+ uint32_t
+ slot),
+ void *(*slot_get_address) (void *user_data,
+ uint32_t handle),
+ uint32_t(*slot_get_base) (void *user_data,
+ uint32_t handle),
+ uint32_t(*slot_get_offset) (void *user_data,
+ uint32_t handle),
+ uint32_t(*slot_get_slot_size) (void
+ *user_data,
+ uint32_t
+ handle));
+
+/*!
+ * Initialize a Keystore Object.
+ *
+ * This function must be called before performing any other operation with the
+ * Object. It sets the user keystore object up to use the default keystore
+ * handler. If a custom keystore handler is desired, the function
+ * #fsl_shw_init_keystore() can be used instead.
+ *
+ * @param keystore The Keystore object to operate on.
+ */
+extern void fsl_shw_init_keystore_default(fsl_shw_kso_t * keystore);
+
+/*!
+ * Establish a Keystore Object.
+ *
+ * This function establishes a keystore object that has been set up by a call
+ * to #fsl_shw_init_keystore(). It is a wrapper for the user-defined
+ * data_init() function, which is specified during keystore initialization.
+ *
+ * @param user_ctx The user context that this keystore should be attached
+ * to
+ * @param keystore The Keystore object to operate on.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_establish_keystore(fsl_shw_uco_t * user_ctx,
+ fsl_shw_kso_t * keystore);
+
+/*!
+ * Release a Keystore Object.
+ *
+ * This function releases an established keystore object. It is a wrapper for
+ * the user-defined data_cleanup() function, which is specified during keystore
+ * initialization.
+ *
+ * @param user_ctx The user context that this keystore should be attached
+ * to.
+ * @param keystore The Keystore object to operate on.
+ */
+extern void fsl_shw_release_keystore(fsl_shw_uco_t * user_ctx,
+ fsl_shw_kso_t * keystore);
+
+/*!
+ * Allocate a slot in the Keystore.
+ *
+ * This function attempts to allocate a slot to hold a key in the keystore. It
+ * is called by #fsl_shw_establish_key() when establishing a Secure Key Object,
+ * if the key has been flagged to be stored in a user keystore by the
+ * #fsl_shw_sko_set_keystore() function. It is a wrapper for the
+ * implementation-specific function slot_alloc().
+ *
+ * @param keystore The Keystore object to operate on.
+ * @param[in] size Size of the key to be stored (octets).
+ * @param[in] owner_id ID of the key owner.
+ * @param[out] slot If successful, assigned slot ID
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t keystore_slot_alloc(fsl_shw_kso_t * keystore,
+ uint32_t size,
+ uint64_t owner_id, uint32_t * slot);
+
+/*!
+ * Deallocate a slot in the Keystore.
+ *
+ * This function attempts to allocate a slot to hold a key in the keystore.
+ * It is called by #fsl_shw_extract_key() and #fsl_shw_release_key() when the
+ * key that it contains is to be released. It is a wrapper for the
+ * implmentation-specific function slot_dealloc().
+
+ * @param keystore The Keystore object to operate on.
+ * @param[in] owner_id ID of the key owner.
+ * @param[in] slot If successful, assigned slot ID.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t keystore_slot_dealloc(fsl_shw_kso_t * keystore,
+ uint64_t owner_id, uint32_t slot);
+
+/*!
+ * Load cleartext key data into a key slot
+ *
+ * This function loads a key slot with cleartext data.
+ *
+ * @param keystore The Keystore object to operate on.
+ * @param[in] owner_id ID of the key owner.
+ * @param[in] slot If successful, assigned slot ID.
+ * @param[in] key_data Pointer to the location of the cleartext key data.
+ * @param[in] key_length Length of the key data (octets).
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t
+keystore_slot_load(fsl_shw_kso_t * keystore, uint64_t owner_id, uint32_t slot,
+ const uint8_t * key_data, uint32_t key_length);
+
+/*!
+ * Read cleartext key data from a key slot
+ *
+ * This function returns the key in a key slot.
+ *
+ * @param keystore The Keystore object to operate on.
+ * @param[in] owner_id ID of the key owner.
+ * @param[in] slot ID of slot where key resides.
+ * @param[in] key_length Length of the key data (octets).
+ * @param[out] key_data Pointer to the location of the cleartext key data.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t
+keystore_slot_read(fsl_shw_kso_t * keystore, uint64_t owner_id, uint32_t slot,
+ uint32_t key_length, uint8_t * key_data);
+
+/*!
+ * Encrypt a keyslot
+ *
+ * This function encrypts a key using the hardware secret key.
+ *
+ * @param user_ctx User context
+ * @param keystore The Keystore object to operate on.
+ * @param[in] owner_id ID of the key owner.
+ * @param[in] slot Slot ID of the key to encrypt.
+ * @param[in] length Length of the key
+ * @param[out] destination Pointer to the location where the encrypted data
+ * is to be stored.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t
+keystore_slot_encrypt(fsl_shw_uco_t * user_ctx,
+ fsl_shw_kso_t * keystore, uint64_t owner_id,
+ uint32_t slot, uint32_t length, uint8_t * destination);
+
+/*!
+ * Decrypt a keyslot
+ *
+ * This function decrypts a key using the hardware secret key.
+ *
+ * @param user_ctx User context
+ * @param keystore The Keystore object to operate on.
+ * @param[in] owner_id ID of the key owner.
+ * @param[in] slot Slot ID of the key to encrypt.
+ * @param[in] length Length of the key
+ * @param[in] source Pointer to the location where the encrypted data
+ * is stored.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t
+keystore_slot_decrypt(fsl_shw_uco_t * user_ctx,
+ fsl_shw_kso_t * keystore, uint64_t owner_id,
+ uint32_t slot, uint32_t length, const uint8_t * source);
+
+/* @} */
+
+/*! @addtogroup default_keystore
+ @{ */
+
+/*!
+ * Data structure to hold per-slot information
+ */
+typedef struct keystore_data_slot_info_t {
+ uint8_t allocated; /*!< Track slot assignments */
+ uint64_t owner; /*!< Owner IDs */
+ uint32_t key_length; /*!< Size of the key */
+} keystore_data_slot_info_t;
+
+/*!
+ * Data structure to hold keystore information.
+ */
+typedef struct keystore_data_t {
+ void *base_address; /*!< Base of the Secure Partition */
+ uint32_t slot_count; /*!< Number of slots in the keystore */
+ struct keystore_data_slot_info_t *slot; /*!< Per-slot information */
+} keystore_data_t;
+
+/*!
+ * Default keystore initialization routine.
+ *
+ * This function acquires a Secure Partition Object to store the keystore,
+ * divides it into slots of length #KEYSTORE_SLOT_SIZE, and builds a data
+ * structure to hold key information.
+ *
+ * @param user_ctx User context
+ * @param[out] user_data Pointer to the location where the keystore data
+ * structure is to be stored.
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+fsl_shw_return_t shw_kso_init_data(fsl_shw_uco_t * user_ctx, void **user_data);
+
+/*!
+ * Default keystore cleanup routine.
+ *
+ * This function releases the Secure Partition Object and the memory holding
+ * the keystore data structure, that obtained by the shw_kso_init_data
+ * function.
+ *
+ * @param user_ctx User context
+ * @param[in,out] user_data Pointer to the location where the keystore data
+ * structure is stored.
+ */
+void shw_kso_cleanup_data(fsl_shw_uco_t * user_ctx, void **user_data);
+
+/*!
+ * Default keystore slot access verification
+ *
+ * This function compares the supplied Owner ID to the registered owner of
+ * the key slot, to see if the supplied ID is correct.
+ *
+ * @param[in] user_data Pointer to the location where the keystore data
+ * structure stored.
+ * @param[in] owner_id Owner ID supplied as a credential.
+ * @param[in] slot Requested slot
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+fsl_shw_return_t shw_slot_verify_access(void *user_data, uint64_t owner_id,
+ uint32_t slot);
+
+/*!
+ * Default keystore slot allocation
+ *
+ * This function first checks that the requested size is equal to or less than
+ * the maximum keystore slot size. If so, it searches the keystore for a free
+ * key slot, and if found, marks it as used and returns a slot reference to the
+ * user.
+ *
+ * @param[in] user_data Pointer to the location where the keystore data
+ * structure stored.
+ * @param[in] size Size of the key data that will be stored in this slot
+ * (octets)
+ * @param[in] owner_id Owner ID supplied as a credential.
+ * @param[out] slot Requested slot
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+fsl_shw_return_t shw_slot_alloc(void *user_data, uint32_t size,
+ uint64_t owner_id, uint32_t * slot);
+
+/*!
+ * Default keystore slot deallocation
+ *
+ * This function releases the given key slot in the keystore, making it
+ * available to store a new key.
+ *
+ * @param[in] user_data Pointer to the location where the keystore data
+ * structure stored.
+ * @param[in] owner_id Owner ID supplied as a credential.
+ * @param[in] slot Requested slot
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+fsl_shw_return_t shw_slot_dealloc(void *user_data,
+ uint64_t owner_id, uint32_t slot);
+
+/*!
+ * Default keystore slot address lookup
+ *
+ * This function calculates the address where the key data is stored.
+ *
+ * @param[in] user_data Pointer to the location where the keystore data
+ * structure stored.
+ * @param[in] slot Requested slot
+ *
+ * @return SCC2: Virtual address (kernel or userspace) of the key data.
+ * SCC: Physical address of the key data.
+ */
+void *shw_slot_get_address(void *user_data, uint32_t slot);
+
+/*!
+ * Default keystore slot base address lookup
+ *
+ * This function calculates the base address of the Secure Partition on which
+ * the key data is located. For the reference design, only one Secure
+ * Partition is used per Keystore, however in general, any number may be used.
+ *
+ * @param[in] user_data Pointer to the location where the keystore data
+ * structure stored.
+ * @param[in] slot Requested slot
+ *
+ * @return SCC2: Secure Partition virtual (kernel or userspace) base address.
+ * SCC: Secure Partition physical base address.
+ */
+uint32_t shw_slot_get_base(void *user_data, uint32_t slot);
+
+/*!
+ * Default keystore slot offset lookup
+ *
+ * This function calculates the offset from the base of the Secure Partition
+ * where the key data is located.
+ *
+ * @param[in] user_data Pointer to the location where the keystore data
+ * structure stored.
+ * @param[in] slot Requested slot
+ *
+ * @return SCC2: Key data offset (octets)
+ * SCC: Not implemented
+ */
+uint32_t shw_slot_get_offset(void *user_data, uint32_t slot);
+
+/*!
+ * Default keystore slot offset lookup
+ *
+ * This function returns the size of the given key slot. In the reference
+ * implementation, all key slots are of the same size, however in general,
+ * the keystore slot sizes can be made variable.
+ *
+ * @param[in] user_data Pointer to the location where the keystore data
+ * structure stored.
+ * @param[in] slot Requested slot
+ *
+ * @return SCC2: Keystore slot size.
+ * SCC: Not implemented
+ */
+uint32_t shw_slot_get_slot_size(void *user_data, uint32_t slot);
+
+/* @} */
+
+#endif /* FSL_SHW_KEYSTORE_H */
diff --git a/drivers/mxc/security/sahara2/include/linux_port.h b/drivers/mxc/security/sahara2/include/linux_port.h
new file mode 100644
index 000000000000..bd65c55c4f7b
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/linux_port.h
@@ -0,0 +1,1806 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file linux_port.h
+ *
+ * OS_PORT ported to Linux (2.6.9+ for now)
+ *
+ */
+
+ /*!
+ * @if USE_MAINPAGE
+ * @mainpage ==Linux version of== Generic OS API for STC Drivers
+ * @endif
+ *
+ * @section intro_sec Introduction
+ *
+ * This API / kernel programming environment blah blah.
+ *
+ * See @ref dkops "Driver-to-Kernel Operations" as a good place to start.
+ */
+
+#ifndef LINUX_PORT_H
+#define LINUX_PORT_H
+
+#define PORTABLE_OS_VERSION 101
+
+/* Linux Kernel Includes */
+#include <linux/version.h> /* Current version Linux kernel */
+
+#if defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+#include <linux/modversions.h>
+#endif
+#define MODVERSIONS
+#endif
+/*!
+ * __NO_VERSION__ defined due to Kernel module possibly spanning multiple
+ * files.
+ */
+#define __NO_VERSION__
+
+#include <linux/module.h> /* Basic support for loadable modules,
+ printk */
+#include <linux/init.h> /* module_init, module_exit */
+#include <linux/kernel.h> /* General kernel system calls */
+#include <linux/sched.h> /* for interrupt.h */
+#include <linux/fs.h> /* for inode */
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/slab.h> /* kmalloc */
+
+#include <stdarg.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+#include <linux/device.h> /* used in dynamic power management */
+#else
+#include <linux/platform_device.h> /* used in dynamic power management */
+#endif
+
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/clk.h> /* clock en/disable for DPM */
+
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/uaccess.h> /* copy_to_user(), copy_from_user() */
+#include <asm/io.h> /* ioremap() */
+#include <asm/irq.h>
+#include <asm/cacheflush.h>
+
+#include <mach/hardware.h>
+
+#ifndef TRUE
+/*! Useful symbol for unsigned values used as flags. */
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+/*! Useful symbol for unsigned values used as flags. */
+#define FALSE 0
+#endif
+
+/* These symbols are defined in Linux 2.6 and later. Include here for minimal
+ * support of 2.4 kernel.
+ **/
+#if !defined(LINUX_VERSION_CODE) || LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+/*!
+ * Symbol defined somewhere in 2.5/2.6. It is the return signature of an ISR.
+ */
+#define irqreturn_t void
+/*! Possible return value of 'modern' ISR routine. */
+#define IRQ_HANDLED
+/*! Method of generating value of 'modern' ISR routine. */
+#define IRQ_RETVAL(x)
+#endif
+
+/*!
+ * Type used for registering and deregistering interrupts.
+ */
+typedef int os_interrupt_id_t;
+
+/*!
+ * Type used as handle for a process
+ *
+ * See #os_get_process_handle() and #os_send_signal().
+ */
+/*
+ * The following should be defined this way, but it gets compiler errors
+ * on the current tool chain.
+ *
+ * typedef task_t *os_process_handle_t;
+ */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+typedef task_t *os_process_handle_t;
+#else
+typedef struct task_struct *os_process_handle_t;
+#endif
+
+/*!
+ * Generic return code for functions which need such a thing.
+ *
+ * No knowledge should be assumed of the value of any of these symbols except
+ * that @c OS_ERROR_OK_S is guaranteed to be zero.
+ */
+typedef enum {
+ OS_ERROR_OK_S = 0, /*!< Success */
+ OS_ERROR_FAIL_S = -EIO, /*!< Generic driver failure */
+ OS_ERROR_NO_MEMORY_S = -ENOMEM, /*!< Failure to acquire/use memory */
+ OS_ERROR_BAD_ADDRESS_S = -EFAULT, /*!< Bad address */
+ OS_ERROR_BAD_ARG_S = -EINVAL, /*!< Bad input argument */
+} os_error_code;
+
+/*!
+ * Handle to a lock.
+ */
+#ifdef CONFIG_PREEMPT_RT
+typedef raw_spinlock_t *os_lock_t;
+#else
+typedef spinlock_t *os_lock_t;
+#endif
+
+/*!
+ * Context while locking.
+ */
+typedef unsigned long os_lock_context_t;
+
+/*!
+ * Declare a wait object for sleeping/waking processes.
+ */
+#define OS_WAIT_OBJECT(name) \
+ DECLARE_WAIT_QUEUE_HEAD(name##_qh)
+
+/*!
+ * Driver registration handle
+ *
+ * Used with #os_driver_init_registration(), #os_driver_add_registration(),
+ * and #os_driver_complete_registration().
+ */
+typedef struct {
+ unsigned reg_complete; /*!< TRUE if next inits succeeded. */
+ dev_t dev; /*!< dev_t for register_chrdev() */
+ struct file_operations fops; /*!< struct for register_chrdev() */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
+ struct class_simple *cs; /*!< results of class_simple_create() */
+#else
+ struct class *cs; /*!< results of class_create() */
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
+ struct class_device *cd; /*!< Result of class_device_create() */
+#else
+ struct device *cd; /*!< Result of device_create() */
+#endif
+ unsigned power_complete; /*!< TRUE if next inits succeeded */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+ struct device_driver dd; /*!< struct for register_driver() */
+#else
+ struct platform_driver dd; /*!< struct for register_driver() */
+#endif
+ struct platform_device pd; /*!< struct for platform_register_device() */
+} os_driver_reg_t;
+
+/*
+ * Function types which can be associated with driver entry points.
+ *
+ * Note that init and shutdown are absent.
+ */
+/*! @{ */
+/*! Keyword for registering open() operation handler. */
+#define OS_FN_OPEN open
+/*! Keyword for registering close() operation handler. */
+#define OS_FN_CLOSE release
+/*! Keyword for registering read() operation handler. */
+#define OS_FN_READ read
+/*! Keyword for registering write() operation handler. */
+#define OS_FN_WRITE write
+/*! Keyword for registering ioctl() operation handler. */
+#define OS_FN_IOCTL ioctl
+/*! Keyword for registering mmap() operation handler. */
+#define OS_FN_MMAP mmap
+/*! @} */
+
+/*!
+ * Function signature for the portable interrupt handler
+ *
+ * While it would be nice to know which interrupt is being serviced, the
+ * Least Common Denominator rule says that no arguments get passed in.
+ *
+ * @return Zero if not handled, non-zero if handled.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+typedef int (*os_interrupt_handler_t) (int, void *, struct pt_regs *);
+#else
+typedef int (*os_interrupt_handler_t) (int, void *);
+#endif
+
+/*!
+ * @defgroup dkops Driver-to-Kernel Operations
+ *
+ * These are the operations which drivers should call to get the OS to perform
+ * services.
+ */
+
+/*! @addtogroup dkops */
+/*! @{ */
+
+/*!
+ * Register an interrupt handler.
+ *
+ * @param driver_name The name of the driver
+ * @param interrupt_id The interrupt line to monitor (type
+ * #os_interrupt_id_t)
+ * @param function The function to be called to handle an interrupt
+ *
+ * @return #os_error_code
+ */
+#define os_register_interrupt(driver_name, interrupt_id, function) \
+ request_irq(interrupt_id, function, 0, driver_name, NULL)
+
+/*!
+ * Deregister an interrupt handler.
+ *
+ * @param interrupt_id The interrupt line to stop monitoring
+ *
+ * @return #os_error_code
+ */
+#define os_deregister_interrupt(interrupt_id) \
+ free_irq(interrupt_id, NULL)
+
+/*!
+ * INTERNAL implementation of os_driver_init_registration()
+ *
+ * @return An os error code.
+ */
+inline static int os_drv_do_init_reg(os_driver_reg_t * handle)
+{
+ memset(handle, 0, sizeof(*handle));
+ handle->fops.owner = THIS_MODULE;
+ handle->power_complete = FALSE;
+ handle->reg_complete = FALSE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+ handle->dd.name = NULL;
+#else
+ handle->dd.driver.name = NULL;
+#endif
+
+ return OS_ERROR_OK_S;
+}
+
+/*!
+ * Initialize driver registration.
+ *
+ * If the driver handles open(), close(), ioctl(), read(), write(), or mmap()
+ * calls, then it needs to register their location with the kernel so that they
+ * get associated with the device.
+ *
+ * @param handle The handle object to be used with this registration. The
+ * object must live (be in memory somewhere) at least until
+ * os_driver_remove_registration() is called.
+ *
+ * @return A handle for further driver registration, or NULL if failed.
+ */
+#define os_driver_init_registration(handle) \
+ os_drv_do_init_reg(&handle)
+
+/*!
+ * Add a function registration to driver registration.
+ *
+ * @param handle A handle initialized by #os_driver_init_registration().
+ * @param name Which function is being supported.
+ * @param function The result of a call to a @c _REF version of one of the
+ * driver function signature macros
+ * @return void
+ */
+#define os_driver_add_registration(handle, name, function) \
+ do {handle.fops.name = (void*)(function); } while (0)
+
+/*!
+ * Record 'power suspend' function for the device.
+ *
+ * @param handle A handle initialized by #os_driver_init_registration().
+ * @param function Name of function to call on power suspend request
+ *
+ * Status: Provisional
+ *
+ * @return void
+ */
+#define os_driver_register_power_suspend(handle, function) \
+ handle.dd.suspend = function
+
+/*!
+ * Record 'power resume' function for the device.
+ *
+ * @param handle A handle initialized by #os_driver_init_registration().
+ * @param function Name of function to call on power resume request
+ *
+ * Status: Provisional
+ *
+ * @return void
+ */
+#define os_driver_register_resume(handle, function) \
+ handle.dd.resume = function
+
+/*!
+ * INTERNAL function of the Linux port of the OS API. Implements the
+ * os_driver_complete_registration() function.
+ *
+ * @param handle The handle used with #os_driver_init_registration().
+ * @param major The major device number to be associated with the driver.
+ * If this value is zero, a major number may be assigned.
+ * See #os_driver_get_major() to determine final value.
+ * #os_driver_remove_registration().
+ * @param driver_name The driver name. Can be used as part of 'device node'
+ * name on platforms which support such a feature.
+ *
+ * @return An error code
+ */
+inline static int os_drv_do_reg(os_driver_reg_t * handle,
+ unsigned major, char *driver_name)
+{
+ os_error_code code = OS_ERROR_NO_MEMORY_S;
+ char *name = kmalloc(strlen(driver_name) + 1, 0);
+
+ if (name != NULL) {
+ memcpy(name, driver_name, strlen(driver_name) + 1);
+ code = OS_ERROR_OK_S; /* OK so far */
+ /* If any chardev/POSIX routines were added, then do chrdev part */
+ if (handle->fops.open || handle->fops.release
+ || handle->fops.read || handle->fops.write
+ || handle->fops.ioctl || handle->fops.mmap) {
+
+ printk("ioctl pointer: %p. mmap pointer: %p\n",
+ handle->fops.ioctl, handle->fops.mmap);
+
+ /* this method is depricated, see:
+ * http://lwn.net/Articles/126808/
+ */
+ code =
+ register_chrdev(major, driver_name, &handle->fops);
+
+ /* instead something like this: */
+#if 0
+ handle->dev = MKDEV(major, 0);
+ code =
+ register_chrdev_region(handle->dev, 1, driver_name);
+ if (code < 0) {
+ code = OS_ERROR_FAIL_S;
+ } else {
+ cdev_init(&handle->cdev, &handle->fops);
+ code = cdev_add(&handle->cdev, major, 1);
+ }
+#endif
+
+ if (code < 0) {
+ code = OS_ERROR_FAIL_S;
+ } else {
+ if (code != 0) {
+ /* Zero was passed in for major; code is actual value */
+ handle->dev = MKDEV(code, 0);
+ } else {
+ handle->dev = MKDEV(major, 0);
+ }
+ code = OS_ERROR_OK_S;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
+ handle->cs =
+ class_simple_create(THIS_MODULE,
+ driver_name);
+ if (IS_ERR(handle->cs)) {
+ code = (os_error_code) handle->cs;
+ handle->cs = NULL;
+ } else {
+ handle->cd =
+ class_simple_device_add(handle->cs,
+ handle->dev,
+ NULL,
+ driver_name);
+ if (IS_ERR(handle->cd)) {
+ class_simple_device_remove
+ (handle->dev);
+ unregister_chrdev(MAJOR
+ (handle->dev),
+ driver_name);
+ code =
+ (os_error_code) handle->cs;
+ handle->cs = NULL;
+ } else {
+ handle->reg_complete = TRUE;
+ }
+ }
+#else
+ handle->cs =
+ class_create(THIS_MODULE, driver_name);
+ if (IS_ERR(handle->cs)) {
+ code = (os_error_code) handle->cs;
+ handle->cs = NULL;
+ } else {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
+ handle->cd =
+ class_device_create(handle->cs,
+ NULL,
+ handle->dev,
+ NULL,
+ driver_name);
+#else
+ handle->cd =
+ device_create(handle->cs, NULL,
+ handle->dev, NULL,
+ driver_name);
+#endif
+ if (IS_ERR(handle->cd)) {
+ class_destroy(handle->cs);
+ unregister_chrdev(MAJOR
+ (handle->dev),
+ driver_name);
+ code =
+ (os_error_code) handle->cs;
+ handle->cs = NULL;
+ } else {
+ handle->reg_complete = TRUE;
+ }
+ }
+#endif
+ }
+ }
+ /* ... fops routine registered */
+ /* Handle power management fns through separate interface */
+ if ((code == OS_ERROR_OK_S) &&
+ (handle->dd.suspend || handle->dd.resume)) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+ handle->dd.name = name;
+ handle->dd.bus = &platform_bus_type;
+ code = driver_register(&handle->dd);
+#else
+ handle->dd.driver.name = name;
+ handle->dd.driver.bus = &platform_bus_type;
+ code = driver_register(&handle->dd.driver);
+#endif
+ if (code == OS_ERROR_OK_S) {
+ handle->pd.name = name;
+ handle->pd.id = 0;
+ code = platform_device_register(&handle->pd);
+ if (code != OS_ERROR_OK_S) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+ driver_unregister(&handle->dd);
+#else
+ driver_unregister(&handle->dd.driver);
+#endif
+ } else {
+ handle->power_complete = TRUE;
+ }
+ }
+ } /* ... suspend or resume */
+ } /* name != NULL */
+ return code;
+}
+
+/*!
+ * Finalize the driver registration with the kernel.
+ *
+ * Upon return from this call, the driver may begin receiving calls at the
+ * defined entry points.
+ *
+ * @param handle The handle used with #os_driver_init_registration().
+ * @param major The major device number to be associated with the driver.
+ * If this value is zero, a major number may be assigned.
+ * See #os_driver_get_major() to determine final value.
+ * #os_driver_remove_registration().
+ * @param driver_name The driver name. Can be used as part of 'device node'
+ * name on platforms which support such a feature.
+ *
+ * @return An error code
+ */
+#define os_driver_complete_registration(handle, major, driver_name) \
+ os_drv_do_reg(&handle, major, driver_name)
+
+/*!
+ * Get driver Major Number from handle after a successful registration.
+ *
+ * @param handle A handle which has completed registration.
+ *
+ * @return The major number (if any) associated with the handle.
+ */
+#define os_driver_get_major(handle) \
+ (handle.reg_complete ? MAJOR(handle.dev) : -1)
+
+/*!
+ * INTERNAL implemention of os_driver_remove_registration.
+ *
+ * @param handle A handle initialized by #os_driver_init_registration().
+ *
+ * @return An error code.
+ */
+inline static int os_drv_rmv_reg(os_driver_reg_t * handle)
+{
+ if (handle->reg_complete) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
+ if (handle->cd != NULL) {
+ class_simple_device_remove(handle->dev);
+ handle->cd = NULL;
+ }
+ if (handle->cs != NULL) {
+ class_simple_destroy(handle->cs);
+ handle->cs = NULL;
+ }
+ unregister_chrdev(MAJOR(handle->dev), handle->dd.name);
+#else
+ if (handle->cd != NULL) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
+ class_device_destroy(handle->cs, handle->dev);
+#else
+ device_destroy(handle->cs, handle->dev);
+#endif
+ handle->cd = NULL;
+ }
+ if (handle->cs != NULL) {
+ class_destroy(handle->cs);
+ handle->cs = NULL;
+ }
+ unregister_chrdev(MAJOR(handle->dev), handle->dd.driver.name);
+#endif
+ handle->reg_complete = FALSE;
+ }
+ if (handle->power_complete) {
+ platform_device_unregister(&handle->pd);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+ driver_unregister(&handle->dd);
+#else
+ driver_unregister(&handle->dd.driver);
+#endif
+ handle->power_complete = FALSE;
+ }
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+ if (handle->dd.name != NULL) {
+ kfree(handle->dd.name);
+ handle->dd.name = NULL;
+ }
+#else
+ if (handle->dd.driver.name != NULL) {
+ kfree(handle->dd.driver.name);
+ handle->dd.driver.name = NULL;
+ }
+#endif
+ return OS_ERROR_OK_S;
+}
+
+/*!
+ * Remove the driver's registration with the kernel.
+ *
+ * Upon return from this call, the driver not receive any more calls at the
+ * defined entry points (other than ISR and shutdown).
+ *
+ * @param handle A handle initialized by #os_driver_init_registration().
+ *
+ * @return An error code.
+ */
+#define os_driver_remove_registration(handle) \
+ os_drv_rmv_reg(&handle)
+
+/*!
+ * Register a driver with the Linux Device Model.
+ *
+ * @param driver_information The device_driver structure information
+ *
+ * @return An error code.
+ *
+ * Status: denigrated in favor of #os_driver_complete_registration()
+ */
+#define os_register_to_driver(driver_information) \
+ driver_register(driver_information)
+
+/*!
+ * Unregister a driver from the Linux Device Model
+ *
+ * this routine unregisters from the Linux Device Model
+ *
+ * @param driver_information The device_driver structure information
+ *
+ * @return An error code.
+ *
+ * Status: Denigrated. See #os_register_to_driver().
+ */
+#define os_unregister_from_driver(driver_information) \
+ driver_unregister(driver_information)
+
+/*!
+ * register a device to a driver
+ *
+ * this routine registers a drivers devices to the Linux Device Model
+ *
+ * @param device_information The platform_device structure information
+ *
+ * @return An error code.
+ *
+ * Status: denigrated in favor of #os_driver_complete_registration()
+ */
+#define os_register_a_device(device_information) \
+ platform_device_register(device_information)
+
+/*!
+ * unregister a device from a driver
+ *
+ * this routine unregisters a drivers devices from the Linux Device Model
+ *
+ * @param device_information The platform_device structure information
+ *
+ * @return An error code.
+ *
+ * Status: Denigrated. See #os_register_a_device().
+ */
+#define os_unregister_a_device(device_information) \
+ platform_device_unregister(device_information)
+
+/*!
+ * Print a message to console / into log file. After the @c msg argument a
+ * number of printf-style arguments may be added. Types should be limited to
+ * printf string, char, octal, decimal, and hexadecimal types. (This excludes
+ * pointers, and floating point).
+ *
+ * @param msg The main text of the message to be logged
+ * @param s The printf-style arguments which go with msg, if any
+ *
+ * @return (void)
+ */
+#define os_printk(...) \
+ (void) printk(__VA_ARGS__)
+
+/*!
+ * Prepare a task to execute the given function. This should only be done once
+ * per function,, during the driver's initialization routine.
+ *
+ * @param task_fn Name of the OS_DEV_TASK() function to be created.
+ *
+ * @return an OS ERROR code.
+ */
+#define os_create_task(function_name) \
+ OS_ERROR_OK_S
+
+/*!
+ * Schedule execution of a task.
+ *
+ * @param function_name The function associated with the task.
+ *
+ * @return (void)
+ */
+#define os_dev_schedule_task(function_name) \
+ tasklet_schedule(&(function_name ## let))
+
+/*!
+ * Make sure that task is no longer running and will no longer run.
+ *
+ * This function will not return until both are true. This is useful when
+ * shutting down a driver.
+ */
+#define os_dev_stop_task(function_name) \
+do { \
+ tasklet_disable(&(function_name ## let)); \
+ tasklet_kill(&(function_name ## let)); \
+} while (0)
+
+/*!
+ * Allocate some kernel memory
+ *
+ * @param amount Number of 8-bit bytes to allocate
+ * @param flags Some indication of purpose of memory (needs definition)
+ *
+ * @return Pointer to allocated memory, or NULL if failed.
+ */
+#define os_alloc_memory(amount, flags) \
+ (void*)kmalloc(amount, flags)
+
+/*!
+ * Free some kernel memory
+ *
+ * @param location The beginning of the region to be freed.
+ *
+ * Do some OSes have separate free() functions which should be
+ * distinguished by passing in @c flags here, too? Don't some also require the
+ * size of the buffer being freed?
+ */
+#define os_free_memory(location) \
+ kfree(location)
+
+/*!
+ * Allocate cache-coherent memory
+ *
+ * @param amount Number of bytes to allocate
+ * @param[out] dma_addrp Location to store physical address of allocated
+ * memory.
+ * @param flags Some indication of purpose of memory (needs
+ * definition).
+ *
+ * @return (virtual space) pointer to allocated memory, or NULL if failed.
+ *
+ */
+#define os_alloc_coherent(amount, dma_addrp, flags) \
+ (void*)dma_alloc_coherent(NULL, amount, dma_addrp, flags)
+
+/*!
+ * Free cache-coherent memory
+ *
+ * @param size Number of bytes which were allocated.
+ * @param virt_addr Virtual(kernel) address of memory.to be freed, as
+ * returned by #os_alloc_coherent().
+ * @param dma_addr Physical address of memory.to be freed, as returned
+ * by #os_alloc_coherent().
+ *
+ * @return void
+ *
+ */
+#define os_free_coherent(size, virt_addr, dma_addr) \
+ dma_free_coherent(NULL, size, virt_addr, dma_addr
+
+/*!
+ * Map an I/O space into kernel memory space
+ *
+ * @param start The starting address of the (physical / io space) region
+ * @param range_bytes The number of bytes to map
+ *
+ * @return A pointer to the mapped area, or NULL on failure
+ */
+#define os_map_device(start, range_bytes) \
+ (void*)ioremap_nocache((start), range_bytes)
+
+/*!
+ * Unmap an I/O space from kernel memory space
+ *
+ * @param start The starting address of the (virtual) region
+ * @param range_bytes The number of bytes to unmap
+ *
+ * @return None
+ */
+#define os_unmap_device(start, range_bytes) \
+ iounmap((void*)(start))
+
+/*!
+ * Copy data from Kernel space to User space
+ *
+ * @param to The target location in user memory
+ * @param from The source location in kernel memory
+ * @param size The number of bytes to be copied
+ *
+ * @return #os_error_code
+ */
+#define os_copy_to_user(to, from, size) \
+ ((copy_to_user(to, from, size) == 0) ? 0 : OS_ERROR_BAD_ADDRESS_S)
+
+/*!
+ * Copy data from User space to Kernel space
+ *
+ * @param to The target location in kernel memory
+ * @param from The source location in user memory
+ * @param size The number of bytes to be copied
+ *
+ * @return #os_error_code
+ */
+#define os_copy_from_user(to, from, size) \
+ ((copy_from_user(to, from, size) == 0) ? 0 : OS_ERROR_BAD_ADDRESS_S)
+
+/*!
+ * Read a 8-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @return The value in the register
+ */
+#define os_read8(register_address) \
+ __raw_readb(register_address)
+
+/*!
+ * Write a 8-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @param value The value to write into the register
+ */
+#define os_write8(register_address, value) \
+ __raw_writeb(value, register_address)
+
+/*!
+ * Read a 16-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @return The value in the register
+ */
+#define os_read16(register_address) \
+ __raw_readw(register_address)
+
+/*!
+ * Write a 16-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @param value The value to write into the register
+ */
+#define os_write16(register_address, value) \
+ __raw_writew(value, (uint32_t*)(register_address))
+
+/*!
+ * Read a 32-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @return The value in the register
+ */
+#define os_read32(register_address) \
+ __raw_readl((uint32_t*)(register_address))
+
+/*!
+ * Write a 32-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @param value The value to write into the register
+ */
+#define os_write32(register_address, value) \
+ __raw_writel(value, register_address)
+
+/*!
+ * Read a 64-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @return The value in the register
+ */
+#define os_read64(register_address) \
+ ERROR_UNIMPLEMENTED
+
+/*!
+ * Write a 64-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @param value The value to write into the register
+ */
+#define os_write64(register_address, value) \
+ ERROR_UNIMPLEMENTED
+
+/*!
+ * Delay some number of microseconds
+ *
+ * Note that this is a busy-loop, not a suspension of the task/process.
+ *
+ * @param msecs The number of microseconds to delay
+ *
+ * @return void
+ */
+#define os_mdelay mdelay
+
+/*!
+ * Calculate virtual address from physical address
+ *
+ * @param pa Physical address
+ *
+ * @return virtual address
+ *
+ * @note this assumes that addresses are 32 bits wide
+ */
+#define os_va __va
+
+/*!
+ * Calculate physical address from virtual address
+ *
+ *
+ * @param va Virtual address
+ *
+ * @return physical address
+ *
+ * @note this assumes that addresses are 32 bits wide
+ */
+#define os_pa __pa
+
+#ifdef CONFIG_PREEMPT_RT
+/*!
+ * Allocate and initialize a lock, returning a lock handle.
+ *
+ * The lock state will be initialized to 'unlocked'.
+ *
+ * @return A lock handle, or NULL if an error occurred.
+ */
+inline static os_lock_t os_lock_alloc_init(void)
+{
+ raw_spinlock_t *lockp;
+ lockp = (raw_spinlock_t *) kmalloc(sizeof(raw_spinlock_t), 0);
+ if (lockp) {
+ _raw_spin_lock_init(lockp);
+ } else {
+ printk("OS: lock init failed\n");
+ }
+
+ return lockp;
+}
+#else
+/*!
+ * Allocate and initialize a lock, returning a lock handle.
+ *
+ * The lock state will be initialized to 'unlocked'.
+ *
+ * @return A lock handle, or NULL if an error occurred.
+ */
+inline static os_lock_t os_lock_alloc_init(void)
+{
+ spinlock_t *lockp;
+ lockp = (spinlock_t *) kmalloc(sizeof(spinlock_t), 0);
+ if (lockp) {
+ spin_lock_init(lockp);
+ } else {
+ printk("OS: lock init failed\n");
+ }
+
+ return lockp;
+}
+#endif /* CONFIG_PREEMPT_RT */
+
+/*!
+ * Acquire a lock.
+ *
+ * This function should only be called from an interrupt service routine.
+ *
+ * @param lock_handle A handle to the lock to acquire.
+ *
+ * @return void
+ */
+#define os_lock(lock_handle) \
+ spin_lock(lock_handle)
+
+/*!
+ * Unlock a lock. Lock must have been acquired by #os_lock().
+ *
+ * @param lock_handle A handle to the lock to unlock.
+ *
+ * @return void
+ */
+#define os_unlock(lock_handle) \
+ spin_unlock(lock_handle)
+
+/*!
+ * Acquire a lock in non-ISR context
+ *
+ * This function will spin until the lock is available.
+ *
+ * @param lock_handle A handle of the lock to acquire.
+ * @param context Place to save the before-lock context
+ *
+ * @return void
+ */
+#define os_lock_save_context(lock_handle, context) \
+ spin_lock_irqsave(lock_handle, context)
+
+/*!
+ * Release a lock in non-ISR context
+ *
+ * @param lock_handle A handle of the lock to release.
+ * @param context Place where before-lock context was saved.
+ *
+ * @return void
+ */
+#define os_unlock_restore_context(lock_handle, context) \
+ spin_unlock_irqrestore(lock_handle, context)
+
+/*!
+ * Deallocate a lock handle.
+ *
+ * @param lock_handle An #os_lock_t that has been allocated.
+ *
+ * @return void
+ */
+#define os_lock_deallocate(lock_handle) \
+ kfree(lock_handle)
+
+/*!
+ * Determine process handle
+ *
+ * The process handle of the current user is returned.
+ *
+ * @return A handle on the current process.
+ */
+#define os_get_process_handle() \
+ current
+
+/*!
+ * Send a signal to a process
+ *
+ * @param proc A handle to the target process.
+ * @param sig The POSIX signal to send to that process.
+ */
+#define os_send_signal(proc, sig) \
+ send_sig(sig, proc, 0);
+
+/*!
+ * Get some random bytes
+ *
+ * @param buf The location to store the random data.
+ * @param count The number of bytes to store.
+ *
+ * @return void
+ */
+#define os_get_random_bytes(buf, count) \
+ get_random_bytes(buf, count)
+
+/*!
+ * Go to sleep on an object.
+ *
+ * @param object The object on which to sleep
+ * @param condition An expression to check for sleep completion. Must be
+ * coded so that it can be referenced more than once inside
+ * macro, i.e., no ++ or other modifying expressions.
+ * @param atomic Non-zero if sleep must not return until condition.
+ *
+ * @return error code -- OK or sleep interrupted??
+ */
+#define os_sleep(object, condition, atomic) \
+({ \
+ DEFINE_WAIT(_waitentry_); \
+ os_error_code code = OS_ERROR_OK_S; \
+ \
+ while (!(condition)) { \
+ prepare_to_wait(&(object##_qh), &_waitentry_, \
+ atomic ? 0 : TASK_INTERRUPTIBLE); \
+ if (!(condition)) { \
+ schedule(); \
+ } \
+ \
+ finish_wait(&(object##_qh), &_waitentry_); \
+ \
+ if (!atomic && signal_pending(current)) { \
+ code = OS_ERROR_FAIL_S; /* NEED SOMETHING BETTER */ \
+ break; \
+ } \
+ }; \
+ \
+ code; \
+})
+
+/*!
+ * Wake up whatever is sleeping on sleep object
+ *
+ * @param object The object on which things might be sleeping
+ *
+ * @return none
+ */
+#define os_wake_sleepers(object) \
+ wake_up_interruptible(&(object##_qh));
+
+ /*! @} *//* dkops */
+
+/******************************************************************************
+ * Function signature-generating macros
+ *****************************************************************************/
+
+/*!
+ * @defgroup drsigs Driver Signatures
+ *
+ * These macros will define the entry point signatures for interrupt handlers;
+ * driver initialization and shutdown; device open/close; etc.
+ *
+ * There are two versions of each macro for a given Driver Entry Point. The
+ * first version is used to define a function and its implementation in the
+ * driver.c file, e.g. #OS_DEV_INIT().
+ *
+ * The second form is used whenever a forward declaration (prototype) is
+ * needed. It has the letters @c _DCL appended to the name of the defintion
+ * function, and takes only the first two arguments (driver_name and
+ * function_name). These are not otherwise mentioned in this documenation.
+ *
+ * There is a third form used when a reference to a function is required, for
+ * instance when passing the routine as a pointer to a function. It has the
+ * letters @c _REF appended to it, and takes only the first two arguments
+ * (driver_name and function_name). These functions are not otherwise
+ * mentioned in this documentation.
+ *
+ * (Note that these two extra forms are required because of the
+ * possibility/likelihood of having a 'wrapper function' which invokes the
+ * generic function with expected arguments. An alternative would be to have a
+ * generic function which isn't able to get at any arguments directly, but
+ * would be equipped with macros which could get at information passed in.
+ *
+ * Example:
+ *
+ * (in a header file)
+ * @code
+ * OS_DEV_INIT_DCL(widget, widget_init);
+ * @endcode
+ *
+ * (in an implementation file)
+ * @code
+ * OS_DEV_INIT(widget, widget_init)
+ * {
+ * os_dev_init_return(TRUE);
+ * }
+ * @endcode
+ *
+ */
+
+/*! @addtogroup drsigs */
+/*! @{ */
+
+/*!
+ * Define a function which will handle device initialization
+ *
+ * This is tne driver initialization routine. This is normally where the
+ * part would be initialized; queues, locks, interrupts handlers defined;
+ * long-term dynamic memory allocated for driver use; etc.
+ *
+ * @param function_name The name of the portable initialization function.
+ *
+ * @return A call to #os_dev_init_return()
+ *
+ */
+#define OS_DEV_INIT(function_name) \
+module_init(function_name); \
+static int __init function_name (void)
+
+/*! Make declaration for driver init function.
+ * @param function_name foo
+ */
+#define OS_DEV_INIT_DCL(function_name) \
+static int __init function_name (void);
+
+/*!
+ * Generate a function reference to the driver's init function.
+ * @param function_name Name of the OS_DEV_INIT() function.
+ *
+ * @return A function pointer.
+ */
+#define OS_DEV_INIT_REF(function_name) \
+function_name
+
+/*!
+ * Define a function which will handle device shutdown
+ *
+ * This is the inverse of the #OS_DEV_INIT() routine.
+ *
+ * @param function_name The name of the portable driver shutdown routine.
+ *
+ * @return A call to #os_dev_shutdown_return()
+ *
+ */
+#define OS_DEV_SHUTDOWN(function_name) \
+module_exit(function_name); \
+static void function_name(void)
+
+/*!
+ * Generate a function reference to the driver's shutdown function.
+ * @param function_name Name of the OS_DEV_HUSTDOWN() function.
+ *
+ * @return A function pointer.
+ */
+#define OS_DEV_SHUTDOWN_DCL(function_name) \
+static void function_name(void);
+
+/*!
+ * Generate a reference to driver's shutdown function
+ * @param function_name Name of the OS_DEV_HUSTDOWN() function.
+*/
+
+#define OS_DEV_SHUTDOWN_REF(function_name) \
+function_name
+
+/*!
+ * Define a function which will open the device for a user.
+ *
+ * @param function_name The name of the driver open() function
+ *
+ * @return A call to #os_dev_open_return()
+ */
+#define OS_DEV_OPEN(function_name) \
+static int function_name(struct inode* inode_p_, struct file* file_p_)
+
+/*!
+ * Declare prototype for an open() function.
+ *
+ * @param function_name The name of the OS_DEV_OPEN() function.
+ */
+#define OS_DEV_OPEN_DCL(function_name) \
+OS_DEV_OPEN(function_name);
+
+/*!
+ * Generate a function reference to the driver's open() function.
+ * @param function_name Name of the OS_DEV_OPEN() function.
+ *
+ * @return A function pointer.
+ */
+#define OS_DEV_OPEN_REF(function_name) \
+function_name
+
+/*!
+ * Define a function which will handle a user's ioctl() request
+ *
+ * @param function_name The name of the driver ioctl() function
+ *
+ * @return A call to #os_dev_ioctl_return()
+ */
+#define OS_DEV_IOCTL(function_name) \
+static int function_name(struct inode* inode_p_, struct file* file_p_, \
+ unsigned int cmd_, unsigned long data_)
+
+/*! Boo. */
+#define OS_DEV_IOCTL_DCL(function_name) \
+OS_DEV_IOCTL(function_name);
+
+/*!
+ * Generate a function reference to the driver's ioctl() function.
+ * @param function_name Name of the OS_DEV_IOCTL() function.
+ *
+ * @return A function pointer.
+ */
+#define OS_DEV_IOCTL_REF(function_name) \
+function_name
+
+/*!
+ * Define a function which will handle a user's mmap() request
+ *
+ * @param function_name The name of the driver mmap() function
+ *
+ * @return A call to #os_dev_ioctl_return()
+ */
+#define OS_DEV_MMAP(function_name) \
+int function_name(struct file* file_p_, struct vm_area_struct* vma_)
+
+#define OS_DEV_MMAP_DCL(function_name) \
+OS_DEV_MMAP(function_name);
+
+#define OS_DEV_MMAP_REF(function_name) \
+function_name
+
+/* Retrieve the context to the memory structure that is to be MMAPed */
+#define os_mmap_memory_ctx() (vma_)
+
+/* Determine the size of the requested MMAP region*/
+#define os_mmap_memory_size() (vma_->vm_end - vma_->vm_start)
+
+/* Determine the base address of the requested MMAP region*/
+#define os_mmap_user_base() (vma_->vm_start)
+
+/*!
+ * Declare prototype for an read() function.
+ *
+ * @param function_name The name of the driver read function.
+ */
+#define OS_DEV_READ_DCL(function_name) \
+OS_DEV_READ(function_name);
+
+/*!
+ * Generate a function reference to the driver's read() routine
+ * @param function_name Name of the OS_DEV_READ() function.
+ *
+ * @return A function pointer.
+ */
+#define OS_DEV_READ_REF(function_name) \
+function_name
+
+/*!
+ * Define a function which will handle a user's write() request
+ *
+ * @param function_name The name of the driver write() function
+ *
+ * @return A call to #os_dev_write_return()
+ */
+#define OS_DEV_WRITE(function_name) \
+static ssize_t function_name(struct file* file_p_, char* user_buffer_, \
+ size_t count_bytes_, loff_t* file_position_)
+
+/*!
+ * Declare prototype for an write() function.
+ *
+ * @param function_name The name of the driver write function.
+ */
+#define OS_DEV_WRITE_DCL(function_name) \
+OS_DEV_WRITE(function_name);
+
+/*!
+ * Generate a function reference to the driver's write() routine
+ * @param function_name Name of the OS_DEV_WRITE() function.
+ *
+ * @return A function pointer.
+ */
+#define OS_DEV_WRITE_REF(function_name) \
+function_name
+
+/*!
+ * Define a function which will close the device - opposite of OS_DEV_OPEN()
+ *
+ * @param function_name The name of the driver close() function
+ *
+ * @return A call to #os_dev_close_return()
+ */
+#define OS_DEV_CLOSE(function_name) \
+static int function_name(struct inode* inode_p_, struct file* file_p_)
+
+/*!
+ * Declare prototype for an close() function
+ *
+ * @param function_name The name of the driver close() function.
+ */
+#define OS_DEV_CLOSE_DCL(function_name) \
+OS_DEV_CLOSE(function_name);
+
+/*!
+ * Generate a function reference to the driver's close function.
+ * @param function_name Name of the OS_DEV_CLOSE() function.
+ *
+ * @return A function pointer.
+ */
+#define OS_DEV_CLOSE_REF(function_name) \
+function_name
+
+/*!
+ * Define a function which will handle an interrupt
+ *
+ * No arguments are available to the generic function. It must not invoke any
+ * OS functions which are illegal in a ISR. It gets no parameters, and must
+ * have a call to #os_dev_isr_return() instead of any/all return statements.
+ *
+ * Example:
+ * @code
+ * OS_DEV_ISR(widget)
+ * {
+ * os_dev_isr_return(1);
+ * }
+ * @endcode
+ *
+ * @param function_name The name of the driver ISR function
+ *
+ * @return A call to #os_dev_isr_return()
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+#define OS_DEV_ISR(function_name) \
+static irqreturn_t function_name(int N1_, void* N2_, struct pt_regs* N3_)
+#else
+#define OS_DEV_ISR(function_name) \
+static irqreturn_t function_name(int N1_, void* N2_)
+#endif
+
+/*!
+ * Declare prototype for an ISR function.
+ *
+ * @param function_name The name of the driver ISR function.
+ */
+#define OS_DEV_ISR_DCL(function_name) \
+OS_DEV_ISR(function_name);
+
+/*!
+ * Generate a function reference to the driver's interrupt service routine
+ * @param function_name Name of the OS_DEV_ISR() function.
+ *
+ * @return A function pointer.
+ */
+#define OS_DEV_ISR_REF(function_name) \
+function_name
+
+/*!
+ * Define a function which will operate as a background task / bottom half.
+ *
+ * Tasklet stuff isn't strictly limited to 'Device drivers', but leave it
+ * this namespace anyway.
+ *
+ * @param function_name The name of this background task function
+ *
+ * @return A call to #os_dev_task_return()
+ */
+#define OS_DEV_TASK(function_name) \
+static void function_name(unsigned long data_)
+
+/*!
+ * Declare prototype for a background task / bottom half function
+ *
+ * @param function_name The name of this background task function
+ */
+#define OS_DEV_TASK_DCL(function_name) \
+OS_DEV_TASK(function_name); \
+DECLARE_TASKLET(function_name ## let, function_name, 0);
+
+/*!
+ * Generate a reference to an #OS_DEV_TASK() function
+ *
+ * @param function_name The name of the task being referenced.
+ */
+#define OS_DEV_TASK_REF(function_name) \
+ (function_name ## let)
+
+ /*! @} *//* drsigs */
+
+/*****************************************************************************
+ * Functions/Macros for returning values from Driver Signature routines
+ *****************************************************************************/
+
+/*!
+ * Return from the #OS_DEV_INIT() function
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+#define os_dev_init_return(code) \
+ return code
+
+/*!
+ * Return from the #OS_DEV_SHUTDOWN() function
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+#define os_dev_shutdown_return(code) \
+ return
+
+/*!
+ * Return from the #OS_DEV_ISR() function
+ *
+ * The function should verify that it really was supposed to be called,
+ * and that its device needed attention, in order to properly set the
+ * return code.
+ *
+ * @param code non-zero if interrupt handled, zero otherwise.
+ *
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+#define os_dev_isr_return(code) \
+do { \
+ /* Unused warnings */ \
+ (void)N1_; \
+ (void)N2_; \
+ (void)N3_; \
+ \
+ return IRQ_RETVAL(code); \
+} while (0)
+#else
+#define os_dev_isr_return(code) \
+do { \
+ /* Unused warnings */ \
+ (void)N1_; \
+ (void)N2_; \
+ \
+ return IRQ_RETVAL(code); \
+} while (0)
+#endif
+
+/*!
+ * Return from the #OS_DEV_OPEN() function
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+#define os_dev_open_return(code) \
+do { \
+ int retcode = code; \
+ \
+ /* get rid of 'unused parameter' warnings */ \
+ (void)inode_p_; \
+ (void)file_p_; \
+ \
+ return retcode; \
+} while (0)
+
+/*!
+ * Return from the #OS_DEV_IOCTL() function
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+#define os_dev_ioctl_return(code) \
+do { \
+ int retcode = code; \
+ \
+ /* get rid of 'unused parameter' warnings */ \
+ (void)inode_p_; \
+ (void)file_p_; \
+ (void)cmd_; \
+ (void)data_; \
+ \
+ return retcode; \
+} while (0)
+
+/*!
+ * Return from the #OS_DEV_READ() function
+ *
+ * @param code Number of bytes read, or an error code to report failure.
+ *
+ */
+#define os_dev_read_return(code) \
+do { \
+ ssize_t retcode = code; \
+ \
+ /* get rid of 'unused parameter' warnings */ \
+ (void)file_p_; \
+ (void)user_buffer_; \
+ (void)count_bytes_; \
+ (void)file_position_; \
+ \
+ return retcode; \
+} while (0)
+
+/*!
+ * Return from the #OS_DEV_WRITE() function
+ *
+ * @param code Number of bytes written, or an error code to report failure.
+ *
+ */
+#define os_dev_write_return(code) \
+do { \
+ ssize_t retcode = code; \
+ \
+ /* get rid of 'unused parameter' warnings */ \
+ (void)file_p_; \
+ (void)user_buffer_; \
+ (void)count_bytes_; \
+ (void)file_position_; \
+ \
+ return retcode; \
+} while (0)
+
+/*!
+ * Return from the #OS_DEV_CLOSE() function
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+#define os_dev_close_return(code) \
+do { \
+ ssize_t retcode = code; \
+ \
+ /* get rid of 'unused parameter' warnings */ \
+ (void)inode_p_; \
+ (void)file_p_; \
+ \
+ return retcode; \
+} while (0)
+
+/*!
+ * Start the #OS_DEV_TASK() function
+ *
+ * In some implementations, this could be turned into a label for
+ * the os_dev_task_return() call.
+ *
+ * @return none
+ */
+#define os_dev_task_begin()
+
+/*!
+ * Return from the #OS_DEV_TASK() function
+ *
+ * In some implementations, this could be turned into a sleep followed
+ * by a jump back to the os_dev_task_begin() call.
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+#define os_dev_task_return(code) \
+do { \
+ /* Unused warnings */ \
+ (void)data_; \
+ \
+ return; \
+} while (0)
+
+/*****************************************************************************
+ * Functions/Macros for accessing arguments from Driver Signature routines
+ *****************************************************************************/
+
+/*! @defgroup drsigargs Functions for Getting Arguments in Signature functions
+ *
+ */
+/* @addtogroup @drsigargs */
+/*! @{ */
+/*!
+ * Used in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and
+ * #OS_DEV_WRITE() routines to check whether user is requesting read
+ * (permission)
+ */
+#define os_dev_is_flag_read() \
+ (file_p_->f_mode & FMODE_READ)
+
+/*!
+ * Used in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and
+ * #OS_DEV_WRITE() routines to check whether user is requesting write
+ * (permission)
+ */
+#define os_dev_is_flag_write() \
+ (file_p_->f_mode & FMODE_WRITE)
+
+/*!
+ * Used in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and
+ * #OS_DEV_WRITE() routines to check whether user is requesting non-blocking
+ * I/O.
+ */
+#define os_dev_is_flag_nonblock() \
+ (file_p_->f_flags & (O_NONBLOCK | O_NDELAY))
+
+/*!
+ * Used in #OS_DEV_OPEN() and #OS_DEV_CLOSE() to determine major device being
+ * accessed.
+ */
+#define os_dev_get_major() \
+ (imajor(inode_p_))
+
+/*!
+ * Used in #OS_DEV_OPEN() and #OS_DEV_CLOSE() to determine minor device being
+ * accessed.
+ */
+#define os_dev_get_minor() \
+ (iminor(inode_p_))
+
+/*!
+ * Used in #OS_DEV_IOCTL() to determine which operation the user wants
+ * performed.
+ *
+ * @return Value of the operation.
+ */
+#define os_dev_get_ioctl_op() \
+ (cmd_)
+
+/*!
+ * Used in #OS_DEV_IOCTL() to return the associated argument for the desired
+ * operation.
+ *
+ * @return A value which can be cast to a struct pointer or used as
+ * int/long.
+ */
+#define os_dev_get_ioctl_arg() \
+ (data_)
+
+/*!
+ * Used in OS_DEV_READ() and OS_DEV_WRITE() routines to access the requested
+ * byte count.
+ *
+ * @return (unsigned) a count of bytes
+ */
+#define os_dev_get_count() \
+ ((unsigned)count_bytes_)
+
+/*!
+ * Used in OS_DEV_READ() and OS_DEV_WRITE() routines to return the pointer
+ * byte count.
+ *
+ * @return char* pointer to user buffer
+ */
+#define os_dev_get_user_buffer() \
+ ((void*)user_buffer_)
+
+/*!
+ * Used in OS_DEV_READ(), OS_DEV_WRITE(), and OS_DEV_IOCTL() routines to
+ * get the POSIX flags field for the associated open file).
+ *
+ * @return The flags associated with the file.
+ */
+#define os_dev_get_file_flags() \
+ (file_p_->f_flags)
+
+/*!
+ * Set the driver's private structure associated with this file/open.
+ *
+ * Generally used during #OS_DEV_OPEN(). See #os_dev_get_user_private().
+ *
+ * @param struct_p The driver data structure to associate with this user.
+ */
+#define os_dev_set_user_private(struct_p) \
+ file_p_->private_data = (void*)(struct_p)
+
+/*!
+ * Get the driver's private structure associated with this file.
+ *
+ * May be used during #OS_DEV_OPEN(), #OS_DEV_READ(), #OS_DEV_WRITE(),
+ * #OS_DEV_IOCTL(), and #OS_DEV_CLOSE(). See #os_dev_set_user_private().
+ *
+ * @return The driver data structure to associate with this user.
+ */
+#define os_dev_get_user_private() \
+ ((void*)file_p_->private_data)
+
+/*!
+ * Get the IRQ associated with this call to the #OS_DEV_ISR() function.
+ *
+ * @return The IRQ (integer) interrupt number.
+ */
+#define os_dev_get_irq() \
+ N1_
+
+ /*! @} *//* drsigargs */
+
+/*!
+ * @defgroup cacheops Cache Operations
+ *
+ * These functions are for synchronizing processor cache with RAM.
+ */
+/*! @addtogroup cacheops */
+/*! @{ */
+
+/*!
+ * Flush and invalidate all cache lines.
+ */
+#if 0
+#define os_flush_cache_all() \
+ flush_cache_all()
+#else
+/* Call ARM fn directly, in case L2cache=on3 not set */
+#define os_flush_cache_all() \
+ v6_flush_kern_cache_all_L2()
+
+/*!
+ * ARM-routine to flush all cache. Defined here, because it exists in no
+ * easy-access header file. ARM-11 with L210 cache only!
+ */
+extern void v6_flush_kern_cache_all_L2(void);
+#endif
+
+/*
+ * These macros are using part of the Linux DMA API. They rely on the
+ * map function to do nothing more than the equivalent clean/inv/flush
+ * operation at the time of the mapping, and do nothing at an unmapping
+ * call, which the Sahara driver code will never invoke.
+ */
+
+/*!
+ * Clean a range of addresses from the cache. That is, write updates back
+ * to (RAM, next layer).
+ *
+ * @param start Starting virtual address
+ * @param len Number of bytes to flush
+ *
+ * @return void
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+#define os_cache_clean_range(start,len) \
+ dma_map_single(NULL, (void*)start, len, DMA_TO_DEVICE)
+#else
+#define os_cache_clean_range(start,len) \
+{ \
+ void *s = (void*)start; \
+ void *e = s + len; \
+ dmac_map_area(s, len, DMA_TO_DEVICE); \
+ outer_clean_range(__pa(s), __pa(e)); \
+}
+#endif
+
+/*!
+ * Invalidate a range of addresses in the cache
+ *
+ * @param start Starting virtual address
+ * @param len Number of bytes to flush
+ *
+ * @return void
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+#define os_cache_inv_range(start,len) \
+ dma_map_single(NULL, (void*)start, len, DMA_FROM_DEVICE)
+#else
+#define os_cache_inv_range(start,len) \
+{ \
+ void *s = (void*)start; \
+ void *e = s + len; \
+ dmac_unmap_area(s, len, DMA_FROM_DEVICE); \
+ outer_inv_range(__pa(s), __pa(e)); \
+}
+#endif
+
+/*!
+ * Flush a range of addresses from the cache. That is, perform clean
+ * and invalidate
+ *
+ * @param start Starting virtual address
+ * @param len Number of bytes to flush
+ *
+ * @return void
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+#define os_cache_flush_range(start,len) \
+ dma_map_single(NULL, (void*)start, len, DMA_BIDIRECTIONAL)
+#else
+#define os_cache_flush_range(start,len) \
+{ \
+ void *s = (void*)start; \
+ void *e = s + len; \
+ dmac_flush_range(s, e); \
+ outer_flush_range(__pa(s), __pa(e)); \
+}
+#endif
+
+ /*! @} *//* cacheops */
+
+#endif /* LINUX_PORT_H */
diff --git a/drivers/mxc/security/sahara2/include/platform_abstractions.h b/drivers/mxc/security/sahara2/include/platform_abstractions.h
new file mode 100644
index 000000000000..5fc87ccc5161
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/platform_abstractions.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*!
+ * @file platform_abstractions.h
+ */
diff --git a/drivers/mxc/security/sahara2/include/portable_os.h b/drivers/mxc/security/sahara2/include/portable_os.h
new file mode 100644
index 000000000000..445acd5d420c
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/portable_os.h
@@ -0,0 +1,1453 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef PORTABLE_OS_H
+#define PORTABLE_OS_H
+
+/***************************************************************************/
+
+/*
+ * Add support for your target OS by checking appropriate flags and then
+ * including the appropriate file. Don't forget to document the conditions
+ * in the later documentation section at the beginning of the
+ * DOXYGEN_PORTABLE_OS_DOC.
+ */
+
+#if defined(LINUX_KERNEL)
+
+#include "linux_port.h"
+
+#elif defined(PORTABLE_OS)
+
+#include "check_portability.h"
+
+#else
+
+#error Target OS unsupported or unspecified
+
+#endif
+
+
+/***************************************************************************/
+
+/*!
+ * @file portable_os.h
+ *
+ * This file should be included by portable driver code in order to gain access
+ * to the OS-specific header files. It is the only OS-related header file that
+ * the writer of a portable driver should need.
+ *
+ * This file also contains the documentation for the common API.
+ *
+ * Begin reading the documentation for this file at the @ref index "main page".
+ *
+ */
+
+/*!
+ * @if USE_MAINPAGE
+ * @mainpage Generic OS API for STC Drivers
+ * @endif
+ *
+ * @section intro_sec Introduction
+ *
+ * This defines the API / kernel programming environment for portable drivers.
+ *
+ * This API is broken up into several functional areas. It greatly limits the
+ * choices of a device-driver author, but at the same time should allow for
+ * greater portability of the resulting code.
+ *
+ * Each kernel-to-driver function (initialization function, interrupt service
+ * routine, etc.) has a 'portable signature' which must be used, and a specific
+ * function which must be called to generate the return statement. There is
+ * one exception, a background task or "bottom half" routine, which instead has
+ * a specific structure which must be followed. These signatures and function
+ * definitions are found in @ref drsigs.
+ *
+ * None of these kernel-to-driver functions seem to get any arguments passed to
+ * them. Instead, there are @ref drsigargs which allow one of these functions
+ * to get at fairly generic parts of its calling arguments, if there are any.
+ *
+ * Almost every driver will have some need to call the operating system
+ * @ref dkops is the list of services which are available to the driver.
+ *
+ *
+ * @subsection warn_sec Warning
+ *
+ * The specifics of the types, values of the various enumerations
+ * (unless specifically stated, like = 0), etc., are only here for illustrative
+ * purposes. No attempts should be made to make use of any specific knowledge
+ * gleaned from this documentation. These types are only meant to be passed in
+ * and out of the API, and their contents are to be handled only by the
+ * provided OS-specific functions.
+ *
+ * Also, note that the function may be provided as macros in some
+ * implementations, or vice versa.
+ *
+ *
+ * @section dev_sec Writing a Portable Driver
+ *
+ * First off, writing a portable driver means calling no function in an OS
+ * except what is available through this header file.
+ *
+ * Secondly, all OS-called functions in your driver must be invoked and
+ * referenced through the signature routines.
+ *
+ * Thirdly, there might be some rules which you can get away with ignoring or
+ * violating on one OS, yet will cause your code not to be portable to a
+ * different OS.
+ *
+ *
+ * @section limit_sec Limitations
+ *
+ * This API is not expected to handle every type of driver which may be found
+ * in an operating system. For example, it will not be able to handle the
+ * usual design for something like a UART driver, where there are multiple
+ * logical devices to access, because the design usually calls for some sort of
+ * indication to the #OS_DEV_TASK() function or OS_DEV_ISR() to indicate which
+ * channel is to be serviced by that instance of the task/function. This sort
+ * of argument is missing in this API for functions like os_dev_schedule_task() and
+ * os_register_interrupt().
+ *
+ *
+ * @section port_guide Porting Guidelines
+ *
+ * This section is intended for a developer who needs to port the header file
+ * to an operating system which is not yet supported.
+ *
+ * This interface allows for a lot of flexibility when it comes to porting to
+ * an operating systems device driver interface. There are three main areas to
+ * examine: The use of Driver Routine Signatures, the use of Driver Argument
+ * Access functions, the Calls to Kernel Functions, and Data Types.
+ *
+ *
+ * @subsection port_sig Porting Driver Routine Signatures
+ *
+ * The three macros for each function (e.g. #OS_DEV_INIT(), #OS_DEV_INIT_DCL(),
+ * and #OS_DEV_INIT_REF()) allow the flexibility of having a 'wrapper' function
+ * with the OS-required signature, which would then call the user's function
+ * with some different signature.
+ *
+ * The first form would lay down the wrapper function, followed by the
+ * signature for the user function. The second form would lay down just the
+ * signatures for both functions, and the last function would reference the
+ * wrapper function, since that is the interface function called by the OS.
+ *
+ * Note that the driver author has no visibility at all to the signature of the
+ * routines. The author can access arguments only through a limited set of
+ * functions, and must return via another function.
+ *
+ * The Return Functions allow a lot of flexibility in converting the return
+ * value, or not returning a value at all. These will likely be implemented as
+ * macros.
+ *
+ *
+ * @subsection port_arg Porting Driver Argument Access Functions
+ *
+ * The signatures defined by the guide will usually be replaced with macro
+ * definitions.
+ *
+ *
+ * @subsection port_dki Porting Calls to Kernel Functions
+ *
+ * The signatures defined by the guide may be replaced with macro definitions,
+ * if that makes more sense.
+ *
+ * Implementors are free to ignore arguments which are not applicable to their
+ * OS.
+ *
+ * @subsection port_datatypes Porting Data Types
+ *
+ *
+ */
+
+/***************************************************************************
+ * Compile flags
+ **************************************************************************/
+
+/*
+ * This compile flag should only be turned on when running doxygen to generate
+ * the API documentation.
+ */
+#ifdef DOXYGEN_PORTABLE_OS_DOC
+
+/*!
+ * @todo module_init()/module_cleanup() for Linux need to be added to OS
+ * abstractions. Also need EXPORT_SYMBOL() equivalent??
+ *
+ */
+
+/* Drop OS differentation documentation here */
+
+/*!
+ * \#define this flag to build your driver as a Linux driver
+ */
+#define LINUX
+
+/* end OS differentation documentation */
+
+/*!
+ * Symbol to give version number of the implementation file. Earliest
+ * definition is in version 1.1, with value 101 (to mean version 1.1)
+ */
+#define PORTABLE_OS_VERSION 101
+
+/*
+ * NOTICE: The following definitions (the rest of the file) are not meant ever
+ * to be compiled. Instead, they are the documentation for the portable OS
+ * API, to be used by driver writers.
+ *
+ * Each individual OS port will define each of these types, functions, or
+ * macros as appropriate to the target OS. This is why they are under the
+ * DOXYGEN_PORTABLE_OS_DOC flag.
+ */
+
+/***************************************************************************
+ * Type definitions
+ **************************************************************************/
+
+/*!
+ * Type used for registering and deregistering interrupts.
+ *
+ * This is typically an interrupt channel number.
+ */
+typedef int os_interrupt_id_t;
+
+/*!
+ * Type used as handle for a process
+ *
+ * See #os_get_process_handle() and #os_send_signal().
+ */
+typedef int os_process_handle_t;
+
+/*!
+ * Generic return code for functions which need such a thing.
+ *
+ * No knowledge should be assumed of the value of any of these symbols except
+ * that @c OS_ERROR_OK_S is guaranteed to be zero.
+ *
+ * @todo Any other named values? What about (-EAGAIN? -ERESTARTSYS? Are they
+ * too Linux/Unix-specific read()/write() return values) ?
+ */
+typedef enum {
+ OS_ERROR_OK_S = 0, /*!< Success */
+ OS_ERROR_FAIL_S, /*!< Generic driver failure */
+ OS_ERROR_NO_MEMORY_S, /*!< Failure to acquire/use memory */
+ OS_ERROR_BAD_ADDRESS_S, /*!< Bad address */
+ OS_ERROR_BAD_ARG_S /*!< Bad input argument */
+} os_error_code;
+
+/*!
+ * Handle to a lock.
+ */
+typedef int *os_lock_t;
+
+/*!
+ * Context while locking.
+ */
+typedef int os_lock_context_t;
+
+/*!
+ * An object which can be slept on and later used to wake any/all sleepers.
+ */
+typedef int os_sleep_object_t;
+
+/*!
+ * Driver registration handle
+ */
+typedef void *os_driver_reg_t;
+
+/*!
+ * Function signature for an #OS_DEV_INIT() function.
+ *
+ * @return A call to os_dev_init_return() function.
+ */
+typedef void (*os_init_function_t) (void);
+
+/*!
+ * Function signature for an #OS_DEV_SHUTDOWN() function.
+ *
+ * @return A call to os_dev_shutdown_return() function.
+ */
+typedef void (*os_shutdown_function_t) (void);
+
+/*!
+ * Function signature for a user-driver function.
+ *
+ * @return A call to the appropriate os_dev_xxx_return() function.
+ */
+typedef void (*os_user_function_t) (void);
+
+/*!
+ * Function signature for the portable interrupt handler
+ *
+ * While it would be nice to know which interrupt is being serviced, the
+ * Least Common Denominator rule says that no arguments get passed in.
+ *
+ * @return A call to #os_dev_isr_return()
+ */
+typedef void (*os_interrupt_handler_t) (void);
+
+/*!
+ * Function signature for a task function
+ *
+ * Many task function definitions get some sort of generic argument so that the
+ * same function can run across many (queues, channels, ...) as separate task
+ * instances. This has been left out of this API.
+ *
+ * This function must be structured as documented by #OS_DEV_TASK().
+ *
+ */
+typedef void (*os_task_fn_t) (void);
+
+/*!
+ * Function types which can be associated with driver entry points. These are
+ * used in os_driver_add_registration().
+ *
+ * Note that init and shutdown are absent.
+ */
+typedef enum {
+ OS_FN_OPEN, /*!< open() operation handler. */
+ OS_FN_CLOSE, /*!< close() operation handler. */
+ OS_FN_READ, /*!< read() operation handler. */
+ OS_FN_WRITE, /*!< write() operation handler. */
+ OS_FN_IOCTL, /*!< ioctl() operation handler. */
+ OS_FN_MMAP /*!< mmap() operation handler. */
+} os_driver_fn_t;
+
+/***************************************************************************
+ * Driver-to-Kernel Operations
+ **************************************************************************/
+
+/*!
+ * @defgroup dkops Driver-to-Kernel Operations
+ *
+ * These are the operations which drivers should call to get the OS to perform
+ * services.
+ */
+
+/*! @addtogroup dkops */
+/*! @{ */
+
+/*!
+ * Register an interrupt handler.
+ *
+ * @param driver_name The name of the driver
+ * @param interrupt_id The interrupt line to monitor (type
+ * #os_interrupt_id_t)
+ * @param function The function to be called to handle an interrupt
+ *
+ * @return #os_error_code
+ */
+os_error_code os_register_interrupt(char *driver_name,
+ os_interrupt_id_t interrupt_id,
+ os_interrupt_handler_t function);
+
+/*!
+ * Deregister an interrupt handler.
+ *
+ * @param interrupt_id The interrupt line to stop monitoring
+ *
+ * @return #os_error_code
+ */
+os_error_code os_deregister_interrupt(os_interrupt_id_t interrupt_id);
+
+/*!
+ * Initialize driver registration.
+ *
+ * If the driver handles open(), close(), ioctl(), read(), write(), or mmap()
+ * calls, then it needs to register their location with the kernel so that they
+ * get associated with the device.
+ *
+ * @param handle The handle object to be used with this registration. The
+ * object must live (be in memory somewhere) at least until
+ * os_driver_remove_registration() is called.
+ *
+ * @return An os error code.
+ */
+os_error_code os_driver_init_registration(os_driver_reg_t handle);
+
+/*!
+ * Add a function registration to driver registration.
+ *
+ * @param handle The handle used with #os_driver_init_registration().
+ * @param name Which function is being supported.
+ * @param function The result of a call to a @c _REF version of one of the
+ * driver function signature macros
+ * driver function signature macros
+ * @return void
+ */
+void os_driver_add_registration(os_driver_reg_t handle, os_driver_fn_t name,
+ void *function);
+
+/*!
+ * Finalize the driver registration with the kernel.
+ *
+ * Upon return from this call, the driver may begin receiving calls at the
+ * defined entry points.
+ *
+ * @param handle The handle used with #os_driver_init_registration().
+ * @param major The major device number to be associated with the driver.
+ * If this value is zero, a major number may be assigned.
+ * See #os_driver_get_major() to determine final value.
+ * #os_driver_remove_registration().
+ * @param driver_name The driver name. Can be used as part of 'device node'
+ * name on platforms which support such a feature.
+ *
+ * @return An error code
+ */
+os_error_code os_driver_complete_registration(os_driver_reg_t handle,
+ int major, char *driver_name);
+
+/*!
+ * Get driver Major Number from handle after a successful registration.
+ *
+ * @param handle A handle which has completed registration.
+ *
+ * @return The major number (if any) associated with the handle.
+ */
+uint32_t os_driver_get_major(os_driver_reg_t handle);
+
+/*!
+ * Remove the driver's registration with the kernel.
+ *
+ * Upon return from this call, the driver not receive any more calls at the
+ * defined entry points (other than ISR and shutdown).
+ *
+ * @param major The major device number to be associated with the driver.
+ * @param driver_name The driver name
+ *
+ * @return An error code.
+ */
+os_error_code os_driver_remove_registration(int major, char *driver_name);
+
+/*!
+ * Print a message to console / into log file. After the @c msg argument a
+ * number of printf-style arguments may be added. Types should be limited to
+ * printf string, char, octal, decimal, and hexadecimal types. (This excludes
+ * pointers, and floating point).
+ *
+ * @param msg The message to print to console / system log
+ *
+ * @return (void)
+ */
+void os_printk(char *msg, ...);
+
+/*!
+ * Allocate some kernel memory
+ *
+ * @param amount Number of 8-bit bytes to allocate
+ * @param flags Some indication of purpose of memory (needs definition)
+ *
+ * @return Pointer to allocated memory, or NULL if failed.
+ */
+void *os_alloc_memory(unsigned amount, int flags);
+
+/*!
+ * Free some kernel memory
+ *
+ * @param location The beginning of the region to be freed.
+ *
+ * Do some OSes have separate free() functions which should be
+ * distinguished by passing in @c flags here, too? Don't some also require the
+ * size of the buffer being freed? Perhaps separate routines for each
+ * alloc/free pair (DMAable, etc.)?
+ */
+void os_free_memory(void *location);
+
+/*!
+ * Allocate cache-coherent memory
+ *
+ * @param amount Number of bytes to allocate
+ * @param[out] dma_addrp Location to store physical address of allocated
+ * memory.
+ * @param flags Some indication of purpose of memory (needs
+ * definition).
+ *
+ * @return (virtual space) pointer to allocated memory, or NULL if failed.
+ *
+ */
+void *os_alloc_coherent(unsigned amount, uint32_t * dma_addrp, int flags);
+
+/*!
+ * Free cache-coherent memory
+ *
+ * @param size Number of bytes which were allocated.
+ * @param[out] virt_addr Virtual(kernel) address of memory.to be freed, as
+ * returned by #os_alloc_coherent().
+ * @param[out] dma_addr Physical address of memory.to be freed, as returned
+ * by #os_alloc_coherent().
+ *
+ * @return void
+ *
+ */
+void os_free_coherent(unsigned size, void *virt_addr, uint32_t dma_addr);
+
+/*!
+ * Map an I/O space into kernel memory space
+ *
+ * @param start The starting address of the (physical / io space) region
+ * @param range_bytes The number of bytes to map
+ *
+ * @return A pointer to the mapped area, or NULL on failure
+ */
+void *os_map_device(uint32_t start, unsigned range_bytes);
+
+/*!
+ * Unmap an I/O space from kernel memory space
+ *
+ * @param start The starting address of the (virtual) region
+ * @param range_bytes The number of bytes to unmap
+ *
+ * @return None
+ */
+void os_unmap_device(void *start, unsigned range_bytes);
+
+/*!
+ * Copy data from Kernel space to User space
+ *
+ * @param to The target location in user memory
+ * @param from The source location in kernel memory
+ * @param size The number of bytes to be copied
+ *
+ * @return #os_error_code
+ */
+os_error_code os_copy_to_user(void *to, void *from, unsigned size);
+
+/*!
+ * Copy data from User space to Kernel space
+ *
+ * @param to The target location in kernel memory
+ * @param from The source location in user memory
+ * @param size The number of bytes to be copied
+ *
+ * @return #os_error_code
+ */
+os_error_code os_copy_from_user(void *to, void *from, unsigned size);
+
+/*!
+ * Read an 8-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @return The value in the register
+ */
+uint8_t os_read8(uint8_t * register_address);
+
+/*!
+ * Write an 8-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @param value The value to write into the register
+ */
+void os_write8(uint8_t * register_address, uint8_t value);
+
+/*!
+ * Read a 16-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @return The value in the register
+ */
+uint16_t os_read16(uint16_t * register_address);
+
+/*!
+ * Write a 16-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @param value The value to write into the register
+ */
+void os_write16(uint16_t * register_address, uint16_t value);
+
+/*!
+ * Read a 32-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @return The value in the register
+ */
+uint32_t os_read32(uint32_t * register_address);
+
+/*!
+ * Write a 32-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @param value The value to write into the register
+ */
+void os_write32(uint32_t * register_address, uint32_t value);
+
+/*!
+ * Read a 64-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @return The value in the register
+ */
+uint64_t os_read64(uint64_t * register_address);
+
+/*!
+ * Write a 64-bit device register
+ *
+ * @param register_address The (bus) address of the register to write to
+ * @param value The value to write into the register
+ */
+void os_write64(uint64_t * register_address, uint64_t value);
+
+/*!
+ * Prepare a task to execute the given function. This should only be done once
+ * per task, during the driver's initialization routine.
+ *
+ * @param task_fn Name of the OS_DEV_TASK() function to be created.
+ *
+ * @return an OS ERROR code.
+ */
+os_error os_create_task(os_task_fn_t * task_fn);
+
+/*!
+ * Run the task associated with an #OS_DEV_TASK() function
+ *
+ * The task will begin execution sometime after or during this call.
+ *
+ * @param task_fn Name of the OS_DEV_TASK() function to be scheduled.
+ *
+ * @return void
+ */
+void os_dev_schedule_task(os_task_fn_t * task_fn);
+
+/*!
+ * Make sure that task is no longer running and will no longer run.
+ *
+ * This function will not return until both are true. This is useful when
+ * shutting down a driver.
+ *
+ * @param task_fn Name of the OS_DEV_TASK() funciton to be stopped.
+ *
+ */
+void os_stop_task(os_task_fn_t * task_fn);
+
+/*!
+ * Delay some number of microseconds
+ *
+ * Note that this is a busy-loop, not a suspension of the task/process.
+ *
+ * @param msecs The number of microseconds to delay
+ *
+ * @return void
+ */
+void os_mdelay(unsigned long msecs);
+
+/*!
+ * Calculate virtual address from physical address
+ *
+ * @param pa Physical address
+ *
+ * @return virtual address
+ *
+ * @note this assumes that addresses are 32 bits wide
+ */
+void *os_va(uint32_t pa);
+
+/*!
+ * Calculate physical address from virtual address
+ *
+ *
+ * @param va Virtual address
+ *
+ * @return physical address
+ *
+ * @note this assumes that addresses are 32 bits wide
+ */
+uint32_t os_pa(void *va);
+
+/*!
+ * Allocate and initialize a lock, returning a lock handle.
+ *
+ * The lock state will be initialized to 'unlocked'.
+ *
+ * @return A lock handle, or NULL if an error occurred.
+ */
+os_lock_t os_lock_alloc_init(void);
+
+/*!
+ * Acquire a lock.
+ *
+ * This function should only be called from an interrupt service routine.
+ *
+ * @param lock_handle A handle to the lock to acquire.
+ *
+ * @return void
+ */
+void os_lock(os_lock_t lock_handle);
+
+/*!
+ * Unlock a lock. Lock must have been acquired by #os_lock().
+ *
+ * @param lock_handle A handle to the lock to unlock.
+ *
+ * @return void
+ */
+void os_unlock(os_lock_t lock_handle);
+
+/*!
+ * Acquire a lock in non-ISR context
+ *
+ * This function will spin until the lock is available.
+ *
+ * @param lock_handle A handle of the lock to acquire.
+ * @param context Place to save the before-lock context
+ *
+ * @return void
+ */
+void os_lock_save_context(os_lock_t lock_handle, os_lock_context_t context);
+
+/*!
+ * Release a lock in non-ISR context
+ *
+ * @param lock_handle A handle of the lock to release.
+ * @param context Place where before-lock context was saved.
+ *
+ * @return void
+ */
+void os_unlock_restore_context(os_lock_t lock_handle,
+ os_lock_context_t context);
+
+/*!
+ * Deallocate a lock handle.
+ *
+ * @param lock_handle An #os_lock_t that has been allocated.
+ *
+ * @return void
+ */
+void os_lock_deallocate(os_lock_t lock_handle);
+
+/*!
+ * Determine process handle
+ *
+ * The process handle of the current user is returned.
+ *
+ * @return A handle on the current process.
+ */
+os_process_handle_t os_get_process_handle();
+
+/*!
+ * Send a signal to a process
+ *
+ * @param proc A handle to the target process.
+ * @param sig The POSIX signal to send to that process.
+ */
+void os_send_signal(os_process_handle_t proc, int sig);
+
+/*!
+ * Get some random bytes
+ *
+ * @param buf The location to store the random data.
+ * @param count The number of bytes to store.
+ *
+ * @return void
+ */
+void os_get_random_bytes(void *buf, unsigned count);
+
+/*!
+ * Go to sleep on an object.
+ *
+ * Example: code = os_sleep(my_queue, available_count == 0, 0);
+ *
+ * @param object The object on which to sleep
+ * @param condition An expression to check for sleep completion. Must be
+ * coded so that it can be referenced more than once inside
+ * macro, i.e., no ++ or other modifying expressions.
+ * @param atomic Non-zero if sleep must not return until condition.
+ *
+ * @return error code -- OK or sleep interrupted??
+ */
+os_error_code os_sleep(os_sleep_object_t object, unsigned condition,
+ unsigned atomic);
+
+/*!
+ * Wake up whatever is sleeping on sleep object
+ *
+ * @param object The object on which things might be sleeping
+ *
+ * @return none
+ */
+void os_wake_sleepers(os_sleep_object_t object);
+
+ /*! @} *//* dkops */
+
+/*****************************************************************************
+ * Function-signature-generating macros
+ *****************************************************************************/
+
+/*!
+ * @defgroup drsigs Driver Function Signatures
+ *
+ * These macros will define the entry point signatures for interrupt handlers;
+ * driver initialization and shutdown; device open/close; etc. They are to be
+ * used whenever the Kernel will call into the Driver. They are not
+ * appropriate for driver calls to other routines in the driver.
+ *
+ * There are three versions of each macro for a given Driver Entry Point. The
+ * first version is used to define a function and its implementation in the
+ * driver.c file, e.g. #OS_DEV_INIT().
+ *
+ * The second form is used whenever a forward declaration (prototype) is
+ * needed. It has the letters @c _DCL appended to the name of the definition
+ * function. These are not otherwise mentioned in this documenation.
+ *
+ * There is a third form used when a reference to a function is required, for
+ * instance when passing the routine as a pointer to a function. It has the
+ * letters @c _REF appended to the name of the definition function
+ * (e.g. DEV_IOCTL_REF).
+ *
+ * Note that these two extra forms are required because of the possibility of
+ * having an invisible 'wrapper function' created by the os-specific header
+ * file which would need to be invoked by the operating system, and which in
+ * turn would invoke the generic function.
+ *
+ * Example:
+ *
+ * (in a header file)
+ * @code
+ * OS_DEV_INIT_DCL(widget_init);
+ * OS_DEV_ISR_DCL(widget_isr);
+ * @endcode
+ *
+ * (in an implementation file)
+ * @code
+ * OS_DEV_INIT(widget, widget_init)
+ * {
+ *
+ * os_register_interrupt("widget", WIDGET_IRQ, OS_DEV_ISR_REF(widget_isr));
+ *
+ * os_dev_init_return(OS_RETURN_NO_ERROR_S);
+ * }
+ *
+ * OS_DEV_ISR(widget_isr)
+ * {
+ * os_dev_isr_return(TRUE);
+ * }
+ * @endcode
+ */
+
+/*! @addtogroup drsigs */
+/*! @{ */
+
+/*!
+ * Define a function which will handle device initialization
+ *
+ * This is tne driver initialization routine. This is normally where the
+ * part would be initialized; queues, locks, interrupts handlers defined;
+ * long-term dynamic memory allocated for driver use; etc.
+ *
+ * @param function_name The name of the portable initialization function.
+ *
+ * @return A call to #os_dev_init_return()
+ *
+ */
+#define OS_DEV_INIT(function_name)
+
+/*!
+ * Define a function which will handle device shutdown
+ *
+ * This is the reverse of the #OS_DEV_INIT() routine.
+ *
+ * @param function_name The name of the portable driver shutdown routine.
+ *
+ * @return A call to #os_dev_shutdown_return()
+ */
+#define OS_DEV_SHUTDOWN(function_name)
+
+/*!
+ * Define a function which will open the device for a user.
+ *
+ * @param function_name The name of the driver open() function
+ *
+ * @return A call to #os_dev_open_return()
+ */
+#define OS_DEV_OPEN(function_name)
+
+/*!
+ * Define a function which will handle a user's ioctl() request
+ *
+ * @param function_name The name of the driver ioctl() function
+ *
+ * @return A call to #os_dev_ioctl_return()
+ */
+#define OS_DEV_IOCTL(function_name)
+
+/*!
+ * Define a function which will handle a user's read() request
+ *
+ * @param function_name The name of the driver read() function
+ *
+ * @return A call to #os_dev_read_return()
+ */
+#define OS_DEV_READ(function_name)
+
+/*!
+ * Define a function which will handle a user's write() request
+ *
+ * @param function_name The name of the driver write() function
+ *
+ * @return A call to #os_dev_write_return()
+ */
+#define OS_DEV_WRITE(function_name)
+
+/*!
+ * Define a function which will handle a user's mmap() request
+ *
+ * The mmap() function requests the driver to map some memory into user space.
+ *
+ * @todo Determine what support functions are needed for mmap() handling.
+ *
+ * @param function_name The name of the driver mmap() function
+ *
+ * @return A call to #os_dev_mmap_return()
+ */
+#define OS_DEV_MMAP(function_name)
+
+/*!
+ * Define a function which will close the device - opposite of OS_DEV_OPEN()
+ *
+ * @param function_name The name of the driver close() function
+ *
+ * @return A call to #os_dev_close_return()
+ */
+#define OS_DEV_CLOSE(function_name)
+
+/*!
+ * Define a function which will handle an interrupt
+ *
+ * No arguments are available to the generic function. It must not invoke any
+ * OS functions which are illegal in a ISR. It gets no parameters, and must
+ * have a call to #os_dev_isr_return() instead of any/all return statements.
+ *
+ * Example:
+ * @code
+ * OS_DEV_ISR(widget, widget_isr, WIDGET_IRQ_NUMBER)
+ * {
+ * os_dev_isr_return(1);
+ * }
+ * @endcode
+ *
+ * @param function_name The name of the driver ISR function
+ *
+ * @return A call to #os_dev_isr_return()
+ */
+#define OS_DEV_ISR(function_name)
+
+/*!
+ * Define a function which will operate as a background task / bottom half.
+ *
+ * The function implementation must be structured in the following manner:
+ * @code
+ * OS_DEV_TASK(widget_task)
+ * {
+ * OS_DEV_TASK_SETUP(widget_task);
+ *
+ * while OS_DEV_TASK_CONDITION(widget_task) }
+ *
+ * };
+ * }
+ * @endcode
+ *
+ * @todo In some systems the OS_DEV_TASK_CONDITION() will be an action which
+ * will cause the task to sleep on some event triggered by os_run_task(). In
+ * others, the macro will reference a variable laid down by
+ * OS_DEV_TASK_SETUP() to make sure that the loop is only performed once.
+ *
+ * @param function_name The name of this background task function
+ */
+#define OS_DEV_TASK(function_name)
+
+ /*! @} *//* drsigs */
+
+/*! @defgroup dclsigs Routines to declare Driver Signature routines
+ *
+ * These macros drop prototypes suitable for forward-declaration of
+ * @ref drsigs "function signatures".
+ */
+
+/*! @addtogroup dclsigs */
+/*! @{ */
+
+/*!
+ * Declare prototype for the device initialization function
+ *
+ * @param function_name The name of the portable initialization function.
+ */
+#define OS_DEV_INIT_DCL(function_name)
+
+/*!
+ * Declare prototype for the device shutdown function
+ *
+ * @param function_name The name of the portable driver shutdown routine.
+ *
+ * @return A call to #os_dev_shutdown_return()
+ */
+#define OS_DEV_SHUTDOWN_DCL(function_name)
+
+/*!
+ * Declare prototype for the open() function.
+ *
+ * @param function_name The name of the driver open() function
+ *
+ * @return A call to #os_dev_open_return()
+ */
+#define OS_DEV_OPEN_DCL(function_name)
+
+/*!
+ * Declare prototype for the user's ioctl() request function
+ *
+ * @param function_name The name of the driver ioctl() function
+ *
+ * @return A call to #os_dev_ioctl_return()
+ */
+#define OS_DEV_IOCTL_DCL(function_name)
+
+/*!
+ * Declare prototype for the function a user's read() request
+ *
+ * @param function_name The name of the driver read() function
+ */
+#define OS_DEV_READ_DCL(function_name)
+
+/*!
+ * Declare prototype for the user's write() request function
+ *
+ * @param function_name The name of the driver write() function
+ */
+#define OS_DEV_WRITE_DCL(function_name)
+
+/*!
+ * Declare prototype for the user's mmap() request function
+ *
+ * @param function_name The name of the driver mmap() function
+ */
+#define OS_DEV_MMAP_DCL(function_name)
+
+/*!
+ * Declare prototype for the close function
+ *
+ * @param function_name The name of the driver close() function
+ *
+ * @return A call to #os_dev_close_return()
+ */
+#define OS_DEV_CLOSE_DCL(function_name)
+
+/*!
+ * Declare prototype for the interrupt handling function
+ *
+ * @param function_name The name of the driver ISR function
+ */
+#define OS_DEV_ISR_DCL(function_name)
+
+/*!
+ * Declare prototype for a background task / bottom half function
+ *
+ * @param function_name The name of this background task function
+ */
+#define OS_DEV_TASK_DCL(function_name)
+
+ /*! @} *//* dclsigs */
+
+/*****************************************************************************
+ * Functions for Returning Values from Driver Signature routines
+ *****************************************************************************/
+
+/*!
+ * @defgroup retfns Functions to Return Values from Driver Signature routines
+ */
+
+/*! @addtogroup retfns */
+/*! @{ */
+
+/*!
+ * Return from the #OS_DEV_INIT() function
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+void os_dev_init_return(os_error_code code);
+
+/*!
+ * Return from the #OS_DEV_SHUTDOWN() function
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+void os_dev_shutdown_return(os_error_code code);
+
+/*!
+ * Return from the #OS_DEV_ISR() function
+ *
+ * The function should verify that it really was supposed to be called,
+ * and that its device needed attention, in order to properly set the
+ * return code.
+ *
+ * @param code non-zero if interrupt handled, zero otherwise.
+ *
+ */
+void os_dev_isr_return(int code);
+
+/*!
+ * Return from the #OS_DEV_OPEN() function
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+void os_dev_open_return(os_error_code code);
+
+/*!
+ * Return from the #OS_DEV_IOCTL() function
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+void os_dev_ioctl_return(os_error_code code);
+
+/*!
+ * Return from the #OS_DEV_READ() function
+ *
+ * @param code Number of bytes read, or an error code to report failure.
+ *
+ */
+void os_dev_read_return(os_error_code code);
+
+/*!
+ * Return from the #OS_DEV_WRITE() function
+ *
+ * @param code Number of bytes written, or an error code to report failure.
+ *
+ */
+void os_dev_write_return(os_error_code code);
+
+/*!
+ * Return from the #OS_DEV_MMAP() function
+ *
+ * @param code Number of bytes written, or an error code to report failure.
+ *
+ */
+void os_dev_mmap_return(os_error_code code);
+
+/*!
+ * Return from the #OS_DEV_CLOSE() function
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+void os_dev_close_return(os_error_code code);
+
+/*!
+ * Start the #OS_DEV_TASK() function
+ *
+ * In some implementations, this could be turned into a label for
+ * the os_dev_task_return() call.
+ *
+ * For a more portable interface, should this take the sleep object as an
+ * argument???
+ *
+ * @return none
+ */
+void os_dev_task_begin(void);
+
+/*!
+ * Return from the #OS_DEV_TASK() function
+ *
+ * In some implementations, this could be turned into a sleep followed
+ * by a jump back to the os_dev_task_begin() call.
+ *
+ * @param code An error code to report success or failure.
+ *
+ */
+void os_dev_task_return(os_error_code code);
+
+ /*! @} *//* retfns */
+
+/*****************************************************************************
+ * Functions/Macros for accessing arguments from Driver Signature routines
+ *****************************************************************************/
+
+/*! @defgroup drsigargs Functions for Getting Arguments in Signature functions
+ *
+ */
+/* @addtogroup @drsigargs */
+/*! @{ */
+
+/*!
+ * Check whether user is requesting read (permission) on the file/device.
+ * Usable in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ()
+ * and #OS_DEV_WRITE() routines.
+ */
+int os_dev_is_flag_read(void);
+
+/*!
+ * Check whether user is requesting write (permission) on the file/device.
+ * Usable in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ()
+ * and #OS_DEV_WRITE() routines.
+ */
+int os_dev_is_flag_write(void);
+
+/*!
+ * Check whether user is requesting non-blocking I/O. Usable in
+ * #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and
+ * #OS_DEV_WRITE() routines.
+ *
+ * @todo Specify required behavior when nonblock is requested and (sufficient?)
+ * data are not available to fulfill the request.
+ *
+ */
+int os_dev_is_flag_nonblock(void);
+
+/*!
+ * Determine which major device is being accessed. Usable in #OS_DEV_OPEN()
+ * and #OS_DEV_CLOSE().
+ */
+int os_dev_get_major(void);
+
+/*!
+ * Determine which minor device is being accessed. Usable in #OS_DEV_OPEN()
+ * and #OS_DEV_CLOSE().
+ */
+int os_dev_get_minor(void);
+
+/*!
+ * Determine which operation the user wants performed. Usable in
+ * #OS_DEV_IOCTL().
+ *
+ * @return Value of the operation.
+ *
+ * @todo Define some generic way to define the individual operations.
+ */
+unsigned os_dev_get_ioctl_op(void);
+
+/*!
+ * Retrieve the associated argument for the desired operation. Usable in
+ * #OS_DEV_IOCTL().
+ *
+ * @return A value which can be cast to a struct pointer or used as
+ * int/long.
+ */
+os_dev_ioctl_arg_t os_dev_get_ioctl_arg(void);
+
+/*!
+ * Determine the requested byte count. This should be the size of buffer at
+ * #os_dev_get_user_buffer(). Usable in OS_DEV_READ() and OS_DEV_WRITE()
+ * routines.
+ *
+ * @return A count of bytes
+ */
+unsigned os_dev_get_count(void);
+
+/*!
+ * Get the pointer to the user's data buffer. Usable in OS_DEV_READ(),
+ * OS_DEV_WRITE(), and OS_DEV_MMAP() routines.
+ *
+ * @return Pointer to user buffer (in user space). See #os_copy_to_user()
+ * and #os_copy_from_user().
+ */
+void *os_dev_get_user_buffer(void);
+
+/*!
+ * Get the POSIX flags field for the associated open file. Usable in
+ * OS_DEV_READ(), OS_DEV_WRITE(), and OS_DEV_IOCTL() routines.
+ *
+ * @return The flags associated with the file.
+ */
+unsigned os_dev_get_file_flags(void);
+
+/*!
+ * Set the driver's private structure associated with this file/open.
+ *
+ * Generally used during #OS_DEV_OPEN(). May also be used during
+ * #OS_DEV_READ(), #OS_DEV_WRITE(), #OS_DEV_IOCTL(), #OS_DEV_MMAP(), and
+ * #OS_DEV_CLOSE(). See also #os_dev_get_user_private().
+ *
+ * @param struct_p The driver data structure to associate with this user.
+ */
+void os_dev_set_user_private(void *struct_p);
+
+/*!
+ * Get the driver's private structure associated with this file.
+ *
+ * May be used during #OS_DEV_OPEN(), #OS_DEV_READ(), #OS_DEV_WRITE(),
+ * #OS_DEV_IOCTL(), #OS_DEV_MMAP(), and #OS_DEV_CLOSE(). See
+ * also #os_dev_set_user_private().
+ *
+ * @return The driver data structure to associate with this user.
+ */
+void *os_dev_get_user_private(void);
+
+/*!
+ * Get the IRQ associated with this call to the #OS_DEV_ISR() function.
+ *
+ * @return The IRQ (integer) interrupt number.
+ */
+int os_dev_get_irq(void);
+
+ /*! @} *//* drsigargs */
+
+/*****************************************************************************
+ * Functions for Generating References to Driver Routines
+ *****************************************************************************/
+
+/*!
+ * @defgroup drref Functions for Generating References to Driver Routines
+ *
+ * These functions will most likely be implemented as macros. They are a
+ * necessary part of the portable API to guarantee portability. The @c symbol
+ * type in here is the same symbol passed to the associated
+ * signature-generating macro.
+ *
+ * These macros must be used whenever referring to a
+ * @ref drsigs "driver signature function", for instance when storing or
+ * passing a pointer to the function.
+ */
+
+/*! @addtogroup drref */
+/*! @{ */
+
+/*!
+ * Generate a reference to an #OS_DEV_INIT() function
+ *
+ * @param function_name The name of the init function being referenced.
+ *
+ * @return A reference to the function
+ */
+os_init_function_t OS_DEV_INIT_REF(symbol function_name);
+
+/*!
+ * Generate a reference to an #OS_DEV_SHUTDOWN() function
+ *
+ * @param function_name The name of the shutdown function being referenced.
+ *
+ * @return A reference to the function
+ */
+os_shutdown_function_t OS_DEV_SHUTDOWN_REF(symbol function_name);
+
+/*!
+ * Generate a reference to an #OS_DEV_OPEN() function
+ *
+ * @param function_name The name of the open function being referenced.
+ *
+ * @return A reference to the function
+ */
+os_user_function_t OS_DEV_OPEN_REF(symbol function_name);
+
+/*!
+ * Generate a reference to an #OS_DEV_CLOSE() function
+ *
+ * @param function_name The name of the close function being referenced.
+ *
+ * @return A reference to the function
+ */
+os_user_function_t OS_DEV_CLOSE_REF(symbol function_name);
+
+/*!
+ * Generate a reference to an #OS_DEV_READ() function
+ *
+ * @param function_name The name of the read function being referenced.
+ *
+ * @return A reference to the function
+ */
+os_user_function_t OS_DEV_READ_REF(symbol function_name);
+
+/*!
+ * Generate a reference to an #OS_DEV_WRITE() function
+ *
+ * @param function_name The name of the write function being referenced.
+ *
+ * @return A reference to the function
+ */
+os_user_function_t OS_DEV_WRITE_REF(symbol function_name);
+
+/*!
+ * Generate a reference to an #OS_DEV_IOCTL() function
+ *
+ * @param function_name The name of the ioctl function being referenced.
+ *
+ * @return A reference to the function
+ */
+os_user_function_t OS_DEV_IOCTL_REF(symbol function_name);
+
+/*!
+ * Generate a reference to an #OS_DEV_MMAP() function
+ *
+ * @param function_name The name of the mmap function being referenced.
+ *
+ * @return A reference to the function
+ */
+os_user_function_t OS_DEV_MMAP_REF(symbol function_name);
+
+/*!
+ * Generate a reference to an #OS_DEV_ISR() function
+ *
+ * @param function_name The name of the isr being referenced.
+ *
+ * @return a reference to the function
+ */
+os_interrupt_handler_t OS_DEV_ISR_REF(symbol function_name);
+
+ /*! @} *//* drref */
+
+/*!
+ * Flush and invalidate all cache lines.
+ */
+void os_flush_cache_all(void);
+
+/*!
+ * Flush a range of addresses from the cache
+ *
+ * @param start Starting virtual address
+ * @param len Number of bytes to flush
+ */
+void os_cache_flush_range(void *start, uint32_t len);
+
+/*!
+ * Invalidate a range of addresses in the cache
+ *
+ * @param start Starting virtual address
+ * @param len Number of bytes to flush
+ */
+void os_cache_inv_range(void *start, uint32_t len);
+
+/*!
+ * Clean a range of addresses from the cache
+ *
+ * @param start Starting virtual address
+ * @param len Number of bytes to flush
+ */
+void os_cache_clean_range(void *start, uint32_t len);
+
+/*!
+ * @example widget.h
+ */
+
+/*!
+ * @example widget.c
+ */
+
+/*!
+ * @example rng_driver.h
+ */
+
+/*!
+ * @example rng_driver.c
+ */
+
+/*!
+ * @example shw_driver.h
+ */
+
+/*!
+ * @example shw_driver.c
+ */
+
+#endif /* DOXYGEN_PORTABLE_OS_DOC */
+
+#endif /* PORTABLE_OS_H */
diff --git a/drivers/mxc/security/sahara2/include/sah_driver_common.h b/drivers/mxc/security/sahara2/include/sah_driver_common.h
new file mode 100644
index 000000000000..bcdc053bf0c3
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/sah_driver_common.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/**
+* @file sah_driver_common.h
+*
+* @brief Provides types and defined values for use in the Driver Interface.
+*
+*/
+
+#ifndef SAH_DRIVER_COMMON_H
+#define SAH_DRIVER_COMMON_H
+
+#include "fsl_platform.h"
+#include <sahara.h>
+#include <adaptor.h>
+
+/** This specifies the permissions for the device file. It is equivalent to
+ * chmod 666.
+ */
+#define SAHARA_DEVICE_MODE S_IFCHR | S_IRUGO | S_IWUGO
+
+/**
+* The status of entries in the Queue.
+*
+******************************************************************************/
+typedef enum
+{
+ /** This state indicates that the entry is in the queue and awaits
+ * execution on SAHARA. */
+ SAH_STATE_PENDING,
+ /** This state indicates that the entry has been written to the SAHARA
+ * DAR. */
+ SAH_STATE_ON_SAHARA,
+ /** This state indicates that the entry is off of SAHARA, and is awaiting
+ post-processing. */
+ SAH_STATE_OFF_SAHARA,
+ /** This state indicates that the entry is successfully executed on SAHARA,
+ and it is finished with post-processing. */
+ SAH_STATE_COMPLETE,
+ /** This state indicates that the entry caused an error or fault on SAHARA,
+ * and it is finished with post-processing. */
+ SAH_STATE_FAILED,
+ /** This state indicates that the entry was reset via the Reset IO
+ * Control, and it is finished with post-processing. */
+ SAH_STATE_RESET,
+ /** This state indicates that the entry was signalled from user-space and
+ * either in the DAR, IDAR or has finished executing pending Bottom Half
+ * processing. */
+ SAH_STATE_IGNORE,
+ /** This state indicates that the entry was signalled from user-space and
+ * has been processed by the bottom half. */
+ SAH_STATE_IGNORED
+} sah_Queue_Status;
+
+/* any of these conditions being true indicates the descriptor's processing
+ * is complete */
+#define SAH_DESC_PROCESSED(status) \
+ (((status) == SAH_STATE_COMPLETE) || \
+ ((status) == SAH_STATE_FAILED ) || \
+ ((status) == SAH_STATE_RESET ))
+
+extern os_lock_t desc_queue_lock;
+
+extern uint32_t dar_count;
+extern uint32_t interrupt_count;
+extern uint32_t done1done2_count;
+extern uint32_t done1busy2_count;
+extern uint32_t done1_count;
+
+#ifdef FSL_HAVE_SCC2
+extern void *lookup_user_partition(fsl_shw_uco_t * user_ctx,
+ uint32_t user_base);
+#endif
+
+int sah_get_results_pointers(fsl_shw_uco_t* user_ctx, uint32_t arg);
+fsl_shw_return_t sah_get_results_from_pool(volatile fsl_shw_uco_t* user_ctx,
+ sah_results *arg);
+fsl_shw_return_t sah_handle_registration(fsl_shw_uco_t *user_cts);
+fsl_shw_return_t sah_handle_deregistration(fsl_shw_uco_t *user_cts);
+
+int sah_Queue_Manager_Count_Entries(int ignore_state, sah_Queue_Status state);
+unsigned long sah_Handle_Poll(sah_Head_Desc *entry);
+
+#ifdef DIAG_DRV_IF
+/******************************************************************************
+* Descriptor and Link dumping functions.
+******************************************************************************/
+void sah_Dump_Chain(const sah_Desc *chain, dma_addr_t addr);
+#endif /* DIAG_DRV_IF */
+
+#endif /* SAH_DRIVER_COMMON_H */
diff --git a/drivers/mxc/security/sahara2/include/sah_hardware_interface.h b/drivers/mxc/security/sahara2/include/sah_hardware_interface.h
new file mode 100644
index 000000000000..f507a835a504
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/sah_hardware_interface.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/**
+* @file sah_hardware_interface.h
+*
+* @brief Provides an interface to the SAHARA hardware registers.
+*
+*/
+
+#ifndef SAH_HARDWARE_INTERFACE_H
+#define SAH_HARDWARE_INTERFACE_H
+
+#include <sah_driver_common.h>
+#include <sah_status_manager.h>
+
+/* These values can be used with sah_HW_Write_Control(). */
+#ifdef SAHARA1
+/** Define platform as Little-Endian */
+#define CTRL_LITTLE_END 0x00000002
+/** Bit to cause endian change in transfers */
+#define CTRL_INT_EN 0x00000004
+/** Set High Assurance mode */
+#define CTRL_HA 0x00000008
+#else
+/** Bit to cause byte swapping in (data?) transfers */
+#define CTRL_BYTE_SWAP 0x00000001
+/** Bit to cause halfword swapping in (data?) transfers */
+#define CTRL_HALFWORD_SWAP 0x00000002
+/** Bit to cause endian change in (data?) transfers */
+#define CTRL_INT_EN 0x00000010
+/** Set High Assurance mode */
+#define CTRL_HA 0x00000020
+/** Disable High Assurance */
+#define CTRL_HA_DISABLE 0x00000040
+/** Reseed the RNG CHA */
+#define CTRL_RNG_RESEED 0x00000080
+#endif
+
+
+/* These values can be used with sah_HW_Write_Command(). */
+/** Reset the Sahara */
+#define CMD_RESET 0x00000001
+/** Set Sahara into Batch mode. */
+#define CMD_BATCH 0x00010000
+/** Clear the Sahara interrupt */
+#define CMD_CLR_INT_BIT 0x00000100
+/** Clear the Sahara error */
+#define CMD_CLR_ERROR_BIT 0x00000200
+
+
+/** error status register contains error */
+#define STATUS_ERROR 0x00000010
+
+/** Op status register contains op status */
+#define OP_STATUS 0x00000020
+
+
+/* High Level functions */
+int sah_HW_Reset(void);
+fsl_shw_return_t sah_HW_Set_HA(void);
+sah_Execute_Status sah_Wait_On_Sahara(void);
+
+/* Low Level functions */
+uint32_t sah_HW_Read_Version(void);
+uint32_t sah_HW_Read_Control(void);
+uint32_t sah_HW_Read_Status(void);
+uint32_t sah_HW_Read_Error_Status(void);
+uint32_t sah_HW_Read_Op_Status(void);
+uint32_t sah_HW_Read_DAR(void);
+uint32_t sah_HW_Read_CDAR(void);
+uint32_t sah_HW_Read_IDAR(void);
+uint32_t sah_HW_Read_Fault_Address(void);
+uint32_t sah_HW_Read_MM_Status(void);
+uint32_t sah_HW_Read_Config(void);
+void sah_HW_Write_Command(uint32_t command);
+void sah_HW_Write_Control(uint32_t control);
+void sah_HW_Write_DAR(uint32_t pointer);
+void sah_HW_Write_Config(uint32_t configuration);
+
+#if defined DIAG_DRV_IF || defined(DO_DBG)
+
+void sah_Dump_Words(const char *prefix, const unsigned *data, dma_addr_t addr,
+ unsigned length);
+#endif
+
+#endif /* SAH_HARDWARE_INTERFACE_H */
+
+/* End of sah_hardware_interface.c */
diff --git a/drivers/mxc/security/sahara2/include/sah_interrupt_handler.h b/drivers/mxc/security/sahara2/include/sah_interrupt_handler.h
new file mode 100644
index 000000000000..fc4d77475f85
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/sah_interrupt_handler.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/**
+* @file sah_interrupt_handler.h
+*
+* @brief Provides a hardware interrupt handling mechanism for device driver.
+*
+*/
+/******************************************************************************
+*
+* CAUTION:
+*
+* MODIFICATION HISTORY:
+*
+* Date Person Change
+* 30/07/03 MW Initial Creation
+*******************************************************************
+*/
+
+#ifndef SAH_INTERRUPT_HANDLER_H
+#define SAH_INTERRUPT_HANDLER_H
+
+#include <sah_driver_common.h>
+
+/******************************************************************************
+* External function declarations
+******************************************************************************/
+int sah_Intr_Init (wait_queue_head_t *wait_queue);
+void sah_Intr_Release (void);
+
+#endif /* SAH_INTERRUPT_HANDLER_H */
diff --git a/drivers/mxc/security/sahara2/include/sah_kernel.h b/drivers/mxc/security/sahara2/include/sah_kernel.h
new file mode 100644
index 000000000000..e39a61e64430
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/sah_kernel.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+* @file sah_kernel.h
+*
+* @brief Provides definitions for items that user-space and kernel-space share.
+*/
+/******************************************************************************
+*
+* This file needs to be PORTED to a non-Linux platform
+*/
+
+#ifndef SAH_KERNEL_H
+#define SAH_KERNEL_H
+
+#if defined(__KERNEL__)
+
+#if defined(CONFIG_ARCH_MXC91321) || defined(CONFIG_ARCH_MXC91231) \
+ || defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MXC92323)
+#include <mach/hardware.h>
+#define SAHA_BASE_ADDR SAHARA_BASE_ADDR
+#define SAHARA_IRQ MXC_INT_SAHARA
+#elif defined(CONFIG_ARCH_MX5)
+#include <mach/hardware.h>
+#define SAHA_BASE_ADDR SAHARA_BASE_ADDR
+#define SAHARA_IRQ MXC_INT_SAHARA_H0
+#else
+#include <mach/mx2.h>
+#endif
+
+#endif /* KERNEL */
+
+/* IO Controls */
+/* The magic number 'k' is reserved for the SPARC architecture. (See <kernel
+ * source root>/Documentation/ioctl-number.txt.
+ *
+ * Note: Numbers 8-13 were used in a previous version of the API and should
+ * be avoided.
+ */
+#define SAH_IOC_MAGIC 'k'
+#define SAHARA_HWRESET _IO(SAH_IOC_MAGIC, 0)
+#define SAHARA_SET_HA _IO(SAH_IOC_MAGIC, 1)
+#define SAHARA_CHK_TEST_MODE _IOR(SAH_IOC_MAGIC,2, int)
+#define SAHARA_DAR _IO(SAH_IOC_MAGIC, 3)
+#define SAHARA_GET_RESULTS _IO(SAH_IOC_MAGIC, 4)
+#define SAHARA_REGISTER _IO(SAH_IOC_MAGIC, 5)
+#define SAHARA_DEREGISTER _IO(SAH_IOC_MAGIC, 6)
+/* 7 */
+/* 8 */
+/* 9 */
+/* 10 */
+/* 11 */
+/* 12 */
+/* 13 */
+
+#define SAHARA_SCC_DROP_PERMS _IOWR(SAH_IOC_MAGIC, 14, scc_partition_info_t)
+#define SAHARA_SCC_SFREE _IOWR(SAH_IOC_MAGIC, 15, scc_partition_info_t)
+
+#define SAHARA_SK_ALLOC _IOWR(SAH_IOC_MAGIC, 16, scc_slot_t)
+#define SAHARA_SK_DEALLOC _IOWR(SAH_IOC_MAGIC, 17, scc_slot_t)
+#define SAHARA_SK_LOAD _IOWR(SAH_IOC_MAGIC, 18, scc_slot_t)
+#define SAHARA_SK_UNLOAD _IOWR(SAH_IOC_MAGIC, 19, scc_slot_t)
+#define SAHARA_SK_SLOT_ENC _IOWR(SAH_IOC_MAGIC, 20, scc_slot_t)
+#define SAHARA_SK_SLOT_DEC _IOWR(SAH_IOC_MAGIC, 21, scc_slot_t)
+
+#define SAHARA_SCC_ENCRYPT _IOWR(SAH_IOC_MAGIC, 22, scc_region_t)
+#define SAHARA_SCC_DECRYPT _IOWR(SAH_IOC_MAGIC, 23, scc_region_t)
+#define SAHARA_GET_CAPS _IOWR(SAH_IOC_MAGIC, 24, fsl_shw_pco_t)
+
+#define SAHARA_SCC_SSTATUS _IOWR(SAH_IOC_MAGIC, 25, scc_partition_info_t)
+
+#define SAHARA_SK_READ _IOWR(SAH_IOC_MAGIC, 29, scc_slot_t)
+
+/*! This is the name that will appear in /proc/interrupts */
+#define SAHARA_NAME "SAHARA"
+
+/*!
+ * SAHARA IRQ number. See page 9-239 of TLICS - Motorola Semiconductors H.K.
+ * TAHITI-Lite IC Specification, Rev 1.1, Feb 2003.
+ *
+ * TAHITI has two blocks of 32 interrupts. The SAHARA IRQ is number 27
+ * in the second block. This means that the SAHARA IRQ is 27 + 32 = 59.
+ */
+#ifndef SAHARA_IRQ
+#define SAHARA_IRQ (27+32)
+#endif
+
+/*!
+ * Device file definition. The #ifndef is here to support the unit test code
+ * by allowing it to specify a different test device.
+ */
+#ifndef SAHARA_DEVICE_SHORT
+#define SAHARA_DEVICE_SHORT "sahara"
+#endif
+
+#ifndef SAHARA_DEVICE
+#define SAHARA_DEVICE "/dev/"SAHARA_DEVICE_SHORT
+#endif
+
+#endif /* SAH_KERNEL_H */
+
+/* End of sah_kernel.h */
diff --git a/drivers/mxc/security/sahara2/include/sah_memory_mapper.h b/drivers/mxc/security/sahara2/include/sah_memory_mapper.h
new file mode 100644
index 000000000000..ddf4a59af540
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/sah_memory_mapper.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/**
+* @file sah_memory_mapper.h
+*
+* @brief Re-creates SAHARA data structures in Kernel memory such that they are
+* suitable for DMA.
+*
+*/
+
+#ifndef SAH_MEMORY_MAPPER_H
+#define SAH_MEMORY_MAPPER_H
+
+#include <sah_driver_common.h>
+#include <sah_queue_manager.h>
+
+
+/******************************************************************************
+* External function declarations
+******************************************************************************/
+sah_Head_Desc *sah_Copy_Descriptors(fsl_shw_uco_t * user_ctx,
+ sah_Head_Desc * desc);
+
+sah_Link *sah_Copy_Links(fsl_shw_uco_t * user_ctx, sah_Link * ptr);
+
+sah_Head_Desc *sah_Physicalise_Descriptors(sah_Head_Desc * desc);
+
+sah_Link *sah_Physicalise_Links (sah_Link *ptr);
+
+sah_Head_Desc *sah_DePhysicalise_Descriptors (sah_Head_Desc *desc);
+
+sah_Link *sah_DePhysicalise_Links (sah_Link *ptr);
+
+sah_Link *sah_Make_Links(fsl_shw_uco_t * user_ctx,
+ sah_Link * ptr, sah_Link ** tail);
+
+
+void sah_Destroy_Descriptors (sah_Head_Desc *desc);
+
+void sah_Destroy_Links (sah_Link *link);
+
+void sah_Free_Chained_Descriptors (sah_Head_Desc *desc);
+
+void sah_Free_Chained_Links (sah_Link *link);
+
+int sah_Init_Mem_Map (void);
+
+void sah_Stop_Mem_Map (void);
+
+int sah_Block_Add_Page (int big);
+
+sah_Desc *sah_Alloc_Descriptor (void);
+sah_Head_Desc *sah_Alloc_Head_Descriptor (void);
+void sah_Free_Descriptor (sah_Desc *desc);
+void sah_Free_Head_Descriptor (sah_Head_Desc *desc);
+sah_Link *sah_Alloc_Link (void);
+void sah_Free_Link (sah_Link *link);
+
+void *wire_user_memory(void *address, uint32_t length, void **page_ctx);
+void unwire_user_memory(void **page_ctx);
+
+os_error_code map_user_memory(struct vm_area_struct *vma,
+ uint32_t physical_addr, uint32_t size);
+os_error_code unmap_user_memory(uint32_t user_addr, uint32_t size);
+
+#endif /* SAH_MEMORY_MAPPER_H */
+
+/* End of sah_memory_mapper.h */
diff --git a/drivers/mxc/security/sahara2/include/sah_queue_manager.h b/drivers/mxc/security/sahara2/include/sah_queue_manager.h
new file mode 100644
index 000000000000..895006f7ab91
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/sah_queue_manager.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/**
+* @file sah_queue_manager.h
+*
+* @brief This file definitions for the Queue Manager.
+
+* The Queue Manager manages additions and removal from the queue and updates
+* the status of queue entries. It also calls sah_HW_* functions to interact
+* with the hardware.
+*
+*/
+
+#ifndef SAH_QUEUE_MANAGER_H
+#define SAH_QUEUE_MANAGER_H
+
+#include <sah_driver_common.h>
+#include <sah_status_manager.h>
+
+
+/*************************
+* Queue Manager Functions
+*************************/
+fsl_shw_return_t sah_Queue_Manager_Init(void);
+void sah_Queue_Manager_Close(void);
+void sah_Queue_Manager_Reset_Entries(void);
+void sah_Queue_Manager_Append_Entry(sah_Head_Desc *entry);
+void sah_Queue_Manager_Remove_Entry(sah_Head_Desc *entry);
+
+
+/*************************
+* Queue Functions
+*************************/
+sah_Queue *sah_Queue_Construct(void);
+void sah_Queue_Destroy(sah_Queue *this);
+void sah_Queue_Append_Entry(sah_Queue *this, sah_Head_Desc *entry);
+void sah_Queue_Remove_Entry(sah_Queue *this);
+void sah_Queue_Remove_Any_Entry(sah_Queue *this, sah_Head_Desc *entry);
+void sah_postprocess_queue(unsigned long reset_flag);
+
+
+/*************************
+* Misc Releated Functions
+*************************/
+
+int sah_blocking_mode(struct sah_Head_Desc *entry);
+fsl_shw_return_t sah_convert_error_status(uint32_t error_status);
+
+
+#endif /* SAH_QUEUE_MANAGER_H */
+
+/* End of sah_queue_manager.h */
diff --git a/drivers/mxc/security/sahara2/include/sah_status_manager.h b/drivers/mxc/security/sahara2/include/sah_status_manager.h
new file mode 100644
index 000000000000..63660b53c94f
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/sah_status_manager.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/**
+* @file sah_status_manager.h
+*
+* @brief SAHARA Status Manager Types and Function Prototypes
+*
+* @author Stuart Holloway (SH)
+*
+*/
+
+#ifndef STATUS_MANAGER_H
+#define STATUS_MANAGER_H
+#include "sah_driver_common.h"
+#include "sahara.h"
+
+
+/******************************************************************************
+* User defined data types
+******************************************************************************/
+/**
+******************************************************************************
+* sah_Execute_Status
+* Types read from SAHARA Status Register, with additional state for Op Status
+******************************************************************************/
+typedef enum sah_Execute_Status
+{
+ /** Sahara is Idle. */
+ SAH_EXEC_IDLE = 0,
+ /** SAHARA is busy performing a resest or processing a decriptor chain. */
+ SAH_EXEC_BUSY = 1,
+ /** An error occurred while SAHARA executed the first descriptor. */
+ SAH_EXEC_ERROR1 = 2,
+ /** SAHARA has failed internally. */
+ SAH_EXEC_FAULT = 3,
+ /** SAHARA has finished processing a descriptor chain and is idle. */
+ SAH_EXEC_DONE1 = 4,
+ /** SAHARA has finished processing a descriptor chain, and is processing a
+ * second chain. */
+ SAH_EXEC_DONE1_BUSY2 = 5,
+ /** SAHARA has finished processing a descriptor chain, but has generated an
+ * error while processing a second descriptor chain. */
+ SAH_EXEC_DONE1_ERROR2 = 6,
+ /** SAHARA has finished two descriptors. */
+ SAH_EXEC_DONE1_DONE2 = 7,
+ /** SAHARA has stopped, and first descriptor has Op Status, not Err */
+ SAH_EXEC_OPSTAT1 = 0x20,
+} sah_Execute_Status;
+
+/**
+ * When this bit is on in a #sah_Execute_Status, it means that DONE1 is true.
+ */
+#define SAH_EXEC_DONE1_BIT 4
+
+/**
+ * Bits which make up the Sahara State
+ */
+#define SAH_EXEC_STATE_MASK 0x00000007
+
+/**
+*******************************************************************************
+* sah_Execute_Error
+* Types read from SAHARA Error Status Register
+******************************************************************************/
+typedef enum sah_Execute_Error
+{
+ /** No Error */
+ SAH_ERR_NONE = 0,
+ /** Header is not valid. */
+ SAH_ERR_HEADER = 1,
+ /** Descriptor length is not correct. */
+ SAH_ERR_DESC_LENGTH = 2,
+ /** Length or pointer field is zero while the other is non-zero. */
+ SAH_ERR_DESC_POINTER = 3,
+ /** Length of the link is not a multiple of 4 and is not the last link */
+ SAH_ERR_LINK_LENGTH = 4,
+ /** The data pointer in a link is zero */
+ SAH_ERR_LINK_POINTER = 5,
+ /** Input Buffer reported an overflow */
+ SAH_ERR_INPUT_BUFFER = 6,
+ /** Output Buffer reported an underflow */
+ SAH_ERR_OUTPUT_BUFFER = 7,
+ /** Incorrect data in output buffer after CHA's has signalled 'done'. */
+ SAH_ERR_OUTPUT_BUFFER_STARVATION = 8,
+ /** Internal Hardware Failure. */
+ SAH_ERR_INTERNAL_STATE = 9,
+ /** Current Descriptor was not legal, but cause is unknown. */
+ SAH_ERR_GENERAL_DESCRIPTOR = 10,
+ /** Reserved pointer fields have been set to 1. */
+ SAH_ERR_RESERVED_FIELDS = 11,
+ /** Descriptor address error */
+ SAH_ERR_DESCRIPTOR_ADDRESS = 12,
+ /** Link address error */
+ SAH_ERR_LINK_ADDRESS = 13,
+ /** Processing error in CHA module */
+ SAH_ERR_CHA = 14,
+ /** Processing error during DMA */
+ SAH_ERR_DMA = 15
+} sah_Execute_Error;
+
+
+/**
+*******************************************************************************
+* sah_CHA_Error_Source
+* Types read from SAHARA Error Status Register for CHA Error Source
+*
+******************************************************************************/
+typedef enum sah_CHA_Error_Source
+{
+ /** No Error indicated in Source CHA Error. */
+ SAH_CHA_NO_ERROR = 0,
+ /** Error in SKHA module. */
+ SAH_CHA_SKHA_ERROR = 1,
+ /** Error in MDHA module. */
+ SAH_CHA_MDHA_ERROR = 2,
+ /** Error in RNG module. */
+ SAH_CHA_RNG_ERROR = 3,
+ /** Error in PKHA module. */
+ SAH_CHA_PKHA_ERROR = 4,
+} sah_CHA_Error_Source;
+
+/**
+******************************************************************************
+* sah_CHA_Error_Status
+* Types read from SAHARA Error Status Register for CHA Error Status
+*
+******************************************************************************/
+typedef enum sah_CHA_Error_Status
+{
+ /** No CHA error detected */
+ SAH_CHA_NO_ERR = 0x000,
+ /** Non-empty input buffer when complete. */
+ SAH_CHA_IP_BUF = 0x001,
+ /** Illegal Address Error. */
+ SAH_CHA_ADD_ERR = 0x002,
+ /** Illegal Mode Error. */
+ SAH_CHA_MODE_ERR = 0x004,
+ /** Illegal Data Size Error. */
+ SAH_CHA_DATA_SIZE_ERR = 0x008,
+ /** Illegal Key Size Error. */
+ SAH_CHA_KEY_SIZE_ERR = 0x010,
+ /** Mode/Context/Key written during processing. */
+ SAH_CHA_PROC_ERR = 0x020,
+ /** Context Read During Processing. */
+ SAH_CHA_CTX_READ_ERR = 0x040,
+ /** Internal Hardware Error. */
+ SAH_CHA_INTERNAL_HW_ERR = 0x080,
+ /** Input Buffer not enabled or underflow. */
+ SAH_CHA_IP_BUFF_ERR = 0x100,
+ /** Output Buffer not enabled or overflow. */
+ SAH_CHA_OP_BUFF_ERR = 0x200,
+ /** DES key parity error (SKHA) */
+ SAH_CHA_DES_KEY_ERR = 0x400,
+ /** Reserved error code. */
+ SAH_CHA_RES = 0x800
+} sah_CHA_Error_Status;
+
+/**
+*****************************************************************************
+* sah_DMA_Error_Status
+* Types read from SAHARA Error Status Register for DMA Error Status
+******************************************************************************/
+typedef enum sah_DMA_Error_Status
+{
+ /** No DMA Error Code. */
+ SAH_DMA_NO_ERR = 0,
+ /** AHB terminated a bus cycle with an error. */
+ SAH_DMA_AHB_ERR = 2,
+ /** Internal IP bus cycle was terminated with an error termination. */
+ SAH_DMA_IP_ERR = 4,
+ /** Parity error detected on DMA command. */
+ SAH_DMA_PARITY_ERR = 6,
+ /** DMA was requested to cross a 256 byte internal address boundary. */
+ SAH_DMA_BOUNDRY_ERR = 8,
+ /** DMA controller is busy */
+ SAH_DMA_BUSY_ERR = 10,
+ /** Memory Bounds Error */
+ SAH_DMA_RESERVED_ERR = 12,
+ /** Internal DMA hardware error detected */
+ SAH_DMA_INT_ERR = 14
+} sah_DMA_Error_Status;
+
+/**
+*****************************************************************************
+* sah_DMA_Error_Size
+* Types read from SAHARA Error Status Register for DMA Error Size
+*
+******************************************************************************/
+typedef enum sah_DMA_Error_Size
+{
+ /** Error during Byte transfer. */
+ SAH_DMA_SIZE_BYTE = 0,
+ /** Error during Half-word transfer. */
+ SAH_DMA_SIZE_HALF_WORD = 1,
+ /** Error during Word transfer. */
+ SAH_DMA_SIZE_WORD = 2,
+ /** Reserved DMA word size. */
+ SAH_DMA_SIZE_RES = 3
+} sah_DMA_Error_Size;
+
+
+
+
+extern bool sah_dpm_flag;
+
+/*************************
+* Status Manager Functions
+*************************/
+
+unsigned long sah_Handle_Interrupt(sah_Execute_Status hw_status);
+sah_Head_Desc *sah_Find_With_State (sah_Queue_Status status);
+int sah_dpm_init(void);
+void sah_dpm_close(void);
+void sah_Queue_Manager_Prime (sah_Head_Desc *entry);
+
+
+#endif /* STATUS_MANAGER_H */
diff --git a/drivers/mxc/security/sahara2/include/sahara.h b/drivers/mxc/security/sahara2/include/sahara.h
new file mode 100644
index 000000000000..c66c125bc129
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/sahara.h
@@ -0,0 +1,2265 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file sahara.h
+ *
+ * File which implements the FSL_SHW API when used on Sahara
+ */
+/*!
+ * @if USE_MAINPAGE
+ * @mainpage Sahara2 implemtation of FSL Security Hardware API
+ * @endif
+ *
+ */
+
+#define _DIAG_DRV_IF
+#define _DIAG_SECURITY_FUNC
+#define _DIAG_ADAPTOR
+
+#ifndef SAHARA2_API_H
+#define SAHARA2_API_H
+
+#ifdef DIAG_SECURITY_FUNC
+#include <diagnostic.h>
+#endif /* DIAG_SECURITY_FUNC */
+
+/* This is a Linux flag... ? */
+#ifndef __KERNEL__
+#include <inttypes.h>
+#include <stdlib.h>
+#include <memory.h>
+#else
+#include "portable_os.h"
+#endif
+
+/* This definition may need a new name, and needs to go somewhere which
+ * can determine platform, kernel vs. user, os, etc.
+ */
+#define copy_bytes(out, in, len) memcpy(out, in, len)
+
+/* Does this belong here? */
+#ifndef SAHARA_DEVICE
+#define SAHARA_DEVICE "/dev/sahara"
+#endif
+
+/*!
+*******************************************************************************
+* @defgroup lnkflags Link Flags
+*
+* @brief Flags to show information about link data and link segments
+*
+******************************************************************************/
+/*! @addtogroup lnkflags
+ * @{
+ */
+
+/*!
+*******************************************************************************
+* This flag indicates that the data in a link is owned by the security
+* function component and this memory will be freed by the security function
+* component. To be used as part of the flag field of the sah_Link structure.
+******************************************************************************/
+#define SAH_OWNS_LINK_DATA 0x01
+
+/*!
+*******************************************************************************
+* The data in a link is not owned by the security function component and
+* therefore it will not attempt to free this memory. To be used as part of the
+* flag field of the sah_Link structure.
+******************************************************************************/
+#define SAH_USES_LINK_DATA 0x02
+
+/*!
+*******************************************************************************
+* The data in this link will change when the descriptor gets executed.
+******************************************************************************/
+#define SAH_OUTPUT_LINK 0x04
+
+/*!
+*******************************************************************************
+* The ptr and length in this link are really 'established key' info. They
+* are to be converted to ptr/length before putting on request queue.
+******************************************************************************/
+#define SAH_KEY_IS_HIDDEN 0x08
+
+/*!
+*******************************************************************************
+* The link structure has been appended to the previous one by the driver. It
+* needs to be removed before leaving the driver (and returning to API).
+******************************************************************************/
+#define SAH_REWORKED_LINK 0x10
+
+/*!
+*******************************************************************************
+* The length and data fields of this link contain the slot and user id
+* used to access the SCC stored key
+******************************************************************************/
+#define SAH_STORED_KEY_INFO 0x20
+
+/*!
+*******************************************************************************
+* The Data field points to a physical address, and does not need to be
+* processed by the driver. Honored only in Kernel API.
+******************************************************************************/
+#define SAH_PREPHYS_DATA 0x40
+
+/*!
+*******************************************************************************
+* The link was inserted during the Physicalise procedure. It is tagged so
+* it can be removed during DePhysicalise, thereby returning to the caller an
+* intact chain.
+******************************************************************************/
+#define SAH_LINK_INSERTED_LINK 0x80
+
+/*!
+*******************************************************************************
+* The Data field points to the location of the key, which is in a secure
+* partition held by the user. The memory address needs to be converted to
+* kernel space manually, by looking through the partitions that the user holds.
+******************************************************************************/
+#define SAH_IN_USER_KEYSTORE 0x100
+
+/*!
+*******************************************************************************
+* sah_Link_Flags
+*
+* Type to be used for flags associated with a Link in security function.
+* These flags are used internally by the security function component only.
+*
+* Values defined at @ref lnkflags
+*
+* @brief typedef for flags field of sah_Link
+******************************************************************************/
+typedef uint32_t sah_Link_Flags;
+
+/*
+*******************************************************************************
+* Security Parameters Related Structures
+*
+* All of structures associated with API parameters
+*
+******************************************************************************/
+
+/*
+*******************************************************************************
+* Common Types
+*
+* All of structures used across several classes of crytography
+******************************************************************************/
+
+/*!
+*******************************************************************************
+* @brief Indefinite precision integer used for security operations on SAHARA
+* accelerator. The data will always be in little Endian format.
+******************************************************************************/
+typedef uint8_t *sah_Int;
+
+/*!
+*******************************************************************************
+* @brief Byte array used for block cipher and hash digest/MAC operations on
+* SAHARA accelerator. The Endian format will be as specified by the function
+* using the sah_Oct_Str.
+******************************************************************************/
+typedef uint8_t *sah_Oct_Str;
+
+/*!
+ * A queue of descriptor heads -- used to hold requests waiting for user to
+ * pick up the results. */
+typedef struct sah_Queue {
+ int count; /*!< # entries in queue */
+ struct sah_Head_Desc *head; /*!< first entry in queue */
+ struct sah_Head_Desc *tail; /*!< last entry in queue */
+} sah_Queue;
+
+/******************************************************************************
+ * Enumerations
+ *****************************************************************************/
+/*!
+ * Flags for the state of the User Context Object (#fsl_shw_uco_t).
+ */
+typedef enum fsl_shw_user_ctx_flags_t {
+ /*!
+ * API will block the caller until operation completes. The result will be
+ * available in the return code. If this is not set, user will have to get
+ * results using #fsl_shw_get_results().
+ */
+ FSL_UCO_BLOCKING_MODE = 0x01,
+ /*!
+ * User wants callback (at the function specified with
+ * #fsl_shw_uco_set_callback()) when the operation completes. This flag is
+ * valid only if #FSL_UCO_BLOCKING_MODE is not set.
+ */
+ FSL_UCO_CALLBACK_MODE = 0x02,
+ /*! Do not free descriptor chain after driver (adaptor) finishes */
+ FSL_UCO_SAVE_DESC_CHAIN = 0x04,
+ /*!
+ * User has made at least one request with callbacks requested, so API is
+ * ready to handle others.
+ */
+ FSL_UCO_CALLBACK_SETUP_COMPLETE = 0x08,
+ /*!
+ * (virtual) pointer to descriptor chain is completely linked with physical
+ * (DMA) addresses, ready for the hardware. This flag should not be used
+ * by FSL SHW API programs.
+ */
+ FSL_UCO_CHAIN_PREPHYSICALIZED = 0x10,
+ /*!
+ * The user has changed the context but the changes have not been copied to
+ * the kernel driver.
+ */
+ FSL_UCO_CONTEXT_CHANGED = 0x20,
+ /*! Internal Use. This context belongs to a user-mode API user. */
+ FSL_UCO_USERMODE_USER = 0x40,
+} fsl_shw_user_ctx_flags_t;
+
+/*!
+ * Return code for FSL_SHW library.
+ *
+ * These codes may be returned from a function call. In non-blocking mode,
+ * they will appear as the status in a Result Object.
+ */
+typedef enum fsl_shw_return_t {
+ /*!
+ * No error. As a function return code in Non-blocking mode, this may
+ * simply mean that the operation was accepted for eventual execution.
+ */
+ FSL_RETURN_OK_S = 0,
+ /*! Failure for non-specific reason. */
+ FSL_RETURN_ERROR_S,
+ /*!
+ * Operation failed because some resource was not able to be allocated.
+ */
+ FSL_RETURN_NO_RESOURCE_S,
+ /*! Crypto algorithm unrecognized or improper. */
+ FSL_RETURN_BAD_ALGORITHM_S,
+ /*! Crypto mode unrecognized or improper. */
+ FSL_RETURN_BAD_MODE_S,
+ /*! Flag setting unrecognized or inconsistent. */
+ FSL_RETURN_BAD_FLAG_S,
+ /*! Improper or unsupported key length for algorithm. */
+ FSL_RETURN_BAD_KEY_LENGTH_S,
+ /*! Improper parity in a (DES, TDES) key. */
+ FSL_RETURN_BAD_KEY_PARITY_S,
+ /*!
+ * Improper or unsupported data length for algorithm or internal buffer.
+ */
+ FSL_RETURN_BAD_DATA_LENGTH_S,
+ /*! Authentication / Integrity Check code check failed. */
+ FSL_RETURN_AUTH_FAILED_S,
+ /*! A memory error occurred. */
+ FSL_RETURN_MEMORY_ERROR_S,
+ /*! An error internal to the hardware occurred. */
+ FSL_RETURN_INTERNAL_ERROR_S,
+ /*! ECC detected Point at Infinity */
+ FSL_RETURN_POINT_AT_INFINITY_S,
+ /*! ECC detected No Point at Infinity */
+ FSL_RETURN_POINT_NOT_AT_INFINITY_S,
+ /*! GCD is One */
+ FSL_RETURN_GCD_IS_ONE_S,
+ /*! GCD is not One */
+ FSL_RETURN_GCD_IS_NOT_ONE_S,
+ /*! Candidate is Prime */
+ FSL_RETURN_PRIME_S,
+ /*! Candidate is not Prime */
+ FSL_RETURN_NOT_PRIME_S,
+ /*! N register loaded improperly with even value */
+ FSL_RETURN_EVEN_MODULUS_ERROR_S,
+ /*! Divisor is zero. */
+ FSL_RETURN_DIVIDE_BY_ZERO_ERROR_S,
+ /*! Bad Exponent or Scalar value for Point Multiply */
+ FSL_RETURN_BAD_EXPONENT_ERROR_S,
+ /*! RNG hardware problem. */
+ FSL_RETURN_OSCILLATOR_ERROR_S,
+ /*! RNG hardware problem. */
+ FSL_RETURN_STATISTICS_ERROR_S,
+} fsl_shw_return_t;
+
+/*!
+ * Algorithm Identifier.
+ *
+ * Selection of algorithm will determine how large the block size of the
+ * algorithm is. Context size is the same length unless otherwise specified.
+ * Selection of algorithm also affects the allowable key length.
+ */
+typedef enum fsl_shw_key_alg_t {
+ /*!
+ * Key will be used to perform an HMAC. Key size is 1 to 64 octets. Block
+ * size is 64 octets.
+ */
+ FSL_KEY_ALG_HMAC,
+ /*!
+ * Advanced Encryption Standard (Rijndael). Block size is 16 octets. Key
+ * size is 16 octets. (The single choice of key size is a Sahara platform
+ * limitation.)
+ */
+ FSL_KEY_ALG_AES,
+ /*!
+ * Data Encryption Standard. Block size is 8 octets. Key size is 8
+ * octets.
+ */
+ FSL_KEY_ALG_DES,
+ /*!
+ * 2- or 3-key Triple DES. Block size is 8 octets. Key size is 16 octets
+ * for 2-key Triple DES, and 24 octets for 3-key.
+ */
+ FSL_KEY_ALG_TDES,
+ /*!
+ * ARC4. No block size. Context size is 259 octets. Allowed key size is
+ * 1-16 octets. (The choices for key size are a Sahara platform
+ * limitation.)
+ */
+ FSL_KEY_ALG_ARC4,
+ /*!
+ * Private key of a public-private key-pair. Max is 512 bits...
+ */
+ FSL_KEY_PK_PRIVATE,
+} fsl_shw_key_alg_t;
+
+/*!
+ * Mode selector for Symmetric Ciphers.
+ *
+ * The selection of mode determines how a cryptographic algorithm will be
+ * used to process the plaintext or ciphertext.
+ *
+ * For all modes which are run block-by-block (that is, all but
+ * #FSL_SYM_MODE_STREAM), any partial operations must be performed on a text
+ * length which is multiple of the block size. Except for #FSL_SYM_MODE_CTR,
+ * these block-by-block algorithms must also be passed a total number of octets
+ * which is a multiple of the block size.
+ *
+ * In modes which require that the total number of octets of data be a multiple
+ * of the block size (#FSL_SYM_MODE_ECB and #FSL_SYM_MODE_CBC), and the user
+ * has a total number of octets which are not a multiple of the block size, the
+ * user must perform any necessary padding to get to the correct data length.
+ */
+typedef enum fsl_shw_sym_mode_t {
+ /*!
+ * Stream. There is no associated block size. Any request to process data
+ * may be of any length. This mode is only for ARC4 operations, and is
+ * also the only mode used for ARC4.
+ */
+ FSL_SYM_MODE_STREAM,
+
+ /*!
+ * Electronic Codebook. Each block of data is encrypted/decrypted. The
+ * length of the data stream must be a multiple of the block size. This
+ * mode may be used for DES, 3DES, and AES. The block size is determined
+ * by the algorithm.
+ */
+ FSL_SYM_MODE_ECB,
+ /*!
+ * Cipher-Block Chaining. Each block of data is encrypted/decrypted and
+ * then "chained" with the previous block by an XOR function. Requires
+ * context to start the XOR (previous block). This mode may be used for
+ * DES, 3DES, and AES. The block size is determined by the algorithm.
+ */
+ FSL_SYM_MODE_CBC,
+ /*!
+ * Counter. The counter is encrypted, then XORed with a block of data.
+ * The counter is then incremented (using modulus arithmetic) for the next
+ * block. The final operation may be non-multiple of block size. This mode
+ * may be used for AES. The block size is determined by the algorithm.
+ */
+ FSL_SYM_MODE_CTR,
+} fsl_shw_sym_mode_t;
+
+/*!
+ * Algorithm selector for Cryptographic Hash functions.
+ *
+ * Selection of algorithm determines how large the context and digest will be.
+ * Context is the same size as the digest (resulting hash), unless otherwise
+ * specified.
+ */
+typedef enum fsl_shw_hash_alg_t {
+ /*! MD5 algorithm. Digest is 16 octets. */
+ FSL_HASH_ALG_MD5,
+ /*! SHA-1 (aka SHA or SHA-160) algorithm. Digest is 20 octets. */
+ FSL_HASH_ALG_SHA1,
+ /*!
+ * SHA-224 algorithm. Digest is 28 octets, though context is 32 octets.
+ */
+ FSL_HASH_ALG_SHA224,
+ /*! SHA-256 algorithm. Digest is 32 octets. */
+ FSL_HASH_ALG_SHA256
+} fsl_shw_hash_alg_t;
+
+/*!
+ * The type of Authentication-Cipher function which will be performed.
+ */
+typedef enum fsl_shw_acc_mode_t {
+ /*!
+ * CBC-MAC for Counter. Requires context and modulus. Final operation may
+ * be non-multiple of block size. This mode may be used for AES.
+ */
+ FSL_ACC_MODE_CCM,
+ /*!
+ * SSL mode. Not supported. Combines HMAC and encrypt (or decrypt).
+ * Needs one key object for encryption, another for the HMAC. The usual
+ * hashing and symmetric encryption algorithms are supported.
+ */
+ FSL_ACC_MODE_SSL,
+} fsl_shw_acc_mode_t;
+
+/* REQ-S2LRD-PINTFC-COA-HCO-001 */
+/*!
+ * Flags which control a Hash operation.
+ */
+typedef enum fsl_shw_hash_ctx_flags_t {
+ /*!
+ * Context is empty. Hash is started from scratch, with a
+ * message-processed count of zero.
+ */
+ FSL_HASH_FLAGS_INIT = 0x01,
+ /*!
+ * Retrieve context from hardware after hashing. If used with the
+ * #FSL_HASH_FLAGS_FINALIZE flag, the final digest value will be saved in
+ * the object.
+ */
+ FSL_HASH_FLAGS_SAVE = 0x02,
+ /*! Place context into hardware before hashing. */
+ FSL_HASH_FLAGS_LOAD = 0x04,
+ /*!
+ * PAD message and perform final digest operation. If user message is
+ * pre-padded, this flag should not be used.
+ */
+ FSL_HASH_FLAGS_FINALIZE = 0x08,
+} fsl_shw_hash_ctx_flags_t;
+
+/*!
+ * Flags which control an HMAC operation.
+ *
+ * These may be combined by ORing them together. See #fsl_shw_hmco_set_flags()
+ * and #fsl_shw_hmco_clear_flags().
+ */
+typedef enum fsl_shw_hmac_ctx_flags_t {
+ /*!
+ * Message context is empty. HMAC is started from scratch (with key) or
+ * from precompute of inner hash, depending on whether
+ * #FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT is set.
+ */
+ FSL_HMAC_FLAGS_INIT = 1,
+ /*!
+ * Retrieve ongoing context from hardware after hashing. If used with the
+ * #FSL_HMAC_FLAGS_FINALIZE flag, the final digest value (HMAC) will be
+ * saved in the object.
+ */
+ FSL_HMAC_FLAGS_SAVE = 2,
+ /*! Place ongoing context into hardware before hashing. */
+ FSL_HMAC_FLAGS_LOAD = 4,
+ /*!
+ * PAD message and perform final HMAC operations of inner and outer
+ * hashes.
+ */
+ FSL_HMAC_FLAGS_FINALIZE = 8,
+ /*!
+ * This means that the context contains precomputed inner and outer hash
+ * values.
+ */
+ FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT = 16,
+} fsl_shw_hmac_ctx_flags_t;
+
+/*!
+ * Flags to control use of the #fsl_shw_scco_t.
+ *
+ * These may be ORed together to get the desired effect.
+ * See #fsl_shw_scco_set_flags() and #fsl_shw_scco_clear_flags()
+ */
+typedef enum fsl_shw_sym_ctx_flags_t {
+ /*!
+ * Context is empty. In ARC4, this means that the S-Box needs to be
+ * generated from the key. In #FSL_SYM_MODE_CBC mode, this allows an IV of
+ * zero to be specified. In #FSL_SYM_MODE_CTR mode, it means that an
+ * initial CTR value of zero is desired.
+ */
+ FSL_SYM_CTX_INIT = 1,
+ /*!
+ * Load context from object into hardware before running cipher. In
+ * #FSL_SYM_MODE_CTR mode, this would refer to the Counter Value.
+ */
+ FSL_SYM_CTX_LOAD = 2,
+ /*!
+ * Save context from hardware into object after running cipher. In
+ * #FSL_SYM_MODE_CTR mode, this would refer to the Counter Value.
+ */
+ FSL_SYM_CTX_SAVE = 4,
+ /*!
+ * Context (SBox) is to be unwrapped and wrapped on each use.
+ * This flag is unsupported.
+ * */
+ FSL_SYM_CTX_PROTECT = 8,
+} fsl_shw_sym_ctx_flags_t;
+
+/*!
+ * Flags which describe the state of the #fsl_shw_sko_t.
+ *
+ * These may be ORed together to get the desired effect.
+ * See #fsl_shw_sko_set_flags() and #fsl_shw_sko_clear_flags()
+ */
+typedef enum fsl_shw_key_flags_t {
+ /*! If algorithm is DES or 3DES, do not validate the key parity bits. */
+ FSL_SKO_KEY_IGNORE_PARITY = 1,
+ /*! Clear key is present in the object. */
+ FSL_SKO_KEY_PRESENT = 2,
+ /*!
+ * Key has been established for use. This feature is not available for all
+ * platforms, nor for all algorithms and modes.
+ */
+ FSL_SKO_KEY_ESTABLISHED = 4,
+ /*!
+ * Key intended for user (software) use; can be read cleartext from the
+ * keystore.
+ */
+ FSL_SKO_KEY_SW_KEY = 8,
+} fsl_shw_key_flags_t;
+
+/*!
+ * Type of value which is associated with an established key.
+ */
+typedef uint64_t key_userid_t;
+
+/*!
+ * Flags which describe the state of the #fsl_shw_acco_t.
+ *
+ * The @a FSL_ACCO_CTX_INIT and @a FSL_ACCO_CTX_FINALIZE flags, when used
+ * together, provide for a one-shot operation.
+ */
+typedef enum fsl_shw_auth_ctx_flags_t {
+ /*! Initialize Context(s) */
+ FSL_ACCO_CTX_INIT = 1,
+ /*! Load intermediate context(s). This flag is unsupported. */
+ FSL_ACCO_CTX_LOAD = 2,
+ /*! Save intermediate context(s). This flag is unsupported. */
+ FSL_ACCO_CTX_SAVE = 4,
+ /*! Create MAC during this operation. */
+ FSL_ACCO_CTX_FINALIZE = 8,
+ /*!
+ * Formatting of CCM input data is performed by calls to
+ * #fsl_shw_ccm_nist_format_ctr_and_iv() and
+ * #fsl_shw_ccm_nist_update_ctr_and_iv().
+ */
+ FSL_ACCO_NIST_CCM = 0x10,
+} fsl_shw_auth_ctx_flags_t;
+
+/*!
+ * The operation which controls the behavior of #fsl_shw_establish_key().
+ *
+ * These values are passed to #fsl_shw_establish_key().
+ */
+typedef enum fsl_shw_key_wrap_t {
+ /*! Generate a key from random values. */
+ FSL_KEY_WRAP_CREATE,
+ /*! Use the provided clear key. */
+ FSL_KEY_WRAP_ACCEPT,
+ /*! Unwrap a previously wrapped key. */
+ FSL_KEY_WRAP_UNWRAP
+} fsl_shw_key_wrap_t;
+
+/*!
+ * Modulus Selector for CTR modes.
+ *
+ * The incrementing of the Counter value may be modified by a modulus. If no
+ * modulus is needed or desired for AES, use #FSL_CTR_MOD_128.
+ */
+typedef enum fsl_shw_ctr_mod_t {
+ FSL_CTR_MOD_8, /*!< Run counter with modulus of 2^8. */
+ FSL_CTR_MOD_16, /*!< Run counter with modulus of 2^16. */
+ FSL_CTR_MOD_24, /*!< Run counter with modulus of 2^24. */
+ FSL_CTR_MOD_32, /*!< Run counter with modulus of 2^32. */
+ FSL_CTR_MOD_40, /*!< Run counter with modulus of 2^40. */
+ FSL_CTR_MOD_48, /*!< Run counter with modulus of 2^48. */
+ FSL_CTR_MOD_56, /*!< Run counter with modulus of 2^56. */
+ FSL_CTR_MOD_64, /*!< Run counter with modulus of 2^64. */
+ FSL_CTR_MOD_72, /*!< Run counter with modulus of 2^72. */
+ FSL_CTR_MOD_80, /*!< Run counter with modulus of 2^80. */
+ FSL_CTR_MOD_88, /*!< Run counter with modulus of 2^88. */
+ FSL_CTR_MOD_96, /*!< Run counter with modulus of 2^96. */
+ FSL_CTR_MOD_104, /*!< Run counter with modulus of 2^104. */
+ FSL_CTR_MOD_112, /*!< Run counter with modulus of 2^112. */
+ FSL_CTR_MOD_120, /*!< Run counter with modulus of 2^120. */
+ FSL_CTR_MOD_128 /*!< Run counter with modulus of 2^128. */
+} fsl_shw_ctr_mod_t;
+
+/*!
+ * Permissions flags for Secure Partitions
+ */
+typedef enum fsl_shw_permission_t {
+/*! SCM Access Permission: Do not zeroize/deallocate partition on SMN Fail state */
+ FSL_PERM_NO_ZEROIZE = 0x80000000,
+/*! SCM Access Permission: Enforce trusted key read in */
+ FSL_PERM_TRUSTED_KEY_READ = 0x40000000,
+/*! SCM Access Permission: Ignore Supervisor/User mode in permission determination */
+ FSL_PERM_HD_S = 0x00000800,
+/*! SCM Access Permission: Allow Read Access to Host Domain */
+ FSL_PERM_HD_R = 0x00000400,
+/*! SCM Access Permission: Allow Write Access to Host Domain */
+ FSL_PERM_HD_W = 0x00000200,
+/*! SCM Access Permission: Allow Execute Access to Host Domain */
+ FSL_PERM_HD_X = 0x00000100,
+/*! SCM Access Permission: Allow Read Access to Trusted Host Domain */
+ FSL_PERM_TH_R = 0x00000040,
+/*! SCM Access Permission: Allow Write Access to Trusted Host Domain */
+ FSL_PERM_TH_W = 0x00000020,
+/*! SCM Access Permission: Allow Read Access to Other/World Domain */
+ FSL_PERM_OT_R = 0x00000004,
+/*! SCM Access Permission: Allow Write Access to Other/World Domain */
+ FSL_PERM_OT_W = 0x00000002,
+/*! SCM Access Permission: Allow Execute Access to Other/World Domain */
+ FSL_PERM_OT_X = 0x00000001,
+} fsl_shw_permission_t;
+
+typedef enum fsl_shw_cypher_mode_t {
+ FSL_SHW_CYPHER_MODE_ECB = 1, /*!< ECB mode */
+ FSL_SHW_CYPHER_MODE_CBC = 2, /*!< CBC mode */
+} fsl_shw_cypher_mode_t;
+
+typedef enum fsl_shw_pf_key_t {
+ FSL_SHW_PF_KEY_IIM, /*!< Present fused IIM key */
+ FSL_SHW_PF_KEY_PRG, /*!< Present Program key */
+ FSL_SHW_PF_KEY_IIM_PRG, /*!< Present IIM ^ Program key */
+ FSL_SHW_PF_KEY_IIM_RND, /*!< Present Random key */
+ FSL_SHW_PF_KEY_RND, /*!< Present IIM ^ Random key */
+} fsl_shw_pf_key_t;
+
+typedef enum fsl_shw_tamper_t {
+ FSL_SHW_TAMPER_NONE, /*!< No error detected */
+ FSL_SHW_TAMPER_WTD, /*!< wire-mesh tampering det */
+ FSL_SHW_TAMPER_ETBD, /*!< ext tampering det: input B */
+ FSL_SHW_TAMPER_ETAD, /*!< ext tampering det: input A */
+ FSL_SHW_TAMPER_EBD, /*!< external boot detected */
+ FSL_SHW_TAMPER_SAD, /*!< security alarm detected */
+ FSL_SHW_TAMPER_TTD, /*!< temperature tampering det */
+ FSL_SHW_TAMPER_CTD, /*!< clock tampering det */
+ FSL_SHW_TAMPER_VTD, /*!< voltage tampering det */
+ FSL_SHW_TAMPER_MCO, /*!< monotonic counter overflow */
+ FSL_SHW_TAMPER_TCO, /*!< time counter overflow */
+} fsl_shw_tamper_t;
+
+/******************************************************************************
+ * Data Structures
+ *****************************************************************************/
+
+/*!
+ *
+ * @brief Structure type for descriptors
+ *
+ * The first five fields are passed to the hardware.
+ *
+ *****************************************************************************/
+#ifndef USE_NEW_PTRS /* Experimental */
+
+typedef struct sah_Desc {
+ uint32_t header; /*!< descriptor header value */
+ uint32_t len1; /*!< number of data bytes in 'ptr1' buffer */
+ void *ptr1; /*!< pointer to first sah_Link structure */
+ uint32_t len2; /*!< number of data bytes in 'ptr2' buffer */
+ void *ptr2; /*!< pointer to second sah_Link structure */
+ struct sah_Desc *next; /*!< pointer to next descriptor */
+#ifdef __KERNEL__ /* This needs a better test */
+ /* These two must be last. See sah_Copy_Descriptors */
+ struct sah_Desc *virt_addr; /*!< Virtual (kernel) address of this
+ descriptor. */
+ dma_addr_t dma_addr; /*!< Physical (bus) address of this
+ descriptor. */
+ void *original_ptr1; /*!< user's pointer to ptr1 */
+ void *original_ptr2; /*!< user's pointer to ptr2 */
+ struct sah_Desc *original_next; /*!< user's pointer to next */
+#endif
+} sah_Desc;
+
+#else
+
+typedef struct sah_Desc {
+ uint32_t header; /*!< descriptor header value */
+ uint32_t len1; /*!< number of data bytes in 'ptr1' buffer */
+ uint32_t hw_ptr1; /*!< pointer to first sah_Link structure */
+ uint32_t len2; /*!< number of data bytes in 'ptr2' buffer */
+ uint32_t hw_ptr2; /*!< pointer to second sah_Link structure */
+ uint32_t hw_next; /*!< pointer to next descriptor */
+ struct sah_Link *ptr1; /*!< (virtual) pointer to first sah_Link structure */
+ struct sah_Link *ptr2; /*!< (virtual) pointer to first sah_Link structure */
+ struct sah_Desc *next; /*!< (virtual) pointer to next descriptor */
+#ifdef __KERNEL__ /* This needs a better test */
+ /* These two must be last. See sah_Copy_Descriptors */
+ struct sah_Desc *virt_addr; /*!< Virtual (kernel) address of this
+ descriptor. */
+ dma_addr_t dma_addr; /*!< Physical (bus) address of this
+ descriptor. */
+#endif
+} sah_Desc;
+
+#endif
+
+/*!
+*******************************************************************************
+* @brief The first descriptor in a chain
+******************************************************************************/
+typedef struct sah_Head_Desc {
+ sah_Desc desc; /*!< whole struct - must be first */
+ struct fsl_shw_uco_t *user_info; /*!< where result pool lives */
+ uint32_t user_ref; /*!< at time of request */
+ uint32_t uco_flags; /*!< at time of request */
+ uint32_t status; /*!< Status of queue entry */
+ uint32_t error_status; /*!< If error, register from Sahara */
+ uint32_t fault_address; /*!< If error, register from Sahara */
+ uint32_t op_status; /*!< If error, register from Sahara */
+ fsl_shw_return_t result; /*!< Result of running descriptor */
+ struct sah_Head_Desc *next; /*!< Next in queue */
+ struct sah_Head_Desc *prev; /*!< previous in queue */
+ struct sah_Head_Desc *user_desc; /*!< For API async get_results */
+ void *out1_ptr; /*!< For async post-processing */
+ void *out2_ptr; /*!< For async post-processing */
+ uint32_t out_len; /*!< For async post-processing */
+} sah_Head_Desc;
+
+/*!
+ * @brief Structure type for links
+ *
+ * The first three fields are used by hardware.
+ *****************************************************************************/
+#ifndef USE_NEW_PTRS
+
+typedef struct sah_Link {
+ size_t len; /*!< len of 'data' buffer in bytes */
+ uint8_t *data; /*!< buffer to store data */
+ struct sah_Link *next; /*!< pointer to the next sah_Link storing
+ * data */
+ sah_Link_Flags flags; /*!< indicates the component that created the
+ * data buffer. Security Function internal
+ * information */
+ key_userid_t ownerid; /*!< Auth code for established key */
+ uint32_t slot; /*!< Location of the the established key */
+#ifdef __KERNEL__ /* This needs a better test */
+ /* These two elements must be last. See sah_Copy_Links() */
+ struct sah_Link *virt_addr;
+ dma_addr_t dma_addr;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ struct page *vm_info;
+#endif
+ uint8_t *original_data; /*!< user's version of data pointer */
+ struct sah_Link *original_next; /*!< user's version of next pointer */
+#ifdef SAH_COPY_DATA
+ uint8_t *copy_data; /*!< Virtual address of acquired buffer */
+#endif
+#endif /* kernel-only */
+} sah_Link;
+
+#else
+
+typedef struct sah_Link {
+ /*! len of 'data' buffer in bytes */
+ size_t len;
+ /*! buffer to store data */
+ uint32_t hw_data;
+ /*! Physical address */
+ uint32_t hw_next;
+ /*!
+ * indicates the component that created the data buffer. Security Function
+ * internal information
+ */
+ sah_Link_Flags flags;
+ /*! (virtual) pointer to data */
+ uint8_t *data;
+ /*! (virtual) pointer to the next sah_Link storing data */
+ struct sah_Link *next;
+ /*! Auth code for established key */
+ key_userid_t ownerid;
+ /*! Location of the the established key */
+ uint32_t slot;
+#ifdef __KERNEL__ /* This needs a better test */
+ /* These two elements must be last. See sah_Copy_Links() */
+ struct sah_Link *virt_addr;
+ dma_addr_t dma_addr;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ struct page *vm_info;
+#endif
+#endif /* kernel-only */
+} sah_Link;
+
+#endif
+
+/*!
+ * Initialization Object
+ */
+typedef struct fsl_sho_ibo_t {
+} fsl_sho_ibo_t;
+
+/* Imported from Sahara1 driver -- is it needed forever? */
+/*!
+*******************************************************************************
+* FIELDS
+*
+* void * ref - parameter to be passed into the memory function calls
+*
+* void * (*malloc)(void *ref, size_t n) - pointer to user's malloc function
+*
+* void (*free)(void *ref, void *ptr) - pointer to user's free function
+*
+* void * (*memcpy)(void *ref, void *dest, const void *src, size_t n) -
+* pointer to user's memcpy function
+*
+* void * (*memset)(void *ref, void *ptr, int ch, size_t n) - pointer to
+* user's memset function
+*
+* @brief Structure for API memory utilities
+******************************************************************************/
+typedef struct sah_Mem_Util {
+ /*! Who knows. Vestigial. */
+ void *mu_ref;
+ /*! Acquire buffer of size n bytes */
+ void *(*mu_malloc) (void *ref, size_t n);
+ /*! Acquire a sah_Head_Desc */
+ sah_Head_Desc *(*mu_alloc_head_desc) (void *ref);
+ /* Acquire a sah_Desc */
+ sah_Desc *(*mu_alloc_desc) (void *ref);
+ /* Acquire a sah_Link */
+ sah_Link *(*mu_alloc_link) (void *ref);
+ /*! Free buffer at ptr */
+ void (*mu_free) (void *ref, void *ptr);
+ /*! Free sah_Head_Desc at ptr */
+ void (*mu_free_head_desc) (void *ref, sah_Head_Desc * ptr);
+ /*! Free sah_Desc at ptr */
+ void (*mu_free_desc) (void *ref, sah_Desc * ptr);
+ /*! Free sah_Link at ptr */
+ void (*mu_free_link) (void *ref, sah_Link * ptr);
+ /*! Funciton which will copy n bytes from src to dest */
+ void *(*mu_memcpy) (void *ref, void *dest, const void *src, size_t n);
+ /*! Set all n bytes of ptr to ch */
+ void *(*mu_memset) (void *ref, void *ptr, int ch, size_t n);
+} sah_Mem_Util;
+
+/*!
+ * Secure Partition information
+ *
+ * This holds the context to a single secure partition owned by the user. It
+ * is only available in the kernel version of the User Context Object.
+ */
+typedef struct fsl_shw_spo_t {
+ uint32_t user_base; /*!< Base address (user virtual) */
+ void *kernel_base; /*!< Base address (kernel virtual) */
+ struct fsl_shw_spo_t *next; /*!< Pointer to the next partition
+ owned by the user. NULL if this
+ is the last partition. */
+} fsl_shw_spo_t;
+
+/* REQ-S2LRD-PINTFC-COA-UCO-001 */
+/*!
+ * User Context Object
+ */
+typedef struct fsl_shw_uco_t {
+ int sahara_openfd; /*!< this should be kernel-only?? */
+ sah_Mem_Util *mem_util; /*!< Memory utility fns */
+ uint32_t user_ref; /*!< User's reference */
+ void (*callback) (struct fsl_shw_uco_t * uco); /*!< User's callback fn */
+ uint32_t flags; /*!< from fsl_shw_user_ctx_flags_t */
+ unsigned pool_size; /*!< maximum size of user pool */
+#ifdef __KERNEL__
+ sah_Queue result_pool; /*!< where non-blocking results go */
+ os_process_handle_t process; /*!< remember for signalling User mode */
+ fsl_shw_spo_t *partition; /*!< chain of secure partitions owned by
+ the user */
+#else
+ struct fsl_shw_uco_t *next; /*!< To allow user-mode chaining of contexts,
+ for signalling. */
+#endif
+} fsl_shw_uco_t;
+
+/* REQ-S2LRD-PINTFC-API-GEN-006 ?? */
+/*!
+ * Result object
+ */
+typedef struct fsl_shw_result_t {
+ uint32_t user_ref;
+ fsl_shw_return_t code;
+ uint32_t detail1;
+ uint32_t detail2;
+ sah_Head_Desc *user_desc;
+} fsl_shw_result_t;
+
+/*!
+ * Keystore Object
+ */
+typedef struct fsl_shw_kso_t {
+#ifdef __KERNEL__
+ os_lock_t lock; /*!< Pointer to lock that controls access to
+ the keystore. */
+#endif
+ void *user_data; /*!< Pointer to user structure that handles
+ the internals of the keystore. */
+ fsl_shw_return_t(*data_init) (fsl_shw_uco_t * user_ctx,
+ void **user_data);
+ void (*data_cleanup) (fsl_shw_uco_t * user_ctx, void **user_data);
+ fsl_shw_return_t(*slot_verify_access) (void *user_data,
+ uint64_t owner_id,
+ uint32_t slot);
+ fsl_shw_return_t(*slot_alloc) (void *user_data, uint32_t size_bytes,
+ uint64_t owner_id, uint32_t * slot);
+ fsl_shw_return_t(*slot_dealloc) (void *user_data, uint64_t owner_id,
+ uint32_t slot);
+ void *(*slot_get_address) (void *user_data, uint32_t slot);
+ uint32_t(*slot_get_base) (void *user_data, uint32_t slot);
+ uint32_t(*slot_get_offset) (void *user_data, uint32_t slot);
+ uint32_t(*slot_get_slot_size) (void *user_data, uint32_t slot);
+} fsl_shw_kso_t;
+
+/* REQ-S2LRD-PINTFC-COA-SKO-001 */
+/*!
+ * Secret Key Context Object
+ */
+typedef struct fsl_shw_sko_t {
+ uint32_t flags;
+ fsl_shw_key_alg_t algorithm;
+ key_userid_t userid;
+ uint32_t handle;
+ uint16_t key_length;
+ uint8_t key[64];
+ struct fsl_shw_kso_t *keystore; /*!< If present, key is in keystore */
+} fsl_shw_sko_t;
+
+/* REQ-S2LRD-PINTFC-COA-CO-001 */
+/*!
+ * @brief Platform Capability Object
+ */
+typedef struct fsl_shw_pco_t { /* Consider turning these constants into symbols */
+ int api_major;
+ int api_minor;
+ int driver_major;
+ int driver_minor;
+ fsl_shw_key_alg_t sym_algorithms[4];
+ fsl_shw_sym_mode_t sym_modes[4];
+ fsl_shw_hash_alg_t hash_algorithms[4];
+ uint8_t sym_support[5][4]; /* indexed by key alg then mode */
+
+ int scc_driver_major;
+ int scc_driver_minor;
+ int scm_version; /*!< Version from SCM Configuration register */
+ int smn_version; /*!< Version from SMN Status register */
+ int block_size_bytes; /*!< Number of bytes per block of RAM; also
+ block size of the crypto algorithm. */
+ union {
+ struct {
+ int black_ram_size_blocks; /*!< Number of blocks of Black RAM */
+ int red_ram_size_blocks; /*!< Number of blocks of Red RAM */
+ } scc_info;
+ struct {
+ int partition_size_bytes; /*!< Number of bytes in each partition */
+ int partition_count; /*!< Number of partitions on this platform */
+ } scc2_info;
+ };
+} fsl_shw_pco_t;
+
+/* REQ-S2LRD-PINTFC-COA-HCO-001 */
+/*!
+ * Hash Context Object
+ */
+typedef struct fsl_shw_hco_t { /* fsl_shw_hash_context_object */
+ fsl_shw_hash_alg_t algorithm;
+ uint32_t flags;
+ uint8_t digest_length; /* in bytes */
+ uint8_t context_length; /* in bytes */
+ uint8_t context_register_length; /* in bytes */
+ uint32_t context[9]; /* largest digest + msg size */
+} fsl_shw_hco_t;
+
+/*!
+ * HMAC Context Object
+ */
+typedef struct fsl_shw_hmco_t { /* fsl_shw_hmac_context_object */
+ fsl_shw_hash_alg_t algorithm;
+ uint32_t flags;
+ uint8_t digest_length; /*!< in bytes */
+ uint8_t context_length; /*!< in bytes */
+ uint8_t context_register_length; /*!< in bytes */
+ uint32_t ongoing_context[9]; /*!< largest digest + msg
+ size */
+ uint32_t inner_precompute[9]; /*!< largest digest + msg
+ size */
+ uint32_t outer_precompute[9]; /*!< largest digest + msg
+ size */
+} fsl_shw_hmco_t;
+
+/* REQ-S2LRD-PINTFC-COA-SCCO-001 */
+/*!
+ * Symmetric Crypto Context Object Context Object
+ */
+typedef struct fsl_shw_scco_t {
+ uint32_t flags;
+ unsigned block_size_bytes; /* double duty block&ctx size */
+ fsl_shw_sym_mode_t mode;
+ /* Could put modulus plus 16-octet context in union with arc4
+ sbox+ptrs... */
+ fsl_shw_ctr_mod_t modulus_exp;
+ uint8_t context[259];
+} fsl_shw_scco_t;
+
+/*!
+ * Authenticate-Cipher Context Object
+
+ * An object for controlling the function of, and holding information about,
+ * data for the authenticate-cipher functions, #fsl_shw_gen_encrypt() and
+ * #fsl_shw_auth_decrypt().
+ */
+typedef struct fsl_shw_acco_t {
+ uint32_t flags; /*!< See #fsl_shw_auth_ctx_flags_t for
+ meanings */
+ fsl_shw_acc_mode_t mode; /*!< CCM only */
+ uint8_t mac_length; /*!< User's value for length */
+ unsigned q_length; /*!< NIST parameter - */
+ fsl_shw_scco_t cipher_ctx_info; /*!< For running
+ encrypt/decrypt. */
+ union {
+ fsl_shw_scco_t CCM_ctx_info; /*!< For running the CBC in
+ AES-CCM. */
+ fsl_shw_hco_t hash_ctx_info; /*!< For running the hash */
+ } auth_info; /*!< "auth" info struct */
+ uint8_t unencrypted_mac[16]; /*!< max block size... */
+} fsl_shw_acco_t;
+
+/*!
+ * Used by Sahara API to retrieve completed non-blocking results.
+ */
+typedef struct sah_results {
+ unsigned requested; /*!< number of results requested */
+ unsigned *actual; /*!< number of results obtained */
+ fsl_shw_result_t *results; /*!< pointer to memory to hold results */
+} sah_results;
+
+/*!
+ * @typedef scc_partition_status_t
+ */
+/*! Partition status information. */
+typedef enum fsl_shw_partition_status_t {
+ FSL_PART_S_UNUSABLE, /*!< Partition not implemented */
+ FSL_PART_S_UNAVAILABLE, /*!< Partition owned by other host */
+ FSL_PART_S_AVAILABLE, /*!< Partition available */
+ FSL_PART_S_ALLOCATED, /*!< Partition owned by host but not engaged
+ */
+ FSL_PART_S_ENGAGED, /*!< Partition owned by host and engaged */
+} fsl_shw_partition_status_t;
+
+/******************************************************************************
+ * Access Macros for Objects
+ *****************************************************************************/
+/*!
+ * Get FSL SHW API version
+ *
+ * @param pcobject The Platform Capababilities Object to query.
+ * @param[out] pcmajor A pointer to where the major version
+ * of the API is to be stored.
+ * @param[out] pcminor A pointer to where the minor version
+ * of the API is to be stored.
+ */
+#define fsl_shw_pco_get_version(pcobject, pcmajor, pcminor) \
+{ \
+ *(pcmajor) = (pcobject)->api_major; \
+ *(pcminor) = (pcobject)->api_minor; \
+}
+
+/*!
+ * Get underlying driver version.
+ *
+ * @param pcobject The Platform Capababilities Object to query.
+ * @param[out] pcmajor A pointer to where the major version
+ * of the driver is to be stored.
+ * @param[out] pcminor A pointer to where the minor version
+ * of the driver is to be stored.
+ */
+#define fsl_shw_pco_get_driver_version(pcobject, pcmajor, pcminor) \
+{ \
+ *(pcmajor) = (pcobject)->driver_major; \
+ *(pcminor) = (pcobject)->driver_minor; \
+}
+
+/*!
+ * Get list of symmetric algorithms supported.
+ *
+ * @param pcobject The Platform Capababilities Object to query.
+ * @param[out] pcalgorithms A pointer to where to store the location of
+ * the list of algorithms.
+ * @param[out] pcacount A pointer to where to store the number of
+ * algorithms in the list at @a algorithms.
+ */
+#define fsl_shw_pco_get_sym_algorithms(pcobject, pcalgorithms, pcacount) \
+{ \
+ *(pcalgorithms) = (pcobject)->sym_algorithms; \
+ *(pcacount) = sizeof((pcobject)->sym_algorithms)/4; \
+}
+
+/*!
+ * Get list of symmetric modes supported.
+ *
+ * @param pcobject The Platform Capababilities Object to query.
+ * @param[out] gsmodes A pointer to where to store the location of
+ * the list of modes.
+ * @param[out] gsacount A pointer to where to store the number of
+ * algorithms in the list at @a modes.
+ */
+#define fsl_shw_pco_get_sym_modes(pcobject, gsmodes, gsacount) \
+{ \
+ *(gsmodes) = (pcobject)->sym_modes; \
+ *(gsacount) = sizeof((pcobject)->sym_modes)/4; \
+}
+
+/*!
+ * Get list of hash algorithms supported.
+ *
+ * @param pcobject The Platform Capababilities Object to query.
+ * @param[out] gsalgorithms A pointer which will be set to the list of
+ * algorithms.
+ * @param[out] gsacount The number of algorithms in the list at @a
+ * algorithms.
+ */
+#define fsl_shw_pco_get_hash_algorithms(pcobject, gsalgorithms, gsacount) \
+{ \
+ *(gsalgorithms) = (pcobject)->hash_algorithms; \
+ *(gsacount) = sizeof((pcobject)->hash_algorithms)/4; \
+}
+
+/*!
+ * Determine whether the combination of a given symmetric algorithm and a given
+ * mode is supported.
+ *
+ * @param pcobject The Platform Capababilities Object to query.
+ * @param pcalg A Symmetric Cipher algorithm.
+ * @param pcmode A Symmetric Cipher mode.
+ *
+ * @return 0 if combination is not supported, non-zero if supported.
+ */
+#define fsl_shw_pco_check_sym_supported(pcobject, pcalg, pcmode) \
+ ((pcobject)->sym_support[pcalg][pcmode])
+
+/*!
+ * Determine whether a given Encryption-Authentication mode is supported.
+ *
+ * @param pcobject The Platform Capababilities Object to query.
+ * @param pcmode The Authentication mode.
+ *
+ * @return 0 if mode is not supported, non-zero if supported.
+ */
+#define fsl_shw_pco_check_auth_supported(pcobject, pcmode) \
+ ((pcmode == FSL_ACC_MODE_CCM) ? 1 : 0)
+
+/*!
+ * Determine whether Black Keys (key establishment / wrapping) is supported.
+ *
+ * @param pcobject The Platform Capababilities Object to query.
+ *
+ * @return 0 if wrapping is not supported, non-zero if supported.
+ */
+#define fsl_shw_pco_check_black_key_supported(pcobject) \
+ 1
+
+/*!
+ * Determine whether Programmed Key features are available
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ *
+ * @return 1 if Programmed Key features are available, otherwise zero.
+ */
+#define fsl_shw_pco_check_pk_supported(pcobject) \
+ 0
+
+/*!
+ * Determine whether Software Key features are available
+ *
+ * @param pc_info The Platform Capabilities Object to query.
+ *
+ * @return 1 if Software key features are available, otherwise zero.
+ */
+#define fsl_shw_pco_check_sw_keys_supported(pcobject) \
+ 0
+
+/*!
+ * Get FSL SHW SCC driver version
+ *
+ * @param pcobject The Platform Capabilities Object to query.
+ * @param[out] pcmajor A pointer to where the major version
+ * of the SCC driver is to be stored.
+ * @param[out] pcminor A pointer to where the minor version
+ * of the SCC driver is to be stored.
+ */
+#define fsl_shw_pco_get_scc_driver_version(pcobject, pcmajor, pcminor) \
+{ \
+ *(pcmajor) = (pcobject)->scc_driver_major; \
+ *(pcminor) = (pcobject)->scc_driver_minor; \
+}
+
+/*!
+ * Get SCM hardware version
+ *
+ * @param pcobject The Platform Capabilities Object to query.
+ * @return The SCM hardware version
+ */
+#define fsl_shw_pco_get_scm_version(pcobject) \
+ ((pcobject)->scm_version)
+
+/*!
+ * Get SMN hardware version
+ *
+ * @param pcobject The Platform Capabilities Object to query.
+ * @return The SMN hardware version
+ */
+#define fsl_shw_pco_get_smn_version(pcobject) \
+ ((pcobject)->smn_version)
+
+/*!
+ * Get the size of an SCM block, in bytes
+ *
+ * @param pcobject The Platform Capabilities Object to query.
+ * @return The size of an SCM block, in bytes.
+ */
+#define fsl_shw_pco_get_scm_block_size(pcobject) \
+ ((pcobject)->block_size_bytes)
+
+/*!
+ * Get size of Black and Red RAM memory
+ *
+ * @param pcobject The Platform Capabilities Object to query.
+ * @param[out] black_size A pointer to where the size of the Black RAM, in
+ * blocks, is to be placed.
+ * @param[out] red_size A pointer to where the size of the Red RAM, in
+ * blocks, is to be placed.
+ */
+#define fsl_shw_pco_get_smn_size(pcobject, black_size, red_size) \
+{ \
+ if ((pcobject)->scm_version == 1) { \
+ *(black_size) = (pcobject)->scc_info.black_ram_size_blocks; \
+ *(red_size) = (pcobject)->scc_info.red_ram_size_blocks; \
+ } else { \
+ *(black_size) = 0; \
+ *(red_size) = 0; \
+ } \
+}
+
+/*!
+ * Determine whether Secure Partitions are supported
+ *
+ * @param pcobject The Platform Capabilities Object to query.
+ *
+ * @return 0 if secure partitions are not supported, non-zero if supported.
+ */
+#define fsl_shw_pco_check_spo_supported(pcobject) \
+ ((pcobject)->scm_version == 2)
+
+/*!
+ * Get the size of a Secure Partitions
+ *
+ * @param pcobject The Platform Capabilities Object to query.
+ *
+ * @return Partition size, in bytes. 0 if Secure Partitions not supported.
+ */
+#define fsl_shw_pco_get_spo_size_bytes(pcobject) \
+ (((pcobject)->scm_version == 2) ? \
+ ((pcobject)->scc2_info.partition_size_bytes) : 0 )
+
+/*!
+ * Get the number of Secure Partitions on this platform
+ *
+ * @param pcobject The Platform Capabilities Object to query.
+ *
+ * @return Number of partitions. 0 if Secure Paritions not supported. Note
+ * that this returns the total number of partitions, not all may be
+ * available to the user.
+ */
+#define fsl_shw_pco_get_spo_count(pcobject) \
+ (((pcobject)->scm_version == 2) ? \
+ ((pcobject)->scc2_info.partition_count) : 0 )
+
+/*!
+ * Initialize a User Context Object.
+ *
+ * This function must be called before performing any other operation with the
+ * Object. It sets the User Context Object to initial values, and set the size
+ * of the results pool. The mode will be set to a default of
+ * #FSL_UCO_BLOCKING_MODE.
+ *
+ * When using non-blocking operations, this sets the maximum number of
+ * operations which can be outstanding. This number includes the counts of
+ * operations waiting to start, operation(s) being performed, and results which
+ * have not been retrieved.
+ *
+ * Changes to this value are ignored once user registration has completed. It
+ * should be set to 1 if only blocking operations will ever be performed.
+ *
+ * @param ucontext The User Context object to operate on.
+ * @param usize The maximum number of operations which can be
+ * outstanding.
+ */
+#ifdef __KERNEL__
+#define fsl_shw_uco_init(ucontext, usize) \
+{ \
+ (ucontext)->pool_size = usize; \
+ (ucontext)->flags = FSL_UCO_BLOCKING_MODE; \
+ (ucontext)->sahara_openfd = -1; \
+ (ucontext)->mem_util = NULL; \
+ (ucontext)->partition = NULL; \
+ (ucontext)->callback = NULL; \
+}
+#else
+#define fsl_shw_uco_init(ucontext, usize) \
+{ \
+ (ucontext)->pool_size = usize; \
+ (ucontext)->flags = FSL_UCO_BLOCKING_MODE; \
+ (ucontext)->sahara_openfd = -1; \
+ (ucontext)->mem_util = NULL; \
+ (ucontext)->callback = NULL; \
+}
+#endif
+
+/*!
+ * Set the User Reference for the User Context.
+ *
+ * @param ucontext The User Context object to operate on.
+ * @param uref A value which will be passed back with a result.
+ */
+#define fsl_shw_uco_set_reference(ucontext, uref) \
+ (ucontext)->user_ref = uref
+
+/*!
+ * Set the User Reference for the User Context.
+ *
+ * @param ucontext The User Context object to operate on.
+ * @param ucallback The function the API will invoke when an operation
+ * completes.
+ */
+#define fsl_shw_uco_set_callback(ucontext, ucallback) \
+ (ucontext)->callback = ucallback
+
+/*!
+ * Set flags in the User Context.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param ucontext The User Context object to operate on.
+ * @param uflags ORed values from #fsl_shw_user_ctx_flags_t.
+ */
+#define fsl_shw_uco_set_flags(ucontext, uflags) \
+ (ucontext)->flags |= (uflags)
+
+/*!
+ * Clear flags in the User Context.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param ucontext The User Context object to operate on.
+ * @param uflags ORed values from #fsl_shw_user_ctx_flags_t.
+ */
+#define fsl_shw_uco_clear_flags(ucontext, uflags) \
+ (ucontext)->flags &= ~(uflags)
+
+/*!
+ * Retrieve the reference value from a Result Object.
+ *
+ * @param robject The result object to query.
+ *
+ * @return The reference associated with the request.
+ */
+#define fsl_shw_ro_get_reference(robject) \
+ (robject)->user_ref
+
+/*!
+ * Retrieve the status code from a Result Object.
+ *
+ * @param robject The result object to query.
+ *
+ * @return The status of the request.
+ */
+#define fsl_shw_ro_get_status(robject) \
+ (robject)->code
+
+/*!
+ * Initialize a Secret Key Object.
+ *
+ * This function must be called before performing any other operation with
+ * the Object.
+ *
+ * @param skobject The Secret Key Object to be initialized.
+ * @param skalgorithm DES, AES, etc.
+ *
+ */
+#define fsl_shw_sko_init(skobject,skalgorithm) \
+{ \
+ (skobject)->algorithm = skalgorithm; \
+ (skobject)->flags = 0; \
+ (skobject)->keystore = NULL; \
+}
+
+/*!
+ * Initialize a Secret Key Object to use a Platform Key register.
+ *
+ * This function must be called before performing any other operation with
+ * the Object. INVALID on this platform.
+ *
+ * @param skobject The Secret Key Object to be initialized.
+ * @param skalgorithm DES, AES, etc.
+ * @param skhwkey one of the fsl_shw_pf_key_t values.
+ *
+ */
+#define fsl_shw_sko_init_pf_key(skobject,skalgorithm,skhwkey) \
+{ \
+ (skobject)->algorithm = -1; \
+ (skobject)->flags = -1; \
+ (skobject)->keystore = NULL; \
+}
+
+/*!
+ * Store a cleartext key in the key object.
+ *
+ * This has the side effect of setting the #FSL_SKO_KEY_PRESENT flag and
+ * resetting the #FSL_SKO_KEY_ESTABLISHED flag.
+ *
+ * @param skobject A variable of type #fsl_shw_sko_t.
+ * @param skkey A pointer to the beginning of the key.
+ * @param skkeylen The length, in octets, of the key. The value should be
+ * appropriate to the key size supported by the algorithm.
+ * 64 octets is the absolute maximum value allowed for this
+ * call.
+ */
+#define fsl_shw_sko_set_key(skobject, skkey, skkeylen) \
+{ \
+ (skobject)->key_length = skkeylen; \
+ copy_bytes((skobject)->key, skkey, skkeylen); \
+ (skobject)->flags |= FSL_SKO_KEY_PRESENT; \
+ (skobject)->flags &= ~FSL_SKO_KEY_ESTABLISHED; \
+}
+
+/*!
+ * Set a size for the key.
+ *
+ * This function would normally be used when the user wants the key to be
+ * generated from a random source.
+ *
+ * @param skobject A variable of type #fsl_shw_sko_t.
+ * @param skkeylen The length, in octets, of the key. The value should be
+ * appropriate to the key size supported by the algorithm.
+ * 64 octets is the absolute maximum value allowed for this
+ * call.
+ */
+#define fsl_shw_sko_set_key_length(skobject, skkeylen) \
+ (skobject)->key_length = skkeylen;
+
+/*!
+ * Set the User ID associated with the key.
+ *
+ * @param skobject A variable of type #fsl_shw_sko_t.
+ * @param skuserid The User ID to identify authorized users of the key.
+ */
+#define fsl_shw_sko_set_user_id(skobject, skuserid) \
+ (skobject)->userid = (skuserid)
+
+/*!
+ * Establish a user Keystore to hold the key.
+ */
+#define fsl_shw_sko_set_keystore(skobject, user_keystore) \
+ (skobject)->keystore = (user_keystore)
+
+/*!
+ * Set the establish key handle into a key object.
+ *
+ * The @a userid field will be used to validate the access to the unwrapped
+ * key. This feature is not available for all platforms, nor for all
+ * algorithms and modes.
+ *
+ * The #FSL_SKO_KEY_ESTABLISHED will be set (and the #FSL_SKO_KEY_PRESENT flag
+ * will be cleared).
+ *
+ * @param skobject A variable of type #fsl_shw_sko_t.
+ * @param skuserid The User ID to verify this user is an authorized user of
+ * the key.
+ * @param skhandle A @a handle from #fsl_shw_sko_get_established_info.
+ */
+#define fsl_shw_sko_set_established_info(skobject, skuserid, skhandle) \
+{ \
+ (skobject)->userid = (skuserid); \
+ (skobject)->handle = (skhandle); \
+ (skobject)->flags |= FSL_SKO_KEY_ESTABLISHED; \
+ (skobject)->flags &= \
+ ~(FSL_SKO_KEY_PRESENT); \
+}
+
+/*!
+ * Retrieve the established-key handle from a key object.
+ *
+ * @param skobject A variable of type #fsl_shw_sko_t.
+ * @param skhandle The location to store the @a handle of the unwrapped
+ * key.
+ */
+#define fsl_shw_sko_get_established_info(skobject, skhandle) \
+ *(skhandle) = (skobject)->handle
+
+/*!
+ * Extract the algorithm from a key object.
+ *
+ * @param skobject The Key Object to be queried.
+ * @param[out] skalgorithm A pointer to the location to store the algorithm.
+ */
+#define fsl_shw_sko_get_algorithm(skobject, skalgorithm) \
+ *(skalgorithm) = (skobject)->algorithm
+
+/*!
+ * Retrieve the cleartext key from a key object that is stored in a user
+ * keystore.
+ *
+ * @param skobject The Key Object to be queried.
+ * @param[out] skkey A pointer to the location to store the key. NULL
+ * if the key is not stored in a user keystore.
+ */
+#define fsl_shw_sko_get_key(skobject, skkey) \
+{ \
+ fsl_shw_kso_t* keystore = (skobject)->keystore; \
+ if (keystore != NULL) { \
+ *(skkey) = keystore->slot_get_address(keystore->user_data, \
+ (skobject)->handle); \
+ } else { \
+ *(skkey) = NULL; \
+ } \
+}
+
+/*!
+ * Determine the size of a wrapped key based upon the cleartext key's length.
+ *
+ * This function can be used to calculate the number of octets that
+ * #fsl_shw_extract_key() will write into the location at @a covered_key.
+ *
+ * If zero is returned at @a length, this means that the key length in
+ * @a key_info is not supported.
+ *
+ * @param wkeyinfo Information about a key to be wrapped.
+ * @param wkeylen Location to store the length of a wrapped
+ * version of the key in @a key_info.
+ */
+#define fsl_shw_sko_calculate_wrapped_size(wkeyinfo, wkeylen) \
+{ \
+ register fsl_shw_sko_t* kp = wkeyinfo; \
+ register uint32_t kl = kp->key_length; \
+ int key_blocks = (kl + 15) / 16; \
+ int base_size = 35; /* ICV + T' + ALG + LEN + FLAGS */ \
+ \
+ *(wkeylen) = base_size + 16 * key_blocks; \
+}
+
+/*!
+ * Set some flags in the key object.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param skobject A variable of type #fsl_shw_sko_t.
+ * @param skflags (One or more) ORed members of #fsl_shw_key_flags_t which
+ * are to be set.
+ */
+#define fsl_shw_sko_set_flags(skobject, skflags) \
+ (skobject)->flags |= (skflags)
+
+/*!
+ * Clear some flags in the key object.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param skobject A variable of type #fsl_shw_sko_t.
+ * @param skflags (One or more) ORed members of #fsl_shw_key_flags_t
+ * which are to be reset.
+ */
+#define fsl_shw_sko_clear_flags(skobject, skflags) \
+ (skobject)->flags &= ~(skflags)
+
+/*!
+ * Initialize a Hash Context Object.
+ *
+ * This function must be called before performing any other operation with the
+ * Object. It sets the current message length and hash algorithm in the hash
+ * context object.
+ *
+ * @param hcobject The hash context to operate upon.
+ * @param hcalgorithm The hash algorithm to be used (#FSL_HASH_ALG_MD5,
+ * #FSL_HASH_ALG_SHA256, etc).
+ *
+ */
+#define fsl_shw_hco_init(hcobject, hcalgorithm) \
+{ \
+ (hcobject)->algorithm = hcalgorithm; \
+ (hcobject)->flags = 0; \
+ switch (hcalgorithm) { \
+ case FSL_HASH_ALG_MD5: \
+ (hcobject)->digest_length = 16; \
+ (hcobject)->context_length = 16; \
+ (hcobject)->context_register_length = 24; \
+ break; \
+ case FSL_HASH_ALG_SHA1: \
+ (hcobject)->digest_length = 20; \
+ (hcobject)->context_length = 20; \
+ (hcobject)->context_register_length = 24; \
+ break; \
+ case FSL_HASH_ALG_SHA224: \
+ (hcobject)->digest_length = 28; \
+ (hcobject)->context_length = 32; \
+ (hcobject)->context_register_length = 36; \
+ break; \
+ case FSL_HASH_ALG_SHA256: \
+ (hcobject)->digest_length = 32; \
+ (hcobject)->context_length = 32; \
+ (hcobject)->context_register_length = 36; \
+ break; \
+ default: \
+ /* error ! */ \
+ (hcobject)->digest_length = 1; \
+ (hcobject)->context_length = 1; \
+ (hcobject)->context_register_length = 1; \
+ break; \
+ } \
+}
+
+/*!
+ * Get the current hash value and message length from the hash context object.
+ *
+ * The algorithm must have already been specified. See #fsl_shw_hco_init().
+ *
+ * @param hcobject The hash context to query.
+ * @param[out] hccontext Pointer to the location of @a length octets where to
+ * store a copy of the current value of the digest.
+ * @param hcclength Number of octets of hash value to copy.
+ * @param[out] hcmsglen Pointer to the location to store the number of octets
+ * already hashed.
+ */
+#define fsl_shw_hco_get_digest(hcobject, hccontext, hcclength, hcmsglen) \
+{ \
+ copy_bytes(hccontext, (hcobject)->context, hcclength); \
+ if ((hcobject)->algorithm == FSL_HASH_ALG_SHA224 \
+ || (hcobject)->algorithm == FSL_HASH_ALG_SHA256) { \
+ *(hcmsglen) = (hcobject)->context[8]; \
+ } else { \
+ *(hcmsglen) = (hcobject)->context[5]; \
+ } \
+}
+
+/*!
+ * Get the hash algorithm from the hash context object.
+ *
+ * @param hcobject The hash context to query.
+ * @param[out] hcalgorithm Pointer to where the algorithm is to be stored.
+ */
+#define fsl_shw_hco_get_info(hcobject, hcalgorithm) \
+{ \
+ *(hcalgorithm) = (hcobject)->algorithm; \
+}
+
+/*!
+ * Set the current hash value and message length in the hash context object.
+ *
+ * The algorithm must have already been specified. See #fsl_shw_hco_init().
+ *
+ * @param hcobject The hash context to operate upon.
+ * @param hccontext Pointer to buffer of appropriate length to copy into
+ * the hash context object.
+ * @param hcmsglen The number of octets of the message which have
+ * already been hashed.
+ *
+ */
+#define fsl_shw_hco_set_digest(hcobject, hccontext, hcmsglen) \
+{ \
+ copy_bytes((hcobject)->context, hccontext, (hcobject)->context_length); \
+ if (((hcobject)->algorithm == FSL_HASH_ALG_SHA224) \
+ || ((hcobject)->algorithm == FSL_HASH_ALG_SHA256)) { \
+ (hcobject)->context[8] = hcmsglen; \
+ } else { \
+ (hcobject)->context[5] = hcmsglen; \
+ } \
+}
+
+/*!
+ * Set flags in a Hash Context Object.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param hcobject The hash context to be operated on.
+ * @param hcflags The flags to be set in the context. These can be ORed
+ * members of #fsl_shw_hash_ctx_flags_t.
+ */
+#define fsl_shw_hco_set_flags(hcobject, hcflags) \
+ (hcobject)->flags |= (hcflags)
+
+/*!
+ * Clear flags in a Hash Context Object.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param hcobject The hash context to be operated on.
+ * @param hcflags The flags to be reset in the context. These can be ORed
+ * members of #fsl_shw_hash_ctx_flags_t.
+ */
+#define fsl_shw_hco_clear_flags(hcobject, hcflags) \
+ (hcobject)->flags &= ~(hcflags)
+
+/*!
+ * Initialize an HMAC Context Object.
+ *
+ * This function must be called before performing any other operation with the
+ * Object. It sets the current message length and hash algorithm in the HMAC
+ * context object.
+ *
+ * @param hcobject The HMAC context to operate upon.
+ * @param hcalgorithm The hash algorithm to be used (#FSL_HASH_ALG_MD5,
+ * #FSL_HASH_ALG_SHA256, etc).
+ *
+ */
+#define fsl_shw_hmco_init(hcobject, hcalgorithm) \
+ fsl_shw_hco_init(hcobject, hcalgorithm)
+
+/*!
+ * Set flags in an HMAC Context Object.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param hcobject The HMAC context to be operated on.
+ * @param hcflags The flags to be set in the context. These can be ORed
+ * members of #fsl_shw_hmac_ctx_flags_t.
+ */
+#define fsl_shw_hmco_set_flags(hcobject, hcflags) \
+ (hcobject)->flags |= (hcflags)
+
+/*!
+ * Clear flags in an HMAC Context Object.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param hcobject The HMAC context to be operated on.
+ * @param hcflags The flags to be reset in the context. These can be ORed
+ * members of #fsl_shw_hmac_ctx_flags_t.
+ */
+#define fsl_shw_hmco_clear_flags(hcobject, hcflags) \
+ (hcobject)->flags &= ~(hcflags)
+
+/*!
+ * Initialize a Symmetric Cipher Context Object.
+ *
+ * This function must be called before performing any other operation with the
+ * Object. This will set the @a mode and @a algorithm and initialize the
+ * Object.
+ *
+ * @param scobject The context object to operate on.
+ * @param scalg The cipher algorithm this context will be used with.
+ * @param scmode #FSL_SYM_MODE_CBC, #FSL_SYM_MODE_ECB, etc.
+ *
+ */
+#define fsl_shw_scco_init(scobject, scalg, scmode) \
+{ \
+ register uint32_t bsb; /* block-size bytes */ \
+ \
+ switch (scalg) { \
+ case FSL_KEY_ALG_AES: \
+ bsb = 16; \
+ break; \
+ case FSL_KEY_ALG_DES: \
+ /* fall through */ \
+ case FSL_KEY_ALG_TDES: \
+ bsb = 8; \
+ break; \
+ case FSL_KEY_ALG_ARC4: \
+ bsb = 259; \
+ break; \
+ case FSL_KEY_ALG_HMAC: \
+ bsb = 1; /* meaningless */ \
+ break; \
+ default: \
+ bsb = 00; \
+ } \
+ (scobject)->block_size_bytes = bsb; \
+ (scobject)->mode = scmode; \
+ (scobject)->flags = 0; \
+}
+
+/*!
+ * Set the flags for a Symmetric Cipher Context.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param scobject The context object to operate on.
+ * @param scflags The flags to reset (one or more values from
+ * #fsl_shw_sym_ctx_flags_t ORed together).
+ *
+ */
+#define fsl_shw_scco_set_flags(scobject, scflags) \
+ (scobject)->flags |= (scflags)
+
+/*!
+ * Clear some flags in a Symmetric Cipher Context Object.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param scobject The context object to operate on.
+ * @param scflags The flags to reset (one or more values from
+ * #fsl_shw_sym_ctx_flags_t ORed together).
+ *
+ */
+#define fsl_shw_scco_clear_flags(scobject, scflags) \
+ (scobject)->flags &= ~(scflags)
+
+/*!
+ * Set the Context (IV) for a Symmetric Cipher Context.
+ *
+ * This is to set the context/IV for #FSL_SYM_MODE_CBC mode, or to set the
+ * context (the S-Box and pointers) for ARC4. The full context size will
+ * be copied.
+ *
+ * @param scobject The context object to operate on.
+ * @param sccontext A pointer to the buffer which contains the context.
+ *
+ */
+#define fsl_shw_scco_set_context(scobject, sccontext) \
+ copy_bytes((scobject)->context, sccontext, \
+ (scobject)->block_size_bytes)
+
+/*!
+ * Get the Context for a Symmetric Cipher Context.
+ *
+ * This is to retrieve the context/IV for #FSL_SYM_MODE_CBC mode, or to
+ * retrieve context (the S-Box and pointers) for ARC4. The full context
+ * will be copied.
+ *
+ * @param scobject The context object to operate on.
+ * @param[out] sccontext Pointer to location where context will be stored.
+ */
+#define fsl_shw_scco_get_context(scobject, sccontext) \
+ copy_bytes(sccontext, (scobject)->context, (scobject)->block_size_bytes)
+
+/*!
+ * Set the Counter Value for a Symmetric Cipher Context.
+ *
+ * This will set the Counter Value for CTR mode.
+ *
+ * @param scobject The context object to operate on.
+ * @param sccounter The starting counter value. The number of octets.
+ * copied will be the block size for the algorithm.
+ * @param scmodulus The modulus for controlling the incrementing of the
+ * counter.
+ *
+ */
+#define fsl_shw_scco_set_counter_info(scobject, sccounter, scmodulus) \
+ { \
+ if ((sccounter) != NULL) { \
+ copy_bytes((scobject)->context, sccounter, \
+ (scobject)->block_size_bytes); \
+ } \
+ (scobject)->modulus_exp = scmodulus; \
+ }
+
+/*!
+ * Get the Counter Value for a Symmetric Cipher Context.
+ *
+ * This will retrieve the Counter Value is for CTR mode.
+ *
+ * @param scobject The context object to query.
+ * @param[out] sccounter Pointer to location to store the current counter
+ * value. The number of octets copied will be the
+ * block size for the algorithm.
+ * @param[out] scmodulus Pointer to location to store the modulus.
+ *
+ */
+#define fsl_shw_scco_get_counter_info(scobject, sccounter, scmodulus) \
+ { \
+ if ((sccounter) != NULL) { \
+ copy_bytes(sccounter, (scobject)->context, \
+ (scobject)->block_size_bytes); \
+ } \
+ if ((scmodulus) != NULL) { \
+ *(scmodulus) = (scobject)->modulus_exp; \
+ } \
+ }
+
+/*!
+ * Initialize a Authentication-Cipher Context.
+ *
+ * @param acobject Pointer to object to operate on.
+ * @param acmode The mode for this object (only #FSL_ACC_MODE_CCM
+ * supported).
+ */
+#define fsl_shw_acco_init(acobject, acmode) \
+ { \
+ (acobject)->flags = 0; \
+ (acobject)->mode = (acmode); \
+ }
+
+/*!
+ * Set the flags for a Authentication-Cipher Context.
+ *
+ * Turns on the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param acobject Pointer to object to operate on.
+ * @param acflags The flags to set (one or more from
+ * #fsl_shw_auth_ctx_flags_t ORed together).
+ *
+ */
+#define fsl_shw_acco_set_flags(acobject, acflags) \
+ (acobject)->flags |= (acflags)
+
+/*!
+ * Clear some flags in a Authentication-Cipher Context Object.
+ *
+ * Turns off the flags specified in @a flags. Other flags are untouched.
+ *
+ * @param acobject Pointer to object to operate on.
+ * @param acflags The flags to reset (one or more from
+ * #fsl_shw_auth_ctx_flags_t ORed together).
+ *
+ */
+#define fsl_shw_acco_clear_flags(acobject, acflags) \
+ (acobject)->flags &= ~(acflags)
+
+/*!
+ * Set up the Authentication-Cipher Object for CCM mode.
+ *
+ * This will set the @a auth_object for CCM mode and save the @a ctr,
+ * and @a mac_length. This function can be called instead of
+ * #fsl_shw_acco_init().
+ *
+ * The paramater @a ctr is Counter Block 0, (counter value 0), which is for the
+ * MAC.
+ *
+ * @param acobject Pointer to object to operate on.
+ * @param acalg Cipher algorithm. Only AES is supported.
+ * @param accounter The initial counter value.
+ * @param acmaclen The number of octets used for the MAC. Valid values are
+ * 4, 6, 8, 10, 12, 14, and 16.
+ */
+/* Do we need to stash the +1 value of the CTR somewhere? */
+#define fsl_shw_acco_set_ccm(acobject, acalg, accounter, acmaclen) \
+{ \
+ (acobject)->flags = 0; \
+ (acobject)->mode = FSL_ACC_MODE_CCM; \
+ (acobject)->auth_info.CCM_ctx_info.block_size_bytes = 16; \
+ (acobject)->cipher_ctx_info.block_size_bytes = 16; \
+ (acobject)->mac_length = acmaclen; \
+ fsl_shw_scco_set_counter_info(&(acobject)->cipher_ctx_info, accounter, \
+ FSL_CTR_MOD_128); \
+}
+
+/*!
+ * Format the First Block (IV) & Initial Counter Value per NIST CCM.
+ *
+ * This function will also set the IV and CTR values per Appendix A of NIST
+ * Special Publication 800-38C (May 2004). It will also perform the
+ * #fsl_shw_acco_set_ccm() operation with information derived from this set of
+ * parameters.
+ *
+ * Note this function assumes the algorithm is AES. It initializes the
+ * @a auth_object by setting the mode to #FSL_ACC_MODE_CCM and setting the
+ * flags to be #FSL_ACCO_NIST_CCM.
+ *
+ * @param acobject Pointer to object to operate on.
+ * @param act The number of octets used for the MAC. Valid values are
+ * 4, 6, 8, 10, 12, 14, and 16.
+ * @param acad Number of octets of Associated Data (may be zero).
+ * @param acq A value for the size of the length of @a q field. Valid
+ * values are 1-8.
+ * @param acN The Nonce (packet number or other changing value). Must
+ * be (15 - @a q_length) octets long.
+ * @param acQ The value of Q (size of the payload in octets).
+ *
+ */
+/* Do we need to stash the +1 value of the CTR somewhere? */
+#define fsl_shw_ccm_nist_format_ctr_and_iv(acobject, act, acad, acq, acN, acQ)\
+ { \
+ uint64_t Q = acQ; \
+ uint8_t bflag = ((acad)?0x40:0) | ((((act)-2)/2)<<3) | ((acq)-1); \
+ unsigned i; \
+ uint8_t* qptr = (acobject)->auth_info.CCM_ctx_info.context + 15; \
+ (acobject)->auth_info.CCM_ctx_info.block_size_bytes = 16; \
+ (acobject)->cipher_ctx_info.block_size_bytes = 16; \
+ (acobject)->mode = FSL_ACC_MODE_CCM; \
+ (acobject)->flags = FSL_ACCO_NIST_CCM; \
+ \
+ /* Store away the MAC length (after calculating actual value */ \
+ (acobject)->mac_length = (act); \
+ /* Set Flag field in Block 0 */ \
+ *((acobject)->auth_info.CCM_ctx_info.context) = bflag; \
+ /* Set Nonce field in Block 0 */ \
+ copy_bytes((acobject)->auth_info.CCM_ctx_info.context+1, acN, \
+ 15-(acq)); \
+ /* Set Flag field in ctr */ \
+ *((acobject)->cipher_ctx_info.context) = (acq)-1; \
+ /* Update the Q (payload length) field of Block0 */ \
+ (acobject)->q_length = acq; \
+ for (i = 0; i < (acq); i++) { \
+ *qptr-- = Q & 0xFF; \
+ Q >>= 8; \
+ } \
+ /* Set the Nonce field of the ctr */ \
+ copy_bytes((acobject)->cipher_ctx_info.context+1, acN, 15-(acq)); \
+ /* Clear the block counter field of the ctr */ \
+ memset((acobject)->cipher_ctx_info.context+16-(acq), 0, (acq)+1); \
+ }
+
+/*!
+ * Update the First Block (IV) & Initial Counter Value per NIST CCM.
+ *
+ * This function will set the IV and CTR values per Appendix A of NIST Special
+ * Publication 800-38C (May 2004).
+ *
+ * Note this function assumes that #fsl_shw_ccm_nist_format_ctr_and_iv() has
+ * previously been called on the @a auth_object.
+ *
+ * @param acobject Pointer to object to operate on.
+ * @param acN The Nonce (packet number or other changing value). Must
+ * be (15 - @a q_length) octets long.
+ * @param acQ The value of Q (size of the payload in octets).
+ *
+ */
+/* Do we need to stash the +1 value of the CTR somewhere? */
+#define fsl_shw_ccm_nist_update_ctr_and_iv(acobject, acN, acQ) \
+ { \
+ uint64_t Q = acQ; \
+ unsigned i; \
+ uint8_t* qptr = (acobject)->auth_info.CCM_ctx_info.context + 15; \
+ \
+ /* Update the Nonce field field of Block0 */ \
+ copy_bytes((acobject)->auth_info.CCM_ctx_info.context+1, acN, \
+ 15 - (acobject)->q_length); \
+ /* Update the Q (payload length) field of Block0 */ \
+ for (i = 0; i < (acobject)->q_length; i++) { \
+ *qptr-- = Q & 0xFF; \
+ Q >>= 8; \
+ } \
+ /* Update the Nonce field of the ctr */ \
+ copy_bytes((acobject)->cipher_ctx_info.context+1, acN, \
+ 15 - (acobject)->q_length); \
+ }
+
+/******************************************************************************
+ * Library functions
+ *****************************************************************************/
+/* REQ-S2LRD-PINTFC-API-GEN-003 */
+extern fsl_shw_pco_t *fsl_shw_get_capabilities(fsl_shw_uco_t * user_ctx);
+
+/* REQ-S2LRD-PINTFC-API-GEN-004 */
+extern fsl_shw_return_t fsl_shw_register_user(fsl_shw_uco_t * user_ctx);
+
+/* REQ-S2LRD-PINTFC-API-GEN-005 */
+extern fsl_shw_return_t fsl_shw_deregister_user(fsl_shw_uco_t * user_ctx);
+
+/* REQ-S2LRD-PINTFC-API-GEN-006 */
+extern fsl_shw_return_t fsl_shw_get_results(fsl_shw_uco_t * user_ctx,
+ unsigned result_size,
+ fsl_shw_result_t results[],
+ unsigned *result_count);
+
+extern fsl_shw_return_t fsl_shw_establish_key(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ fsl_shw_key_wrap_t establish_type,
+ const uint8_t * key);
+
+extern fsl_shw_return_t fsl_shw_extract_key(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ uint8_t * covered_key);
+
+extern fsl_shw_return_t fsl_shw_release_key(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info);
+
+extern void *fsl_shw_smalloc(fsl_shw_uco_t * user_ctx,
+ uint32_t size,
+ const uint8_t * UMID, uint32_t permissions);
+
+extern fsl_shw_return_t fsl_shw_sfree(fsl_shw_uco_t * user_ctx, void *address);
+
+extern fsl_shw_return_t fsl_shw_sstatus(fsl_shw_uco_t * user_ctx,
+ void *address,
+ fsl_shw_partition_status_t * status);
+
+extern fsl_shw_return_t fsl_shw_diminish_perms(fsl_shw_uco_t * user_ctx,
+ void *address,
+ uint32_t permissions);
+
+extern fsl_shw_return_t do_scc_engage_partition(fsl_shw_uco_t * user_ctx,
+ void *address,
+ const uint8_t * UMID,
+ uint32_t permissions);
+
+extern fsl_shw_return_t do_system_keystore_slot_alloc(fsl_shw_uco_t * user_ctx,
+ uint32_t key_lenth,
+ uint64_t ownerid,
+ uint32_t * slot);
+
+extern fsl_shw_return_t do_system_keystore_slot_dealloc(fsl_shw_uco_t *
+ user_ctx,
+ uint64_t ownerid,
+ uint32_t slot);
+
+extern fsl_shw_return_t do_system_keystore_slot_load(fsl_shw_uco_t * user_ctx,
+ uint64_t ownerid,
+ uint32_t slot,
+ const uint8_t * key,
+ uint32_t key_length);
+
+extern fsl_shw_return_t do_system_keystore_slot_read(fsl_shw_uco_t * user_ctx,
+ uint64_t ownerid,
+ uint32_t slot,
+ uint32_t key_length,
+ const uint8_t * key);
+
+extern fsl_shw_return_t do_system_keystore_slot_encrypt(fsl_shw_uco_t *
+ user_ctx,
+ uint64_t ownerid,
+ uint32_t slot,
+ uint32_t key_length,
+ uint8_t * black_data);
+
+extern fsl_shw_return_t do_system_keystore_slot_decrypt(fsl_shw_uco_t *
+ user_ctx,
+ uint64_t ownerid,
+ uint32_t slot,
+ uint32_t key_length,
+ const uint8_t *
+ black_data);
+
+extern fsl_shw_return_t
+do_scc_encrypt_region(fsl_shw_uco_t * user_ctx,
+ void *partition_base, uint32_t offset_bytes,
+ uint32_t byte_count, uint8_t * black_data,
+ uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode);
+
+extern fsl_shw_return_t
+do_scc_decrypt_region(fsl_shw_uco_t * user_ctx,
+ void *partition_base, uint32_t offset_bytes,
+ uint32_t byte_count, const uint8_t * black_data,
+ uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode);
+
+extern fsl_shw_return_t
+system_keystore_get_slot_info(uint64_t owner_id, uint32_t slot,
+ uint32_t * address, uint32_t * slot_size_bytes);
+
+/* REQ-S2LRD-PINTFC-API-BASIC-SYM-002 */
+/* PINTFC-API-BASIC-SYM-ARC4-001 */
+/* PINTFC-API-BASIC-SYM-ARC4-002 */
+extern fsl_shw_return_t fsl_shw_symmetric_encrypt(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ fsl_shw_scco_t * sym_ctx,
+ uint32_t length,
+ const uint8_t * pt,
+ uint8_t * ct);
+
+/* PINTFC-API-BASIC-SYM-002 */
+/* PINTFC-API-BASIC-SYM-ARC4-001 */
+/* PINTFC-API-BASIC-SYM-ARC4-002 */
+extern fsl_shw_return_t fsl_shw_symmetric_decrypt(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ fsl_shw_scco_t * sym_ctx,
+ uint32_t length,
+ const uint8_t * ct,
+ uint8_t * pt);
+
+/* REQ-S2LRD-PINTFC-API-BASIC-HASH-005 */
+extern fsl_shw_return_t fsl_shw_hash(fsl_shw_uco_t * user_ctx,
+ fsl_shw_hco_t * hash_ctx,
+ const uint8_t * msg,
+ uint32_t length,
+ uint8_t * result, uint32_t result_len);
+
+/* REQ-S2LRD-PINTFC-API-BASIC-HMAC-001 */
+extern fsl_shw_return_t fsl_shw_hmac_precompute(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ fsl_shw_hmco_t * hmac_ctx);
+
+/* REQ-S2LRD-PINTFC-API-BASIC-HMAC-002 */
+extern fsl_shw_return_t fsl_shw_hmac(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ fsl_shw_hmco_t * hmac_ctx,
+ const uint8_t * msg,
+ uint32_t length,
+ uint8_t * result, uint32_t result_len);
+
+/* REQ-S2LRD-PINTFC-API-BASIC-RNG-002 */
+extern fsl_shw_return_t fsl_shw_get_random(fsl_shw_uco_t * user_ctx,
+ uint32_t length, uint8_t * data);
+
+extern fsl_shw_return_t fsl_shw_add_entropy(fsl_shw_uco_t * user_ctx,
+ uint32_t length, uint8_t * data);
+
+extern fsl_shw_return_t fsl_shw_gen_encrypt(fsl_shw_uco_t * user_ctx,
+ fsl_shw_acco_t * auth_ctx,
+ fsl_shw_sko_t * cipher_key_info,
+ fsl_shw_sko_t * auth_key_info,
+ uint32_t auth_data_length,
+ const uint8_t * auth_data,
+ uint32_t payload_length,
+ const uint8_t * payload,
+ uint8_t * ct, uint8_t * auth_value);
+
+extern fsl_shw_return_t fsl_shw_auth_decrypt(fsl_shw_uco_t * user_ctx,
+ fsl_shw_acco_t * auth_ctx,
+ fsl_shw_sko_t * cipher_key_info,
+ fsl_shw_sko_t * auth_key_info,
+ uint32_t auth_data_length,
+ const uint8_t * auth_data,
+ uint32_t payload_length,
+ const uint8_t * ct,
+ const uint8_t * auth_value,
+ uint8_t * payload);
+
+extern fsl_shw_return_t fsl_shw_read_key(fsl_shw_uco_t * user_ctx,
+ fsl_shw_sko_t * key_info,
+ uint8_t * key);
+
+static inline fsl_shw_return_t fsl_shw_gen_random_pf_key(fsl_shw_uco_t *
+ user_ctx)
+{
+ (void)user_ctx;
+
+ return FSL_RETURN_NO_RESOURCE_S;
+}
+
+static inline fsl_shw_return_t fsl_shw_read_tamper_event(fsl_shw_uco_t *
+ user_ctx,
+ fsl_shw_tamper_t *
+ tamperp,
+ uint64_t * timestampp)
+{
+ (void)user_ctx;
+ (void)tamperp;
+ (void)timestampp;
+
+ return FSL_RETURN_NO_RESOURCE_S;
+}
+
+fsl_shw_return_t sah_Append_Desc(const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_head,
+ const uint32_t header,
+ sah_Link * link1, sah_Link * link2);
+
+/* Utility Function leftover from sahara1 API */
+void sah_Descriptor_Chain_Destroy(const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_chain);
+
+/* Utility Function leftover from sahara1 API */
+fsl_shw_return_t sah_Descriptor_Chain_Execute(sah_Head_Desc * desc_chain,
+ fsl_shw_uco_t * user_ctx);
+
+fsl_shw_return_t sah_Append_Link(const sah_Mem_Util * mu,
+ sah_Link * link,
+ uint8_t * p,
+ const size_t length,
+ const sah_Link_Flags flags);
+
+fsl_shw_return_t sah_Create_Link(const sah_Mem_Util * mu,
+ sah_Link ** link,
+ uint8_t * p,
+ const size_t length,
+ const sah_Link_Flags flags);
+
+fsl_shw_return_t sah_Create_Key_Link(const sah_Mem_Util * mu,
+ sah_Link ** link,
+ fsl_shw_sko_t * key_info);
+
+void sah_Destroy_Link(const sah_Mem_Util * mu, sah_Link * link);
+
+void sah_Postprocess_Results(fsl_shw_uco_t * user_ctx,
+ sah_results * result_info);
+
+#endif /* SAHARA2_API_H */
diff --git a/drivers/mxc/security/sahara2/include/sahara2_kernel.h b/drivers/mxc/security/sahara2/include/sahara2_kernel.h
new file mode 100644
index 000000000000..bd2fae8e684a
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/sahara2_kernel.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#define DRIVER_NAME sahara2
+
+#define SAHARA_MAJOR_NODE 78
+
+#include "portable_os.h"
+
+#include "platform_abstractions.h"
+
+/* Forward-declare prototypes using signature macros */
+
+OS_DEV_ISR_DCL(sahara2_isr);
+
+OS_DEV_INIT_DCL(sahara2_init);
+
+OS_DEV_SHUTDOWN_DCL(sahara2_shutdown);
+
+OS_DEV_OPEN_DCL(sahara2_open);
+
+OS_DEV_CLOSE_DCL(sahara2_release);
+
+OS_DEV_IOCTL_DCL(sahara2_ioctl);
+
+struct sahara2_kernel_user {
+ void *command_ring[32];
+};
+
+struct sahara2_sym_arg {
+ char *key;
+ unsigned key_len;
+};
+
+/*! These need to be added to Linux / OS abstractions */
+/*
+module_init(OS_DEV_INIT_REF(sahara2_init));
+module_cleanup(OS_DEV_SHUTDOWN_REF(sahara2_shutdown));
+*/
diff --git a/drivers/mxc/security/sahara2/include/sf_util.h b/drivers/mxc/security/sahara2/include/sf_util.h
new file mode 100644
index 000000000000..f64c3f7c393c
--- /dev/null
+++ b/drivers/mxc/security/sahara2/include/sf_util.h
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+* @file sf_util.h
+*
+* @brief Header for Sahara Descriptor-chain building Functions
+*/
+#ifndef SF_UTIL_H
+#define SF_UTIL_H
+
+#include <fsl_platform.h>
+#include <sahara.h>
+
+/*! Header value for Sahara Descriptor 1 */
+#define SAH_HDR_SKHA_SET_MODE_IV_KEY 0x10880000
+/*! Header value for Sahara Descriptor 2 */
+#define SAH_HDR_SKHA_SET_MODE_ENC_DEC 0x108D0000
+/*! Header value for Sahara Descriptor 4 */
+#define SAH_HDR_SKHA_ENC_DEC 0x90850000
+/*! Header value for Sahara Descriptor 5 */
+#define SAH_HDR_SKHA_READ_CONTEXT_IV 0x10820000
+/*! Header value for Sahara Descriptor 6 */
+#define SAH_HDR_MDHA_SET_MODE_MD_KEY 0x20880000
+/*! Header value for Sahara Descriptor 8 */
+#define SAH_HDR_MDHA_SET_MODE_HASH 0x208D0000
+/*! Header value for Sahara Descriptor 10 */
+#define SAH_HDR_MDHA_HASH 0xA0850000
+/*! Header value for Sahara Descriptor 11 */
+#define SAH_HDR_MDHA_STORE_DIGEST 0x20820000
+/*! Header value for Sahara Descriptor 18 */
+#define SAH_HDR_RNG_GENERATE 0x308C0000
+/*! Header value for Sahara Descriptor 19 */
+#define SAH_HDR_PKHA_LD_N_E 0xC0800000
+/*! Header value for Sahara Descriptor 20 */
+#define SAH_HDR_PKHA_LD_A_EX_ST_B 0x408D0000
+/*! Header value for Sahara Descriptor 21 */
+#define SAH_HDR_PKHA_LD_N_EX_ST_B 0x408E0000
+/*! Header value for Sahara Descriptor 22 */
+#define SAH_HDR_PKHA_LD_A_B 0xC0830000
+/*! Header value for Sahara Descriptor 23 */
+#define SAH_HDR_PKHA_LD_A0_A1 0x40840000
+/*! Header value for Sahara Descriptor 24 */
+#define SAH_HDR_PKHA_LD_A2_A3 0xC0850000
+/*! Header value for Sahara Descriptor 25 */
+#define SAH_HDR_PKHA_LD_B0_B1 0xC0860000
+/*! Header value for Sahara Descriptor 26 */
+#define SAH_HDR_PKHA_LD_B2_B3 0x40870000
+/*! Header value for Sahara Descriptor 27 */
+#define SAH_HDR_PKHA_ST_A_B 0x40820000
+/*! Header value for Sahara Descriptor 28 */
+#define SAH_HDR_PKHA_ST_A0_A1 0x40880000
+/*! Header value for Sahara Descriptor 29 */
+#define SAH_HDR_PKHA_ST_A2_A3 0xC0890000
+/*! Header value for Sahara Descriptor 30 */
+#define SAH_HDR_PKHA_ST_B0_B1 0xC08A0000
+/*! Header value for Sahara Descriptor 31 */
+#define SAH_HDR_PKHA_ST_B2_B3 0x408B0000
+/*! Header value for Sahara Descriptor 32 */
+#define SAH_HDR_PKHA_EX_ST_B1 0xC08C0000
+/*! Header value for Sahara Descriptor 33 */
+#define SAH_HDR_ARC4_SET_MODE_SBOX 0x90890000
+/*! Header value for Sahara Descriptor 34 */
+#define SAH_HDR_ARC4_READ_SBOX 0x90860000
+/*! Header value for Sahara Descriptor 35 */
+#define SAH_HDR_ARC4_SET_MODE_KEY 0x90830000
+/*! Header value for Sahara Descriptor 36 */
+#define SAH_HDR_PKHA_LD_A3_B0 0x40810000
+/*! Header value for Sahara Descriptor 37 */
+#define SAH_HDR_PKHA_ST_B1_B2 0xC08F0000
+/*! Header value for Sahara Descriptor 38 */
+#define SAH_HDR_SKHA_CBC_ICV 0x10840000
+/*! Header value for Sahara Descriptor 39 */
+#define SAH_HDR_MDHA_ICV_CHECK 0xA08A0000
+
+/*! Header bit indicating "Link-List optimization" */
+#define SAH_HDR_LLO 0x01000000
+
+#define SAH_SF_DCLS \
+ fsl_shw_return_t ret; \
+ unsigned sf_executed = 0; \
+ sah_Head_Desc* desc_chain = NULL; \
+ uint32_t header
+
+#define SAH_SF_USER_CHECK() \
+do { \
+ ret = sah_validate_uco(user_ctx); \
+ if (ret != FSL_RETURN_OK_S) { \
+ goto out; \
+ } \
+} while (0)
+
+#define SAH_SF_EXECUTE() \
+do { \
+ sf_executed = 1; \
+ ret = sah_Descriptor_Chain_Execute(desc_chain, user_ctx); \
+} while (0)
+
+#define SAH_SF_DESC_CLEAN() \
+do { \
+ if (!sf_executed || (user_ctx->flags & FSL_UCO_BLOCKING_MODE)) { \
+ sah_Descriptor_Chain_Destroy(user_ctx->mem_util, &desc_chain); \
+ } \
+ (void) header; \
+} while (0)
+
+/*! Add Descriptor with two inputs */
+#define DESC_IN_IN(hdr, len1, ptr1, len2, ptr2) \
+{ \
+ ret = sah_add_two_in_desc(hdr, ptr1, len1, ptr2, len2, \
+ user_ctx->mem_util, &desc_chain); \
+ if (ret != FSL_RETURN_OK_S) { \
+ goto out; \
+ } \
+}
+
+/*! Add Descriptor with two vectors */
+#define DESC_D_D(hdr, len1, ptr1, len2, ptr2) \
+{ \
+ ret = sah_add_two_d_desc(hdr, ptr1, len1, ptr2, len2, \
+ user_ctx->mem_util, &desc_chain); \
+ if (ret != FSL_RETURN_OK_S) { \
+ goto out; \
+ } \
+}
+
+/*! Add Descriptor with input and a key */
+#define DESC_IN_KEY(hdr, len1, ptr1, key2) \
+{ \
+ ret = sah_add_in_key_desc(hdr, ptr1, len1, key2, \
+ user_ctx->mem_util, &desc_chain); \
+ if (ret != FSL_RETURN_OK_S) { \
+ goto out; \
+ } \
+}
+
+/*! Add Descriptor with input and an output */
+#define DESC_IN_OUT(hdr, len1, ptr1, len2, ptr2) \
+{ \
+ ret = sah_add_in_out_desc(hdr, ptr1, len1, ptr2, len2, \
+ user_ctx->mem_util, &desc_chain); \
+ if (ret != FSL_RETURN_OK_S) { \
+ goto out; \
+ } \
+}
+
+/*! Add Descriptor with input and a key output */
+#define DESC_IN_KEYOUT(hdr, len1, ptr1, key2) \
+{ \
+ ret = sah_add_in_keyout_desc(hdr, ptr1, len1, key2, \
+ user_ctx->mem_util, &desc_chain); \
+ if (ret != FSL_RETURN_OK_S) { \
+ goto out; \
+ } \
+}
+
+/*! Add Descriptor with a key and an output */
+#define DESC_KEY_OUT(hdr, key1, len2, ptr2) \
+{ \
+ ret = sah_add_key_out_desc(hdr, key1, ptr2, len2, \
+ user_ctx->mem_util, &desc_chain); \
+ if (ret != FSL_RETURN_OK_S) { \
+ goto out; \
+ } \
+}
+
+/*! Add Descriptor with two outputs */
+#define DESC_OUT_OUT(hdr, len1, ptr1, len2, ptr2) \
+{ \
+ ret = sah_add_two_out_desc(hdr, ptr1, len1, ptr2, len2, \
+ user_ctx->mem_util, &desc_chain); \
+ if (ret != FSL_RETURN_OK_S) { \
+ goto out; \
+ } \
+}
+
+/*! Add Descriptor with output then input pointers */
+#define DESC_OUT_IN(hdr, len1, ptr1, len2, ptr2) \
+{ \
+ ret = sah_add_out_in_desc(hdr, ptr1, len1, ptr2, len2, \
+ user_ctx->mem_util, &desc_chain); \
+ if (ret != FSL_RETURN_OK_S) { \
+ goto out; \
+ } \
+}
+
+#ifdef SAH_SF_DEBUG
+/*! Add Descriptor with two outputs */
+#define DBG_DESC(hdr, len1, ptr1, len2, ptr2) \
+{ \
+ ret = sah_add_two_out_desc(hdr, ptr1, len1, ptr2, len2, \
+ user_ctx->mem_util, &desc_chain); \
+ if (ret != FSL_RETURN_OK_S) { \
+ goto out; \
+ } \
+}
+#else
+#define DBG_DESC(hdr, len1, ptr1, len2, ptr2)
+#endif
+
+#ifdef __KERNEL__
+#define DESC_DBG_ON ({console_loglevel = 8;})
+#define DESC_DBG_OFF ({console_loglevel = 7;})
+#else
+#define DESC_DBG_ON system("echo 8 > /proc/sys/kernel/printk")
+#define DESC_DBG_OFF system("echo 7 > /proc/sys/kernel/printk")
+#endif
+
+#define DESC_TEMP_ALLOC(size) \
+({ \
+ uint8_t* ptr; \
+ ptr = user_ctx->mem_util->mu_malloc(user_ctx->mem_util->mu_ref, \
+ size); \
+ if (ptr == NULL) { \
+ ret = FSL_RETURN_NO_RESOURCE_S; \
+ goto out; \
+ } \
+ \
+ ptr; \
+})
+
+#define DESC_TEMP_FREE(ptr) \
+({ \
+ if ((ptr != NULL) && \
+ (!sf_executed || (user_ctx->flags & FSL_UCO_BLOCKING_MODE))) { \
+ user_ctx->mem_util-> \
+ mu_free(user_ctx->mem_util->mu_ref, ptr); \
+ ptr = NULL; \
+ } \
+})
+
+/* Temporary implementation. This needs to be in internal/secure RAM */
+#define DESC_TEMP_SECURE_ALLOC(size) \
+({ \
+ uint8_t* ptr; \
+ ptr = user_ctx->mem_util->mu_malloc(user_ctx->mem_util->mu_ref, \
+ size); \
+ if (ptr == NULL) { \
+ ret = FSL_RETURN_NO_RESOURCE_S; \
+ goto out; \
+ } \
+ \
+ ptr; \
+})
+
+#define DESC_TEMP_SECURE_FREE(ptr, size) \
+({ \
+ if ((ptr != NULL) && \
+ (!sf_executed || (user_ctx->flags & FSL_UCO_BLOCKING_MODE))) { \
+ user_ctx->mem_util->mu_memset(user_ctx->mem_util->mu_ref, \
+ ptr, 0, size); \
+ \
+ user_ctx->mem_util-> \
+ mu_free(user_ctx->mem_util->mu_ref, ptr); \
+ ptr = NULL; \
+ } \
+})
+
+extern const uint32_t sah_insert_mdha_algorithm[];
+
+/*! @defgroup mdhaflags MDHA Mode Register Values
+ *
+ * These are bit fields and combinations of bit fields for setting the Mode
+ * Register portion of a Sahara Descriptor Header field.
+ *
+ * The parity bit has been set to ensure that these values have even parity,
+ * therefore using an Exclusive-OR operation against an existing header will
+ * preserve its parity.
+ *
+ * @addtogroup mdhaflags
+ @{
+ */
+#define sah_insert_mdha_icv_check 0x80001000
+#define sah_insert_mdha_ssl 0x80000400
+#define sah_insert_mdha_mac_full 0x80000200
+#define sah_insert_mdha_opad 0x80000080
+#define sah_insert_mdha_ipad 0x80000040
+#define sah_insert_mdha_init 0x80000020
+#define sah_insert_mdha_hmac 0x80000008
+#define sah_insert_mdha_pdata 0x80000004
+#define sah_insert_mdha_algorithm_sha224 0x00000003
+#define sah_insert_mdha_algorithm_sha256 0x80000002
+#define sah_insert_mdha_algorithm_md5 0x80000001
+#define sah_insert_mdha_algorithm_sha1 0x00000000
+/*! @} */
+
+extern const uint32_t sah_insert_skha_algorithm[];
+extern const uint32_t sah_insert_skha_mode[];
+extern const uint32_t sah_insert_skha_modulus[];
+
+/*! @defgroup skhaflags SKHA Mode Register Values
+ *
+ * These are bit fields and combinations of bit fields for setting the Mode
+ * Register portion of a Sahara Descriptor Header field.
+ *
+ * The parity bit has been set to ensure that these values have even parity,
+ * therefore using an Exclusive-OR operation against an existing header will
+ * preserve its parity.
+ *
+ * @addtogroup skhaflags
+ @{
+ */
+/*! */
+#define sah_insert_skha_modulus_128 0x00001e00
+#define sah_insert_skha_no_key_parity 0x80000100
+#define sah_insert_skha_ctr_last_block 0x80000020
+#define sah_insert_skha_suppress_cbc 0x80000020
+#define sah_insert_skha_no_permute 0x80000020
+#define sah_insert_skha_algorithm_arc4 0x00000003
+#define sah_insert_skha_algorithm_tdes 0x80000002
+#define sah_insert_skha_algorithm_des 0x80000001
+#define sah_insert_skha_algorithm_aes 0x00000000
+#define sah_insert_skha_aux0 0x80000020
+#define sah_insert_skha_mode_ctr 0x00000018
+#define sah_insert_skha_mode_ccm 0x80000010
+#define sah_insert_skha_mode_cbc 0x80000008
+#define sah_insert_skha_mode_ecb 0x00000000
+#define sah_insert_skha_encrypt 0x80000004
+#define sah_insert_skha_decrypt 0x00000000
+/*! @} */
+
+/*! @defgroup rngflags RNG Mode Register Values
+ *
+ */
+/*! */
+#define sah_insert_rng_gen_seed 0x80000001
+
+/*! @} */
+
+/*! @defgroup pkhaflags PKHA Mode Register Values
+ *
+ */
+/*! */
+#define sah_insert_pkha_soft_err_false 0x80000200
+#define sah_insert_pkha_soft_err_true 0x80000100
+
+#define sah_insert_pkha_rtn_clr_mem 0x80000001
+#define sah_insert_pkha_rtn_clr_eram 0x80000002
+#define sah_insert_pkha_rtn_mod_exp 0x00000003
+#define sah_insert_pkha_rtn_mod_r2modn 0x80000004
+#define sah_insert_pkha_rtn_mod_rrmodp 0x00000005
+#define sah_insert_pkha_rtn_ec_fp_aff_ptmul 0x00000006
+#define sah_insert_pkha_rtn_ec_f2m_aff_ptmul 0x80000007
+#define sah_insert_pkha_rtn_ec_fp_proj_ptmul 0x80000008
+#define sah_insert_pkha_rtn_ec_f2m_proj_ptmul 0x00000009
+#define sah_insert_pkha_rtn_ec_fp_add 0x0000000A
+#define sah_insert_pkha_rtn_ec_fp_double 0x8000000B
+#define sah_insert_pkha_rtn_ec_f2m_add 0x0000000C
+#define sah_insert_pkha_rtn_ec_f2m_double 0x8000000D
+#define sah_insert_pkha_rtn_f2m_r2modn 0x8000000E
+#define sah_insert_pkha_rtn_f2m_inv 0x0000000F
+#define sah_insert_pkha_rtn_mod_inv 0x80000010
+#define sah_insert_pkha_rtn_rsa_sstep 0x00000011
+#define sah_insert_pkha_rtn_mod_emodn 0x00000012
+#define sah_insert_pkha_rtn_f2m_emodn 0x80000013
+#define sah_insert_pkha_rtn_ec_fp_ptmul 0x00000014
+#define sah_insert_pkha_rtn_ec_f2m_ptmul 0x80000015
+#define sah_insert_pkha_rtn_f2m_gcd 0x80000016
+#define sah_insert_pkha_rtn_mod_gcd 0x00000017
+#define sah_insert_pkha_rtn_f2m_dbl_aff 0x00000018
+#define sah_insert_pkha_rtn_fp_dbl_aff 0x80000019
+#define sah_insert_pkha_rtn_f2m_add_aff 0x8000001A
+#define sah_insert_pkha_rtn_fp_add_aff 0x0000001B
+#define sah_insert_pkha_rtn_f2m_exp 0x8000001C
+#define sah_insert_pkha_rtn_mod_exp_teq 0x0000001D
+#define sah_insert_pkha_rtn_rsa_sstep_teq 0x0000001E
+#define sah_insert_pkha_rtn_f2m_multn 0x8000001F
+#define sah_insert_pkha_rtn_mod_multn 0x80000020
+#define sah_insert_pkha_rtn_mod_add 0x00000021
+#define sah_insert_pkha_rtn_mod_sub 0x00000022
+#define sah_insert_pkha_rtn_mod_mult1_mont 0x80000023
+#define sah_insert_pkha_rtn_mod_mult2_deconv 0x00000024
+#define sah_insert_pkha_rtn_f2m_add 0x80000025
+#define sah_insert_pkha_rtn_f2m_mult1_mont 0x80000026
+#define sah_insert_pkha_rtn_f2m_mult2_deconv 0x00000027
+#define sah_insert_pkha_rtn_miller_rabin 0x00000028
+#define sah_insert_pkha_rtn_mod_amodn 0x00000029
+#define sah_insert_pkha_rtn_f2m_amodn 0x8000002A
+/*! @} */
+
+/*! Add a descriptor with two input pointers */
+fsl_shw_return_t sah_add_two_in_desc(uint32_t header,
+ const uint8_t * in1,
+ uint32_t in1_length,
+ const uint8_t * in2,
+ uint32_t in2_length,
+ const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_chain);
+
+/*! Add a descriptor with two 'data' pointers */
+fsl_shw_return_t sah_add_two_d_desc(uint32_t header,
+ const uint8_t * in1,
+ uint32_t in1_length,
+ const uint8_t * in2,
+ uint32_t in2_length,
+ const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_chain);
+
+/*! Add a descriptor with an input and key pointer */
+fsl_shw_return_t sah_add_in_key_desc(uint32_t header,
+ const uint8_t * in1,
+ uint32_t in1_length,
+ fsl_shw_sko_t * key_info,
+ const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_chain);
+
+/*! Add a descriptor with two key pointers */
+fsl_shw_return_t sah_add_key_key_desc(uint32_t header,
+ fsl_shw_sko_t * key_info1,
+ fsl_shw_sko_t * key_info2,
+ const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_chain);
+
+/*! Add a descriptor with two output pointers */
+fsl_shw_return_t sah_add_two_out_desc(uint32_t header,
+ uint8_t * out1,
+ uint32_t out1_length,
+ uint8_t * out2,
+ uint32_t out2_length,
+ const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_chain);
+
+/*! Add a descriptor with an input and output pointer */
+fsl_shw_return_t sah_add_in_out_desc(uint32_t header,
+ const uint8_t * in, uint32_t in_length,
+ uint8_t * out, uint32_t out_length,
+ const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_chain);
+
+/*! Add a descriptor with an input and key output pointer */
+fsl_shw_return_t sah_add_in_keyout_desc(uint32_t header,
+ const uint8_t * in, uint32_t in_length,
+ fsl_shw_sko_t * key_info,
+ const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_chain);
+
+/*! Add a descriptor with a key and an output pointer */
+fsl_shw_return_t sah_add_key_out_desc(uint32_t header,
+ const fsl_shw_sko_t * key_info,
+ uint8_t * out, uint32_t out_length,
+ const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_chain);
+
+/*! Add a descriptor with an output and input pointer */
+fsl_shw_return_t sah_add_out_in_desc(uint32_t header,
+ uint8_t * out, uint32_t out_length,
+ const uint8_t * in, uint32_t in_length,
+ const sah_Mem_Util * mu,
+ sah_Head_Desc ** desc_chain);
+
+/*! Verify that supplied User Context Object is valid */
+fsl_shw_return_t sah_validate_uco(fsl_shw_uco_t * uco);
+
+#endif /* SF_UTIL_H */
+
+/* End of sf_util.h */