summaryrefslogtreecommitdiff
path: root/drivers/mxc/security/rng/include/shw_driver.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/security/rng/include/shw_driver.h')
-rw-r--r--drivers/mxc/security/rng/include/shw_driver.h2971
1 files changed, 2971 insertions, 0 deletions
diff --git a/drivers/mxc/security/rng/include/shw_driver.h b/drivers/mxc/security/rng/include/shw_driver.h
new file mode 100644
index 000000000000..d529b4fe6e6b
--- /dev/null
+++ b/drivers/mxc/security/rng/include/shw_driver.h
@@ -0,0 +1,2971 @@
+/*
+ * Copyright (C) 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+#ifndef SHW_DRIVER_H
+#define SHW_DRIVER_H
+
+/* This is a Linux flag meaning 'compiling kernel code'... */
+#ifndef __KERNEL__
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <memory.h>
+#include <stdio.h>
+#else
+#include "../../sahara2/include/portable_os.h"
+#endif /* __KERNEL__ */
+
+#include "../../sahara2/include/fsl_platform.h"
+
+/*! @file shw_driver.h
+ *
+ * @brief Header file to use the SHW driver.
+ *
+ * The SHW driver is used in two modes: By a user, from the FSL SHW API in user
+ * space, which goes through /dev/fsl_shw to make open(), ioctl(), and close()
+ * calls; and by other kernel modules/drivers, which use the FSL SHW API, parts
+ * of which are supported directly by the SHW driver.
+ *
+ * Testing is performed by using the apitest and kernel api test routines
+ * developed for the Sahara2 driver.
+ */
+/*#define DIAG_SECURITY_FUNC*/
+/*! Perform a security function. */
+#define SHW_IOCTL_REQUEST 21
+
+/* 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)
+
+
+/*!
+ * This is part of the IOCTL request type passed between kernel and user space.
+ * It is added to #SHW_IOCTL_REQUEST to generate the actual value.
+ */
+typedef enum shw_user_request_t {
+ SHW_USER_REQ_REGISTER_USER, /*!< Initialize user-kernel discussion. */
+ SHW_USER_REQ_DEREGISTER_USER, /*!< Terminate user-kernel discussion. */
+ SHW_USER_REQ_GET_RESULTS, /*!< Get information on outstanding
+ results. */
+ SHW_USER_REQ_GET_CAPABILITIES, /*!< Get information on hardware support. */
+ SHW_USER_REQ_GET_RANDOM, /*!< Get random data from RNG. */
+ SHW_USER_REQ_ADD_ENTROPY, /*!< Add entropy to hardware RNG. */
+ SHW_USER_REQ_DROP_PERMS, /*!< Diminish the permissions of a block of
+ secure memory */
+ SHW_USER_REQ_SSTATUS, /*!< Check the status of a block of secure
+ memory */
+ SHW_USER_REQ_SFREE, /*!< Free a block of secure memory */
+ SHW_USER_REQ_SCC_ENCRYPT, /*!< Encrypt a region of user-owned secure
+ memory */
+ SHW_USER_REQ_SCC_DECRYPT, /*!< Decrypt a region of user-owned secure
+ memory */
+} shw_user_request_t;
+
+
+/*!
+ * @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;
+
+
+/*
+ * 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;
+
+
+/******************************************************************************
+ * 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.
+ */
+/* REQ-FSLSHW-ERR-001 */
+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,
+} 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;
+
+
+/* REQ-FSLSHW-PINTFC-COA-HCO-001 */
+/*!
+ * Flags which control a Hash operation.
+ */
+typedef enum fsl_shw_hash_ctx_flags_t
+{
+ FSL_HASH_FLAGS_INIT = 0x01, /*!< Context is empty. Hash is started
+ from scratch, with a message-processed
+ count of zero. */
+ FSL_HASH_FLAGS_SAVE = 0x02, /*!< 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 = 0x04, /*!< Place context into hardware before
+ hashing. */
+ FSL_HASH_FLAGS_FINALIZE = 0x08, /*!< 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_USE_SECRET_KEY = 8, /*!< Use device-unique key. Not always
+ available. */
+ FSL_SKO_KEY_SW_KEY = 16, /*!< Clear key can be provided to the user */
+ FSL_SKO_KEY_SELECT_PF_KEY = 32, /*!< Internal flag to show that this key
+ references one of the hardware keys, and
+ its value is in pf_key. */
+} 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 = 0x10, /**< 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;
+
+
+/**
+ * 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;
+
+
+/**
+ * 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;
+
+
+/**
+ * A work type associated with a work/result queue request.
+ */
+typedef enum shw_work_type_t
+{
+ SHW_WORK_GET_RANDOM = 1, /**< fsl_shw_get_random() request. */
+ SHW_WORK_ADD_RANDOM, /**< fsl_shw_add_entropy() request. */
+} shw_work_type_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;
+
+/*!
+ * 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 = 1, /*!< ECB mode */
+ FSL_SHW_CYPHER_MODE_CBC = 2, /*!< 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;
+
+/*
+ * Structure passed during user ioctl() calls to manage data stored in secure
+ * partitions.
+ */
+
+typedef struct scc_region_t {
+ uint32_t partition_base; /*!< Base address of partition */
+ uint32_t offset; /*!< Byte offset into partition */
+ uint32_t length; /*!< Number of bytes in request */
+ uint8_t *black_data; /*!< Address of cipher text */
+ uint64_t owner_id; /*!< user's secret */
+ fsl_shw_cypher_mode_t cypher_mode; /*!< ECB or CBC */
+ uint32_t IV[4]; /*!< IV for CBC mode */
+} scc_region_t;
+
+/******************************************************************************
+ * Data Structures
+ *****************************************************************************/
+
+/**
+ * Initialization Object
+ */
+typedef struct fsl_sho_ibo
+{
+} fsl_sho_ibo_t;
+
+
+/**
+ * Common Entry structure for work queues, results queues.
+ */
+typedef struct shw_queue_entry_t {
+ struct shw_queue_entry_t* next; /**< Next entry in queue. */
+ struct fsl_shw_uco_t* user_ctx; /**< Associated user context. */
+ uint32_t flags; /**< User context flags at time of request. */
+ void (*callback)(struct fsl_shw_uco_t* uco); /**< Any callback request. */
+ uint32_t user_ref; /**< User's reference for this request. */
+ fsl_shw_return_t code; /**< FSL SHW result of this operation. */
+ uint32_t detail1; /**< Any extra error info. */
+ uint32_t detail2; /**< More any extra error info. */
+ void* user_mode_req; /**< Pointer into user space. */
+ uint32_t (*postprocess)(struct shw_queue_entry_t* q); /**< (internal)
+ function to call
+ when this operation
+ completes.
+ */
+} shw_queue_entry_t;
+
+
+/**
+ * A queue. Fields must be initialized to NULL before use.
+ */
+typedef struct shw_queue_t
+{
+ struct shw_queue_entry_t* head; /**< First entry in queue. */
+ struct shw_queue_entry_t* tail; /**< Last entry. */
+} shw_queue_t;
+
+
+/**
+ * Secure Partition information
+ */
+typedef struct fsl_shw_spo_t
+{
+ uint32_t user_base;
+ void* kernel_base;
+ struct fsl_shw_spo_t* next;
+} fsl_shw_spo_t;
+
+
+/* REQ-FSLSHW-PINTFC-COA-UCO-001 */
+/**
+ * User Context Object
+ */
+typedef struct fsl_shw_uco_t
+{
+ int openfd; /**< user-mode file descriptor */
+ 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 result pool */
+#ifdef __KERNEL__
+ shw_queue_t 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 */
+#endif
+ struct fsl_shw_uco_t* next; /**< To allow user-mode chaining of contexts,
+ for signalling and in kernel, to link user
+ contexts. */
+ fsl_shw_pf_key_t wrap_key; /*!< What key for ciphering T */
+} fsl_shw_uco_t;
+
+
+/* REQ-FSLSHW-PINTFC-API-GEN-006 ?? */
+/**
+ * Result object
+ */
+typedef struct fsl_shw_result_t
+{
+ uint32_t user_ref; /**< User's reference at time of request. */
+ fsl_shw_return_t code; /**< Return code from request. */
+ uint32_t detail1; /**< Extra error info. Unused in SHW driver. */
+ uint32_t detail2; /**< Extra error info. Unused in SHW driver. */
+ void* user_req; /**< Pointer to original user request. */
+} 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-FSLSHW-PINTFC-COA-SKO-001 */
+/**
+ * Secret Key Context Object
+ */
+typedef struct fsl_shw_sko_t
+{
+ uint32_t flags; /**< Flags from #fsl_shw_sym_ctx_flags_t. */
+ fsl_shw_key_alg_t algorithm; /**< Algorithm for this key. */
+ key_userid_t userid; /**< User's identifying value for Black key. */
+ uint32_t handle; /**< Reference in SCC driver for Red key. */
+ uint16_t key_length; /**< Length of stored key, in bytes. */
+ uint8_t key[64]; /**< Bytes of stored key. */
+ struct fsl_shw_kso_t* keystore; /**< If present, key is in keystore */
+ fsl_shw_pf_key_t pf_key; /*!< What key to select for use when this key
+ is doing ciphering. If FSL_SHW_PF_KEY_PRG
+ or FSL_SHW_PF_KEY_PRG_IIM is the value, then
+ a 'present' or 'established' key will be
+ programed into the PK. */
+} fsl_shw_sko_t;
+
+
+/* REQ-FSLSHW-PINTFC-COA-CO-001 */
+/**
+ * Platform Capability Object
+ *
+ * Pointer to this structure is returned by fsl_shw_get_capabilities() and
+ * queried with the various fsl_shw_pco_() functions.
+ */
+typedef struct fsl_shw_pco_t
+{
+ int api_major; /**< Major version number for API. */
+ int api_minor; /**< Minor version number for API. */
+ int driver_major; /**< Major version of some driver. */
+ int driver_minor; /**< Minor version of some driver. */
+ unsigned sym_algorithm_count; /**< Number of sym_algorithms. */
+ fsl_shw_key_alg_t* sym_algorithms; /**< Pointer to array. */
+ unsigned sym_mode_count; /**< Number of sym_modes. */
+ fsl_shw_sym_mode_t* sym_modes; /**< Pointer to array. */
+ unsigned hash_algorithm_count; /**< Number of hash_algorithms. */
+ fsl_shw_hash_alg_t* hash_algorithms; /**< Pointer to array */
+ 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 scc_info {
+ 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 scc2_info {
+ int partition_size_bytes; /**< Number of bytes in each partition */
+ int partition_count; /**< Number of partitions on this platform */
+ } scc2_info;
+ } u;
+} fsl_shw_pco_t;
+
+
+/* REQ-FSLSHW-PINTFC-COA-HCO-001 */
+/**
+ * Hash Context Object
+ */
+typedef struct fsl_shw_hco_t /* fsl_shw_hash_context_object */
+{
+ fsl_shw_hash_alg_t algorithm; /**< Algorithm for this context. */
+ uint32_t flags; /**< Flags from
+ #fsl_shw_hash_ctx_flags_t. */
+ uint8_t digest_length; /**< hash result length in bytes */
+ uint8_t context_length; /**< Context length in bytes */
+ uint8_t context_register_length; /**< in bytes */
+ uint32_t context[9]; /**< largest digest + msg size */
+} fsl_shw_hco_t;
+
+
+/* REQ-FSLSHW-PINTFC-COA-HCO-001 */
+/**
+ * HMAC Context Object
+ */
+typedef struct fsl_shw_hmco_t /* fsl_shw_hmac_context_object */
+{
+ fsl_shw_hash_alg_t algorithm; /**< Hash algorithm for the HMAC. */
+ uint32_t flags; /**< Flags from
+ #fsl_shw_hmac_ctx_flags_t. */
+ 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-FSLSHW-PINTFC-COA-SCCO-001 */
+/**
+ * Symmetric Crypto Context Object Context Object
+ */
+typedef struct fsl_shw_scco_t
+{
+ uint32_t flags; /**< Flags from #fsl_shw_sym_ctx_flags_t. */
+ unsigned block_size_bytes; /**< Both block and ctx size */
+ fsl_shw_sym_mode_t mode; /**< Symmetric mode for this context. */
+ /* Could put modulus plus 16-octet context in union with arc4
+ sbox+ptrs... */
+ fsl_shw_ctr_mod_t modulus_exp; /**< Exponent value for CTR modulus */
+ uint8_t context[8]; /**< Stored context. Large enough
+ for 3DES. */
+} 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;
+
+
+/**
+ * Common header in request structures between User-mode API and SHW driver.
+ */
+struct shw_req_header {
+ uint32_t flags; /**< Flags - from user-mode context. */
+ uint32_t user_ref; /**< Reference - from user-mode context. */
+ fsl_shw_return_t code; /**< Result code for operation. */
+};
+
+/**
+ * Used by user-mode API to retrieve completed non-blocking results in
+ * SHW_USER_REQ_GET_RESULTS ioctl().
+ */
+struct results_req {
+ struct shw_req_header hdr; /**< Boilerplate. */
+ unsigned requested; /**< number of results requested, */
+ unsigned actual; /**< number of results obtained. */
+ fsl_shw_result_t *results; /**< pointer to memory to hold results. */
+};
+
+
+/**
+ * Used by user-mode API to retrieve hardware capabilities in
+ * SHW_USER_REQ_GET_CAPABILITIES ioctl().
+ */
+struct capabilities_req {
+ struct shw_req_header hdr; /**< Boilerplate. */
+ unsigned size; /**< Size, in bytes, capabilities. */
+ fsl_shw_pco_t* capabilities; /**< Place to copy out the info. */
+};
+
+
+/**
+ * Used by user-mode API to get a random number
+ */
+struct get_random_req {
+ struct shw_req_header hdr; /**< Boilerplate. */
+ unsigned size; /**< Size, in bytes, of random. */
+ uint8_t* random; /**< Place to copy out the random number. */
+};
+
+
+/**
+ * Used by API to add entropy to a random number generator
+ */
+struct add_entropy_req {
+ struct shw_req_header hdr; /**< Boilerplate. */
+ unsigned size; /**< Size, in bytes, of entropy. */
+ uint8_t* entropy; /**< Location of the entropy to be added. */
+};
+
+
+/******************************************************************************
+ * External variables
+ *****************************************************************************/
+#ifdef __KERNEL__
+extern os_lock_t shw_queue_lock;
+
+extern fsl_shw_uco_t* user_list;
+#endif
+
+
+/******************************************************************************
+ * 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) \
+do { \
+ *(pcmajor) = (pcobject)->api_major; \
+ *(pcminor) = (pcobject)->api_minor; \
+} while (0)
+
+
+/**
+ * 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) \
+do { \
+ *(pcmajor) = (pcobject)->driver_major; \
+ *(pcminor) = (pcobject)->driver_minor; \
+} while (0)
+
+
+/**
+ * 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) \
+do { \
+ *(pcalgorithms) = (pcobject)->sym_algorithms; \
+ *(pcacount) = (pcobject)->sym_algorithm_count; \
+} while (0)
+
+
+/**
+ * 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) \
+do { \
+ *(gsmodes) = (pcobject)->sym_modes; \
+ *(gsacount) = (pcobject)->sym_mode_count; \
+} while (0)
+
+
+/**
+ * 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) \
+do { \
+ *(gsalgorithms) = (pcobject)->hash_algorithms; \
+ *(gsacount) = (pcobject)->hash_algorithm_count; \
+} while (0)
+
+
+/**
+ * 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.
+ */
+#if defined(FSL_HAVE_DRYICE) && defined(__KERNEL__)
+#define fsl_shw_pco_check_sym_supported(pcobject, pcalg, pcmode) \
+ ((pcobject)->sym_support[pcalg][pcmode])
+#else
+#define fsl_shw_pco_check_sym_supported(pcobject, pcalg, pcmode) \
+ 0
+#endif
+
+/**
+ * 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) \
+ 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.
+ */
+#if defined(FSL_HAVE_DRYICE) && defined(__KERNEL__)
+#define fsl_shw_pco_check_black_key_supported(pcobject) \
+ 1
+#else
+#define fsl_shw_pco_check_black_key_supported(pcobject) \
+ 0
+
+#endif
+
+/*!
+ * Determine whether Programmed Key features are available
+ *
+ * @param pcobject The Platform Capabilities Object to query.
+ *
+ * @return 1 if Programmed Key features are available, otherwise zero.
+ */
+#if defined(FSL_HAVE_DRYICE) && defined(__KERNEL__)
+#define fsl_shw_pco_check_pk_supported(pcobject) \
+ 1
+#else
+#define fsl_shw_pco_check_pk_supported(pcobject) \
+ 0
+#endif
+
+/*!
+ * 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.
+ */
+#if defined(FSL_HAVE_DRYICE) && defined(__KERNEL__)
+#define fsl_shw_pco_check_sw_keys_supported(pcobject) \
+ 1
+#else
+#define fsl_shw_pco_check_sw_keys_supported(pcobject) \
+ 0
+#endif
+
+/*!
+ * Get FSL SHW SCC driver version
+ *
+ * @param pcobject The Platform Capababilities 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 Capababilities 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 Capababilities 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 Capababilities 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 Capababilities 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)->u.scc_info.black_ram_size_blocks; \
+ *(red_size) = (pcobject)->u.scc_info.red_ram_size_blocks; \
+ } else { \
+ *(black_size) = 0; \
+ *(red_size) = 0; \
+ } \
+}
+
+
+/**
+ * Determine whether Secure Partitions are supported
+ *
+ * @param pcobject The Platform Capababilities 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 Capababilities 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)->u.scc2_info.partition_size_bytes) : 0 ) \
+
+
+/**
+ * Get the number of Secure Partitions on this platform
+ *
+ * @param pcobject The Platform Capababilities 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)->u.scc2_info.partition_count) : 0 ) \
+
+
+/*!
+ * 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) \
+{ \
+ fsl_shw_sko_t* skop = skobject; \
+ \
+ skop->algorithm = skalgorithm; \
+ skop->flags = 0; \
+ skop->keystore = NULL; \
+ skop->pf_key = FSL_SHW_PF_KEY_PRG; \
+}
+
+/*!
+ * Initialize a Secret Key Object to use a Platform Key register.
+ *
+ * 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.
+ * @param skhwkey one of the fsl_shw_pf_key_t values.
+ *
+ */
+#define fsl_shw_sko_init_pf_key(skobject,skalgorithm,skhwkey) \
+{ \
+ fsl_shw_sko_t* skop = skobject; \
+ fsl_shw_key_alg_t alg = skalgorithm; \
+ fsl_shw_pf_key_t key = skhwkey; \
+ \
+ skop->algorithm = alg; \
+ if (alg == FSL_KEY_ALG_TDES) { \
+ skop->key_length = 21; \
+ } \
+ skop->keystore = NULL; \
+ skop->flags = FSL_SKO_KEY_SELECT_PF_KEY; \
+ skop->pf_key = key; \
+ if ((key == FSL_SHW_PF_KEY_IIM) || (key == FSL_SHW_PF_KEY_PRG) \
+ || (key == FSL_SHW_PF_KEY_IIM_PRG) \
+ || (key == FSL_SHW_PF_KEY_IIM_RND) \
+ || (key == FSL_SHW_PF_KEY_RND)) { \
+ skop->flags |= FSL_SKO_KEY_ESTABLISHED; \
+ } \
+}
+
+/*!
+ * 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; \
+ int base_size = 35; /* ICV + T' + ALG + LEN + FLAGS */ \
+ \
+ if (kp->flags & FSL_SKO_KEY_SELECT_PF_KEY) { \
+ kl = 21; /* 168-bit 3DES key */ \
+ } \
+ key_blocks = (kl + 7) / 8; \
+ /* Round length up to 3DES block size for CBC mode */ \
+ *(wkeylen) = base_size + 8 * 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 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) \
+do { \
+ fsl_shw_uco_t* uco = ucontext; \
+ \
+ (uco)->pool_size = usize; \
+ (uco)->flags = FSL_UCO_BLOCKING_MODE | FSL_UCO_CONTEXT_CHANGED; \
+ (uco)->openfd = -1; \
+ (uco)->callback = NULL; \
+ (uco)->partition = NULL; \
+ (uco)->wrap_key = FSL_SHW_PF_KEY_IIM; \
+} while (0)
+
+#else /* __KERNEL__ */
+
+#define fsl_shw_uco_init(ucontext, usize) \
+do { \
+ fsl_shw_uco_t* uco = ucontext; \
+ \
+ (uco)->pool_size = usize; \
+ (uco)->flags = FSL_UCO_BLOCKING_MODE | FSL_UCO_CONTEXT_CHANGED; \
+ (uco)->openfd = -1; \
+ (uco)->callback = NULL; \
+ (uco)->wrap_key = FSL_SHW_PF_KEY_IIM; \
+} while (0)
+
+#endif /* __KERNEL__ */
+
+
+/**
+ * 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) \
+do { \
+ fsl_shw_uco_t* uco = ucontext; \
+ \
+ (uco)->user_ref = uref; \
+ (uco)->flags |= FSL_UCO_CONTEXT_CHANGED; \
+} while (0)
+
+
+/**
+ * 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) \
+do { \
+ fsl_shw_uco_t* uco = ucontext; \
+ \
+ (uco)->callback = ucallback; \
+ (uco)->flags |= FSL_UCO_CONTEXT_CHANGED; \
+} while (0)
+
+/**
+ * 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) | FSL_UCO_CONTEXT_CHANGED
+
+
+/**
+ * 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) \
+do { \
+ fsl_shw_uco_t* uco = ucontext; \
+ \
+ (uco)->flags &= ~(uflags); \
+ (uco)->flags |= FSL_UCO_CONTEXT_CHANGED; \
+} while (0)
+
+
+/**
+ * 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
+
+
+
+/* REQ-FSL-SHW-PINTFC-API-BASIC-HASH-004 */
+/**
+ * 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) \
+do { \
+ (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; \
+ } \
+} while (0)
+
+
+/* REQ-FSL-SHW-PINTFC-API-BASIC-HASH-001 */
+/**
+ * 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) \
+do { \
+ memcpy(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]; \
+ } \
+} while (0)
+
+
+/* REQ-FSL-SHW-PINTFC-API-BASIC-HASH-002 */
+/**
+ * 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) \
+do { \
+ *(hcalgorithm) = (hcobject)->algorithm; \
+} while (0)
+
+
+/* REQ-FSL-SHW-PINTFC-API-BASIC-HASH-003 */
+/* REQ-FSL-SHW-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 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) \
+do { \
+ memcpy((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; \
+ } \
+} while (0)
+
+
+/**
+ * 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) \
+do { \
+ 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; \
+} while (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) \
+ memcpy((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) \
+ memcpy(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) \
+do { \
+ if ((sccounter) != NULL) { \
+ memcpy((scobject)->context, sccounter, \
+ (scobject)->block_size_bytes); \
+ } \
+ (scobject)->modulus_exp = scmodulus; \
+} while (0)
+
+
+/**
+ * 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) \
+do { \
+ if ((sccounter) != NULL) { \
+ memcpy(sccounter, (scobject)->context, \
+ (scobject)->block_size_bytes); \
+ } \
+ if ((scmodulus) != NULL) { \
+ *(scmodulus) = (scobject)->modulus_exp; \
+ } \
+} while (0)
+
+
+/**
+ * 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) \
+do { \
+ (acobject)->flags = 0; \
+ (acobject)->mode = (acmode); \
+} while (0)
+
+
+/**
+ * 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) \
+ do { \
+ (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); \
+} while (0)
+
+
+/**
+ * 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).
+ *
+ */
+#define fsl_shw_ccm_nist_format_ctr_and_iv(acobject, act, acad, acq, acN, acQ)\
+ do { \
+ 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 */ \
+ memcpy((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 */ \
+ memcpy((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); \
+ } while (0)
+
+
+/**
+ * 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) \
+ do { \
+ uint64_t Q = acQ; \
+ unsigned i; \
+ uint8_t* qptr = (acobject)->auth_info.CCM_ctx_info.context + 15; \
+ \
+ /* Update the Nonce field field of Block0 */ \
+ memcpy((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 */ \
+ memcpy((acobject)->cipher_ctx_info.context+1, acN, \
+ 15 - (acobject)->q_length); \
+ } while (0)
+
+
+/******************************************************************************
+ * Library functions
+ *****************************************************************************/
+/* REQ-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSLSHW-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-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSLSHW-PINTFC-API-GEN-004 */
+/**
+ * Create an association between the 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-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSLSHW-PINTFC-API-GEN-005 */
+/**
+ * Destroy the association between the 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-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSLSHW-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,
+ unsigned result_size,
+ fsl_shw_result_t results[],
+ unsigned* result_count);
+
+/**
+ * Place a key into a protected location for use only by cryptographic
+ * algorithms.
+ *
+ * This only needs to be used to a) unwrap a key, or b) set up a key which
+ * could be wrapped with a later call to #fsl_shw_extract_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);
+
+
+/**
+ * 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 #fsl_shw_establish_key().
+ *
+ * This function will also release the key (see #fsl_shw_release_key()) so
+ * that it must be re-established before reuse.
+ *
+ * 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);
+
+/*!
+ * 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);
+
+/**
+ * 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);
+
+
+/*
+ * In userspace, partition assignments will be tracked using the user context.
+ * In kernel mode, partition assignments are based on address only.
+ */
+
+/**
+ * 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);
+
+
+/**
+ * Check the status of a block of a 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.
+ * @param status Status of the partition, of type
+ * #fsl_partition_status_t
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+extern fsl_shw_return_t fsl_shw_sstatus(fsl_shw_uco_t* user_ctx,
+ void* address,
+ fsl_shw_partition_status_t* status);
+
+
+/**
+ * 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);
+
+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_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);
+
+
+/* REQ-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSL-SHW-PINTFC-COA-SKO */
+/* REQ-FSL-SHW-PINTFC-COA-SCCO */
+/* REQ-FSLSHW-PINTFC-API-BASIC-SYM-001 */
+/* 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);
+
+
+/* REQ-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSL-SHW-PINTFC-COA-SKO */
+/* REQ-FSL-SHW-PINTFC-COA-SCCO */
+/* 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-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSL-SHW-PINTFC-COA-HCO */
+/* REQ-FSLSHW-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-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSL-SHW-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 addtion, 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-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSLSHW-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-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSLSHW-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-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSLSHW-PINTFC-API-BASIC-RNG-003 */
+/**
+ * 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);
+
+/* REQ-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSL-SHW-PINTFC-COA-SKO */
+/**
+ * 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);
+
+/* REQ-FSL-SHW-PINTFC-COA-UCO */
+/* REQ-FSL-SHW-PINTFC-COA-SKO */
+/**
+ * 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);
+
+/*!
+ * Cause the hardware to create a new random key for secure memory use.
+ *
+ * Have the hardware use the secure hardware random number generator to load a
+ * new secret key into the hardware random key register. It will not be made
+ * active without a call to #fsl_shw_select_pf_key().
+ *
+ * @param user_ctx A user context from #fsl_shw_register_user().
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+#ifdef __KERNEL__
+
+extern fsl_shw_return_t fsl_shw_gen_random_pf_key(fsl_shw_uco_t * user_ctx);
+
+#else
+
+#define fsl_shw_gen_random_pf_key(user_ctx) FSL_RETURN_NO_RESOURCE_S
+
+#endif /* __KERNEL__ */
+
+/*!
+ * 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.
+ */
+#ifdef __KERNEL__
+
+extern fsl_shw_return_t fsl_shw_read_tamper_event(fsl_shw_uco_t * user_ctx,
+ fsl_shw_tamper_t * tamperp,
+ uint64_t * timestampp);
+#else
+
+#define fsl_shw_read_tamper_event(user_ctx,tamperp,timestampp) \
+ FSL_RETURN_NO_RESOURCE_S
+
+#endif /* __KERNEL__ */
+
+/*****************************************************************************
+ *
+ * Functions internal to SHW driver.
+ *
+*****************************************************************************/
+
+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);
+
+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);
+
+
+/*****************************************************************************
+ *
+ * Functions available to other SHW-family drivers.
+ *
+*****************************************************************************/
+
+#ifdef __KERNEL__
+/**
+ * Add an entry to a work/result queue.
+ *
+ * @param pool Pointer to list structure
+ * @param entry Entry to place at tail of list
+ *
+ * @return void
+ */
+inline static void SHW_ADD_QUEUE_ENTRY(shw_queue_t* pool,
+ shw_queue_entry_t* entry)
+{
+ os_lock_context_t lock_context;
+
+ entry->next = NULL;
+ os_lock_save_context(shw_queue_lock, lock_context);
+
+ if (pool->tail != NULL) {
+ pool->tail->next = entry;
+ } else {
+ /* Queue was empty, so this is also the head. */
+ pool->head = entry;
+ }
+ pool->tail = entry;
+
+ os_unlock_restore_context(shw_queue_lock, lock_context);
+
+ return;
+
+
+}
+
+
+/**
+ * Get first entry on the queue and remove it from the queue.
+ *
+ * @return Pointer to first entry, or NULL if none.
+ */
+inline static shw_queue_entry_t* SHW_POP_FIRST_ENTRY(shw_queue_t* queue)
+{
+ shw_queue_entry_t* entry;
+ os_lock_context_t lock_context;
+
+ os_lock_save_context(shw_queue_lock, lock_context);
+
+ entry = queue->head;
+
+ if (entry != NULL) {
+ queue->head = entry->next;
+ entry->next = NULL;
+ /* If this was only entry, clear the tail. */
+ if (queue->tail == entry) {
+ queue->tail = NULL;
+ }
+ }
+
+ os_unlock_restore_context(shw_queue_lock, lock_context);
+
+ return entry;
+}
+
+
+
+/**
+ * Remove an entry from the list.
+ *
+ * If the entry not on the queue, no error will be returned.
+ *
+ * @param pool Pointer to work queue
+ * @param entry Entry to remove from queue
+ *
+ * @return void
+ *
+ */
+inline static void SHW_QUEUE_REMOVE_ENTRY(shw_queue_t* pool,
+ shw_queue_entry_t* entry)
+{
+ os_lock_context_t lock_context;
+
+ os_lock_save_context(shw_queue_lock, lock_context);
+
+ /* Check for quick case.*/
+ if (pool->head == entry) {
+ pool->head = entry->next;
+ entry->next = NULL;
+ if (pool->tail == entry) {
+ pool->tail = NULL;
+ }
+ } else {
+ register shw_queue_entry_t* prev = pool->head;
+
+ /* We know it is not the head, so start looking at entry after head. */
+ while (prev->next) {
+ if (prev->next != entry) {
+ prev = prev->next; /* Try another */
+ continue;
+ } else {
+ /* Unlink from chain. */
+ prev->next = entry->next;
+ entry->next = NULL;
+ /* If last in chain, update tail. */
+ if (pool->tail == entry) {
+ pool->tail = prev;
+ }
+ break;
+ }
+ } /* while */
+ }
+
+ os_unlock_restore_context(shw_queue_lock, lock_context);
+
+ return;
+}
+#endif /* __KERNEL__ */
+
+
+/*****************************************************************************
+ *
+ * Functions available to User-Mode API functions
+ *
+ ****************************************************************************/
+#ifndef __KERNEL__
+
+
+ /**
+ * Sanity checks the user context object fields to ensure that they make some
+ * sense before passing the uco as a parameter.
+ *
+ * @brief Verify the user context object
+ *
+ * @param uco user context object
+ *
+ * @return A return code of type #fsl_shw_return_t.
+ */
+fsl_shw_return_t validate_uco(fsl_shw_uco_t *uco);
+
+
+/**
+ * Initialize a request block to go to the driver.
+ *
+ * @param hdr Pointer to request block header
+ * @param user_ctx Pointer to user's context
+ *
+ * @return void
+ */
+inline static void init_req(struct shw_req_header* hdr,
+ fsl_shw_uco_t* user_ctx)
+{
+ hdr->flags = user_ctx->flags;
+ hdr->user_ref = user_ctx->user_ref;
+ hdr->code = FSL_RETURN_ERROR_S;
+
+ return;
+}
+
+
+/**
+ * Send a request block off to the driver.
+ *
+ * If this is a non-blocking request, then req will be freed.
+ *
+ * @param type The type of request being sent
+ * @param req Pointer to the request block
+ * @param ctx Pointer to user's context
+ *
+ * @return code from driver if ioctl() succeeded, otherwise
+ * FSL_RETURN_INTERNAL_ERROR_S.
+ */
+inline static fsl_shw_return_t send_req(shw_user_request_t type,
+ struct shw_req_header* req,
+ fsl_shw_uco_t* ctx)
+{
+ fsl_shw_return_t ret = FSL_RETURN_INTERNAL_ERROR_S;
+ unsigned blocking = ctx->flags & FSL_UCO_BLOCKING_MODE;
+ int code;
+
+ code = ioctl(ctx->openfd, SHW_IOCTL_REQUEST + type, req);
+
+ if (code == 0) {
+ if (blocking) {
+ ret = req->code;
+ } else {
+ ret = FSL_RETURN_OK_S;
+ }
+ } else {
+#ifdef FSL_DEBUG
+ fprintf(stderr, "SHW: send_req failed with (%d), %s\n", errno,
+ strerror(errno));
+#endif
+ }
+
+ if (blocking) {
+ free(req);
+ }
+
+ return ret;
+}
+
+
+#endif /* no __KERNEL__ */
+
+#if defined(FSL_HAVE_DRYICE)
+/* Some kernel functions */
+void fsl_shw_permute1_bytes(const uint8_t * key, uint8_t * permuted_key,
+ int key_count);
+void fsl_shw_permute1_bytes_to_words(const uint8_t * key,
+ uint32_t * permuted_key, int key_count);
+
+#define PFKEY_TO_STR(key_in) \
+({ \
+ di_key_t key = key_in; \
+ \
+ ((key == DI_KEY_FK) ? "IIM" : \
+ ((key == DI_KEY_PK) ? "PRG" : \
+ ((key == DI_KEY_RK) ? "RND" : \
+ ((key == DI_KEY_FPK) ? "IIM_PRG" : \
+ ((key == DI_KEY_FRK) ? "IIM_RND" : "unk"))))); \
+})
+
+#ifdef DIAG_SECURITY_FUNC
+extern const char *di_error_string(int code);
+#endif
+
+#endif /* HAVE DRYICE */
+
+#endif /* SHW_DRIVER_H */