1 /* 2 * Copyright (c) 2017-2023, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 /** ============================================================================ 33 * @file CryptoKey.h 34 * 35 * @brief The CryptoKey type is an opaque representation of a cryptographic key. 36 * 37 * @warning This is a beta API. It may change in future releases. 38 * 39 * Cryptographic keying material may be stored on an embedded system multiple ways. 40 * - plaintext: in plaintext in flash or RAM 41 * - key store: in a dedicated hardware database whose entries can not be directly 42 * read out. 43 * 44 * Each storage option requires different approaches to handling the keying material 45 * when performing a crypto operation. In order to separate these concerns from 46 * the API of the various crypto drivers available with TI-RTOS, the CryptoKey 47 * type abstracts away from these details. It does not contain any cryptographic 48 * keying material itself but instead contains the details necessary for drivers to use the 49 * keying material. The driver implementation handles preparing and moving the keying 50 * material as necessary to perform the desired crypto operation. 51 * 52 * The same CryptoKey may be passed to crypto APIs of different modes subject to 53 * restrictions placed on the key by their storage types. Plaintext keys may be used 54 * without restriction while key store keys have their permitted uses 55 * restricted when the keying material is loaded. 56 * These restrictions are specified in a CryptoKey_SecurityPolicy that is device-specific 57 * and depends on the hardware capability of the device. 58 * 59 * An application should never access a field within a CryptoKey struct itself. 60 * Where needed, helper functions are provided to do so. 61 * 62 * Before using a CryptoKey in another crypto API call, it must be initialized 63 * with a call to one of the initialization functions. 64 * - CryptoKeyPlaintext_initKey() 65 * - CryptoKeyPlaintext_initBlankKey() 66 * - KeyStore_PSA_initKey() 67 * - KeyStore_PSA_initBlankKey() 68 * 69 * The keystore CryptoKeys may be used to load a key into a key store after 70 * its respective _init call. 71 * 72 * CryptoKeys can be initialized "blank", without keying material but with an empty buffer 73 * or key store entry, to encode the destination of a key to be created in the 74 * future. This way, keys may be generated securely within a key store 75 * for example and never even be stored in RAM temporarily. 76 * 77 * Not all devices support all CryptoKey functionality. This is hardware-dependent. 78 * 79 */ 80 81 #ifndef ti_drivers_cryptoutils_cyptokey_CryptoKey__include 82 #define ti_drivers_cryptoutils_cyptokey_CryptoKey__include 83 84 #include <stdint.h> 85 #include <stdbool.h> 86 87 #ifdef __cplusplus 88 extern "C" { 89 #endif 90 91 /*! 92 93 */ 94 95 /** 96 * @defgroup CryptoKey_CONTROL Status codes 97 * These CryptoKey macros are reservations for CryptoKey.h 98 * @{ 99 */ 100 101 /*! 102 * Common CryptoKey_control status code reservation offset. 103 * CryptoKey driver implementations should offset status codes with 104 * CryptoKey_STATUS_RESERVED growing negatively. 105 * 106 * Example implementation specific status codes: 107 * @code 108 * #define CryptoKeyXYZ_STATUS_ERROR0 CryptoKey_STATUS_RESERVED - 0 109 * #define CryptoKeyXYZ_STATUS_ERROR1 CryptoKey_STATUS_RESERVED - 1 110 * #define CryptoKeyXYZ_STATUS_ERROR2 CryptoKey_STATUS_RESERVED - 2 111 * @endcode 112 */ 113 #define CryptoKey_STATUS_RESERVED (-32) 114 115 /** 116 * @defgroup CryptoKey_STATUS Status Codes 117 * CryptoKey_STATUS_* macros are general status codes returned by CryptoKey_control() 118 * @{ 119 * @ingroup CryptoKey_CONTROL 120 */ 121 122 /*! 123 * @brief Successful status code 124 * 125 * CryptoKey_control() returns CryptoKey_STATUS_SUCCESS if the control code was executed 126 * successfully. 127 */ 128 #define CryptoKey_STATUS_SUCCESS (0) 129 130 /*! 131 * @brief Generic error status code 132 * 133 * CryptoKey_control() returns CryptoKey_STATUS_ERROR if the control code was not executed 134 * successfully. 135 */ 136 #define CryptoKey_STATUS_ERROR (-1) 137 138 /*! 139 * @brief Returned if the encoding of a CryptoKey is not a CryptoKey_Encoding value 140 * 141 * CryptoKey_control() returns CryptoKey_STATUS_ERROR if the control code was not executed 142 * successfully. 143 */ 144 #define CryptoKey_STATUS_UNDEFINED_ENCODING (-2) 145 146 /** @}*/ 147 148 /** @}*/ 149 150 /* 151 * CRYPTOKEY_HSM is being used to mask bit 6 which determines which accelerator to use. 152 * Any encoding that is ORed with CRYPTOKEY_HSM indicates that the HSM is the engine of choice for the operation 153 */ 154 #define CRYPTOKEY_HSM 0x20U 155 156 #define CRYPTOKEY_PLAINTEXT 0x02U 157 #define CRYPTOKEY_BLANK_PLAINTEXT 0x04U 158 #define CRYPTOKEY_KEYSTORE 0x08U 159 #define CRYPTOKEY_BLANK_KEYSTORE 0x10U 160 161 /*! 162 * @brief List of the different types of CryptoKey. 163 * _HSM encodings are only available for select devices, CC27XX. 164 */ 165 typedef uint8_t CryptoKey_Encoding; 166 static const CryptoKey_Encoding CryptoKey_PLAINTEXT = CRYPTOKEY_PLAINTEXT; 167 static const CryptoKey_Encoding CryptoKey_BLANK_PLAINTEXT = CRYPTOKEY_BLANK_PLAINTEXT; 168 static const CryptoKey_Encoding CryptoKey_KEYSTORE = CRYPTOKEY_KEYSTORE; 169 static const CryptoKey_Encoding CryptoKey_BLANK_KEYSTORE = CRYPTOKEY_BLANK_KEYSTORE; 170 static const CryptoKey_Encoding CryptoKey_PLAINTEXT_HSM = CRYPTOKEY_PLAINTEXT | CRYPTOKEY_HSM; 171 172 /*! 173 * @brief Plaintext CryptoKey datastructure. 174 * 175 * This structure contains all the information necessary to access keying material stored 176 * in plaintext form in flash or RAM. 177 */ 178 typedef struct 179 { 180 uint8_t *keyMaterial; 181 uint32_t keyLength; 182 } CryptoKey_Plaintext; 183 184 /*! 185 * @brief Key store CryptoKey datastructure. 186 * 187 * This structure contains all the information necessary to access keying material stored 188 * in a dedicated key store or key database with memory access controls. 189 * The application must ensure that the key attributes struct used to initialize the pointer 190 * #keyAttributes must either be a global variable or it must be available in the context of the 191 * function that makes the call to import the key associated with the same key attribute. 192 * Otherwise, the keyAttributes pointer will point to a location in stack that could be deallocated. 193 */ 194 typedef struct 195 { 196 uint32_t keyLength; 197 uint32_t keyID; 198 void *keyAttributes; 199 } CryptoKey_KeyStore; 200 201 /*! 202 * @brief CryptoKey datastructure. 203 * 204 * This structure contains a CryptoKey_Encoding and one of 205 * - CryptoKey_Plaintext 206 * - CryptoKey_KeyStore 207 */ 208 typedef struct 209 { 210 CryptoKey_Encoding encoding; 211 union 212 { 213 CryptoKey_Plaintext plaintext; 214 CryptoKey_KeyStore keyStore; 215 } u; 216 } CryptoKey; 217 218 /*! 219 * @brief Structure that specifies the restrictions on a CryptoKey 220 * 221 * This structure is device-specific and declared here in incomplete form. 222 * The structure is fully defined in CryptoKeyDEVICE.h. This creates a link-time binding 223 * when using the structure with key store functions. If the instance 224 * of the CryptoKey_SecurityPolicy is kept in a device-specific application-file, 225 * the generic application code may still use references to it despite being 226 * an incomplete type in the generic application file at compile time. 227 */ 228 typedef struct CryptoKey_SecurityPolicy_ CryptoKey_SecurityPolicy; 229 230 /*! 231 * @brief Gets the key type of the CryptoKey 232 * 233 * @param [in] keyHandle Pointer to a CryptoKey 234 * @param [out] keyType Type of the CryptoKey 235 * 236 * @return Returns a status code 237 */ 238 int_fast16_t CryptoKey_getCryptoKeyType(const CryptoKey *keyHandle, CryptoKey_Encoding *keyType); 239 240 /*! 241 * @brief Whether the CryptoKey is 'blank' or represents valid keying material 242 * 243 * @param [in] keyHandle Pointer to a CryptoKey 244 * @param [out] isBlank Whether the CryptoKey is 'blank' or not 245 * 246 * @return Returns a status code 247 */ 248 int_fast16_t CryptoKey_isBlank(const CryptoKey *keyHandle, bool *isBlank); 249 250 /*! 251 * @brief Function to initialize the CryptoKey_SecurityPolicy struct to its defaults 252 * 253 * This will zero-out all fields that cannot be set to safe defaults 254 * 255 * @param [in] policy Pointer to a CryptoKey_SecurityPolicy 256 * 257 * @return Returns a status code 258 */ 259 int_fast16_t CryptoKey_initSecurityPolicy(CryptoKey_SecurityPolicy *policy); 260 261 /*! 262 * @brief Function to verify a secure CryptoKey 263 * 264 * This will check that the key type is valid and verify plaintext key material 265 * is located in non-secure read-access memory. 266 * 267 * @note This function may not be available in all implementations 268 * 269 * @param [in] secureKey Pointer to a CryptoKey struct located in secure memory 270 * 271 * @retval CryptoKey_STATUS_SUCCESS Key passes all verification checks 272 * @retval CryptoKey_STATUS_ERROR Key fails any verification check 273 */ 274 int_fast16_t CryptoKey_verifySecureInputKey(const CryptoKey *secureKey); 275 276 /*! 277 * @brief Function to verify a secure output CryptoKey 278 * 279 * This will check that the key type is valid and verify plaintext key material 280 * is located in non-secure RW-access memory. 281 * 282 * @note This function may not be available in all implementations 283 * 284 * @param [in] secureKey Pointer to a CryptoKey struct located in secure memory 285 * 286 * @retval CryptoKey_STATUS_SUCCESS Key passes all verification checks 287 * @retval CryptoKey_STATUS_ERROR Key fails any verification check 288 */ 289 int_fast16_t CryptoKey_verifySecureOutputKey(const CryptoKey *secureKey); 290 291 /*! 292 * @brief Function to copy and verify a secure input CryptoKey 293 * 294 * This will check that the source CryptoKey struct is located in non-secure 295 * read-access memory, copy the CryptoKey struct from the src to dst, and check 296 * that the key type is valid and verify plaintext key material is located in 297 * non-secure read-access memory. 298 * 299 * @note This function may not be available in all implementations 300 * 301 * @param [out] dst Pointer to the destination CryptoKey struct located in secure memory 302 * @param [in,out] src Pointer to a source CryptoKey struct pointer located in secure memory 303 * which will be updated to point to the destination CryptoKey struct 304 * 305 * @retval CryptoKey_STATUS_SUCCESS Key passes all verification checks 306 * @retval CryptoKey_STATUS_ERROR Key fails any verification check 307 */ 308 int_fast16_t CryptoKey_copySecureInputKey(CryptoKey *dst, const CryptoKey **src); 309 310 /*! 311 * @brief Function to copy and verify a secure output CryptoKey 312 * 313 * This will check that the source CryptoKey struct is located in non-secure 314 * RW-access memory, copy the CryptoKey struct from the src to dst, and check 315 * that the key type is valid and verify plaintext key material is located in 316 * non-secure RW-access memory. 317 * 318 * @note This function may not be available in all implementations 319 * 320 * @param [out] dst Pointer to the destination CryptoKey struct located in secure memory 321 * @param [in,out] src Pointer to a source CryptoKey struct pointer located in secure memory 322 * which will be updated to point to the destination CryptoKey struct 323 * 324 * @retval CryptoKey_STATUS_SUCCESS Key passes all verification checks 325 * @retval CryptoKey_STATUS_ERROR Key fails any verification check 326 */ 327 int_fast16_t CryptoKey_copySecureOutputKey(CryptoKey *dst, CryptoKey **src); 328 329 #ifdef __cplusplus 330 } 331 #endif 332 333 #endif /* ti_drivers_cryptoutils_cyptokey_CryptoKey__include */ 334