1 /**************************************************************************/ 2 /* */ 3 /* Copyright (c) Microsoft Corporation. All rights reserved. */ 4 /* */ 5 /* This software is licensed under the Microsoft Software License */ 6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8 /* and in the root directory of this software. */ 9 /* */ 10 /**************************************************************************/ 11 12 13 /**************************************************************************/ 14 /**************************************************************************/ 15 /** */ 16 /** NetX Crypto Component */ 17 /** */ 18 /** Crypto */ 19 /** */ 20 /**************************************************************************/ 21 /**************************************************************************/ 22 23 24 /**************************************************************************/ 25 /* */ 26 /* COMPONENT DEFINITION RELEASE */ 27 /* */ 28 /* nx_crypto.h PORTABLE C */ 29 /* 6.1.11 */ 30 /* AUTHOR */ 31 /* */ 32 /* Timothy Stapko, Microsoft Corporation */ 33 /* */ 34 /* DESCRIPTION */ 35 /* */ 36 /* This file defines the NetX Security Encryption component. */ 37 /* */ 38 /* RELEASE HISTORY */ 39 /* */ 40 /* DATE NAME DESCRIPTION */ 41 /* */ 42 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */ 43 /* 09-30-2020 Timothy Stapko Modified comment(s), */ 44 /* disabled unaligned access */ 45 /* by default, and added */ 46 /* crypto standalone support, */ 47 /* resulting in version 6.1 */ 48 /* 06-02-2021 Bhupendra Naphade Modified comment(s), */ 49 /* Renamed FIPS symbol and */ 50 /* fips memory functions, */ 51 /* resulting in version 6.1.7 */ 52 /* 01-31-2022 Timothy Stapko Modified comment(s), */ 53 /* added missing symbol, */ 54 /* resulting in version 6.1.10 */ 55 /* 04-25-2022 Yuxin Zhou Modified comment(s), */ 56 /* cleaned up memory functions,*/ 57 /* resulting in version 6.1.11 */ 58 /* */ 59 /**************************************************************************/ 60 61 #ifndef _NX_CRYPTO_H_ 62 #define _NX_CRYPTO_H_ 63 64 /* Determine if a C++ compiler is being used. If so, ensure that standard 65 C is used to process the API information. */ 66 #ifdef __cplusplus 67 68 /* Yes, C++ compiler is present. Use standard C. */ 69 extern "C" { 70 71 #endif 72 73 /* Default to disabling standalone use of nx_crypto. To use nx_crypto in 74 standalone define NX_CRYPTO_STANDALONE_ENABLE*/ 75 /* 76 #define NX_CRYPTO_STANDALONE_ENABLE 77 */ 78 79 #ifndef NX_CRYPTO_STANDALONE_ENABLE 80 #include "nx_api.h" 81 #else 82 #include "nx_crypto_port.h" 83 #endif 84 85 #ifdef NX_LITTLE_ENDIAN 86 #define NX_CRYPTO_LITTLE_ENDIAN 1 87 #endif 88 89 /* Deprecated definition, provided only for backward compatibility */ 90 #ifdef NX_CRYPTO_FIPS 91 #ifndef NX_CRYPTO_SELF_TEST 92 #define NX_CRYPTO_SELF_TEST 93 #endif /* NX_CRYPTO_SELF_TEST */ 94 #endif /* NX_CRYPTO_FIPS */ 95 96 #include "nx_crypto_const.h" 97 #include <stdlib.h> 98 #include <string.h> 99 100 101 /* Configuration macro: enable curve25519 and curve448. */ 102 /* #define NX_CRYPTO_ENABLE_CURVE25519_448 */ 103 104 #ifdef NX_CRYPTO_SELF_TEST 105 106 VOID *_nx_crypto_self_test_memcpy(void *dest, const void *src, size_t size); 107 VOID *_nx_crypto_self_test_memmove(void *dest, const void *src, size_t size); 108 VOID *_nx_crypto_self_test_memset(void *dest, int value, size_t size); 109 int _nx_crypto_self_test_memcmp(const void *dest, const void *src, size_t size); 110 UINT _nx_crypto_drbg(UINT bits, UCHAR *result); 111 112 #ifndef NX_CRYPTO_RBG 113 #define NX_CRYPTO_RBG _nx_crypto_drbg 114 #endif 115 116 #define NX_CRYPTO_CONST 117 118 #else /* NON NX_CRYPTO_SELF_TEST build. */ 119 120 #ifndef NX_CRYPTO_RBG 121 #define NX_CRYPTO_RBG _nx_crypto_huge_number_rbg 122 #endif 123 124 #define NX_CRYPTO_CONST const 125 #endif 126 127 #ifdef _NX_CRYPTO_INITIALIZE_ 128 VOID *(*volatile _nx_crypto_memset_ptr)(void *dest, int value, size_t size) = memset; 129 VOID *(*volatile _nx_crypto_memcpy_ptr)(void *dest, const void *src, size_t size) = memcpy; 130 #else 131 extern VOID *(*volatile _nx_crypto_memset_ptr)(void *dest, int value, size_t size); 132 extern VOID *(*volatile _nx_crypto_memcpy_ptr)(void *dest, const void *src, size_t size); 133 #endif 134 135 #ifndef NX_CRYPTO_MEMCPY 136 #define NX_CRYPTO_MEMCPY _nx_crypto_memcpy_ptr 137 #endif 138 139 #ifndef NX_CRYPTO_MEMMOVE 140 #define NX_CRYPTO_MEMMOVE memmove 141 #endif 142 143 #ifndef NX_CRYPTO_MEMSET 144 #define NX_CRYPTO_MEMSET _nx_crypto_memset_ptr 145 #endif 146 147 #ifndef NX_CRYPTO_MEMCMP 148 #define NX_CRYPTO_MEMCMP memcmp 149 #endif 150 151 #if !defined(NX_CRYPTO_CHANGE_ULONG_ENDIAN) && defined(NX_CHANGE_ULONG_ENDIAN) 152 #define NX_CRYPTO_CHANGE_ULONG_ENDIAN NX_CHANGE_ULONG_ENDIAN 153 #endif 154 155 #if !defined(NX_CRYPTO_CHANGE_USHORT_ENDIAN) && defined(NX_CHANGE_USHORT_ENDIAN) 156 #define NX_CRYPTO_CHANGE_USHORT_ENDIAN NX_CHANGE_USHORT_ENDIAN 157 #endif 158 159 #ifndef NX_CRYPTO_INTEGRITY_TEST 160 #define NX_CRYPTO_INTEGRITY_TEST 161 #endif 162 163 164 #ifndef NX_CRYPTO_RAND 165 #ifndef NX_CRYPTO_STANDALONE_ENABLE 166 #define NX_CRYPTO_RAND NX_RAND 167 #else 168 #define NX_CRYPTO_RAND rand 169 #endif 170 #endif 171 172 173 #ifndef NX_CRYPTO_SRAND 174 #ifndef NX_CRYPTO_STANDALONE_ENABLE 175 #define NX_CRYPTO_SRAND NX_SRAND 176 #else 177 #define NX_CRYPTO_SRAND srand 178 #endif 179 #endif 180 181 #ifdef NX_CRYPTO_SELF_TEST 182 183 /* NX_CRYPTO_SELF_TEST build forces NX_SECURE_KEY_CLEAR to be set */ 184 #ifndef NX_SECURE_KEY_CLEAR 185 #define NX_SECURE_KEY_CLEAR 186 #endif /* NX_SECURE_KEY_CLEAR */ 187 188 #ifdef _NX_CRYPTO_INITIALIZE_ 189 unsigned int _nx_crypto_library_state = NX_CRYPTO_LIBRARY_STATE_UNINITIALIZED; 190 #else 191 extern unsigned int _nx_crypto_library_state; 192 #endif 193 194 #define NX_CRYPTO_STATE_CHECK \ 195 if((_nx_crypto_library_state & (NX_CRYPTO_LIBRARY_STATE_OPERATIONAL | NX_CRYPTO_LIBRARY_STATE_POST_IN_PROGRESS)) == 0) \ 196 return(NX_CRYPTO_INVALID_LIBRARY); 197 198 #else 199 200 #define NX_CRYPTO_STATE_CHECK 201 #endif /* NX_CRYPTO_SELF_TEST */ 202 203 /* Keep functions not used which is compiler specific. */ 204 #ifndef NX_CRYPTO_KEEP 205 #define NX_CRYPTO_KEEP 206 #endif /* NX_CRYPTO_KEEP */ 207 208 #ifndef NX_CRYPTO_HARDWARE_RAND_INITIALIZE 209 #define NX_CRYPTO_HARDWARE_RAND_INITIALIZE 210 #endif /* NX_CRYPTO_HARDWARE_RAND_INITIALIZE */ 211 212 #ifndef NX_CRYPTO_PARAMETER_NOT_USED 213 #define NX_CRYPTO_PARAMETER_NOT_USED(p) ((void)(p)) 214 #endif /* NX_CRYPTO_PARAMETER_NOT_USED */ 215 216 /* Note that both input and output packets are prepared by the 217 caller. For encryption/decryption operations, the callee shall 218 use the output buffer for encrypted or decrypted data. For 219 authentication operations, the callee shall use the output 220 buffer for the digest. 221 'crypto_metadata' Pointer to a storage space managed by the underlying crypto method. 222 The content of this block is defined by each sa in use. 223 'crypto_metadata_size' is the size of the crypto context block, in bytes. */ 224 typedef struct NX_CRYPTO_INFO_STRUCT 225 { 226 USHORT nx_crypto_op; /* Encrypt, Decrypt, Authenticate, Verify */ 227 NX_CRYPTO_KEY_SIZE nx_crypto_key_size_in_bits; 228 UCHAR *nx_crypto_key; 229 UCHAR *nx_crypto_iv_ptr; 230 UCHAR *nx_crypto_input; 231 UCHAR *nx_crypto_output; 232 USHORT nx_crypto_input_length_in_byte; 233 USHORT nx_crypto_output_length_in_byte; 234 VOID *nx_crypto_metadata; 235 USHORT nx_crypto_metadata_size; 236 USHORT nx_crypto_algorithm; 237 volatile UINT nx_crypto_status; 238 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status); 239 } NX_CRYPTO_INFO; 240 241 /* Notes on *nx_crypto_operation: 242 The crypto method strcuture contains a function pointer: nx_crypto_operation. 243 244 This function pointer should be set for the crypto method in use. The arguments to this function are: 245 nx_crypto_operation(UINT operation, UINT protocol, NX_CRYPTO_METHOD* crypto_method_ptr, NX_PACKET *packet_ptr) 246 247 ESP/AH process invokes this function, specifies the operation to perform (encrypt, decrypt, 248 digest computation, and the packet (data) to be performed on. 249 250 This routine shall return SUCCESS/FAILURE on return. */ 251 252 typedef struct NX_CRYPTO_METHOD_STRUCT 253 { 254 /* Name of the algorithm. For example: 255 NX_CRYPTO_ENCRYPTOIN_3DES_CBC or NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_96. 256 Refer to nx_crypto.h for a list of symbols used in this field. User may 257 wish to extend the list. */ 258 UINT nx_crypto_algorithm; 259 260 /* Size of the key, in bits. */ 261 NX_CRYPTO_KEY_SIZE nx_crypto_key_size_in_bits; 262 263 /* Size of the IV block, in bits. This is used for encryption. */ 264 USHORT nx_crypto_IV_size_in_bits; 265 266 /* Size of the ICV block, in bits. This is used for authentication. */ 267 USHORT nx_crypto_ICV_size_in_bits; 268 269 /* Size of the crypto block, in bytes. */ 270 ULONG nx_crypto_block_size_in_bytes; 271 272 /* Size of the meta data area, in bytes. */ 273 ULONG nx_crypto_metadata_area_size; 274 275 /* nx_cyrpto_init function initializes the underlying crypto 276 method with the "key" information. If the crytpo method requires 277 the storage of additional session information, this nx_crypto_init 278 routine must allocate memory as needed, and pass a handle 279 back to the caller in the parameter "handler". When NetX IPSec 280 invokes this crypto method, the handle is passed to crypto operation. 281 'crypto_metadata' Pointer to a storage space managed by the underlying crypto method. 282 The content of this block is defined by each sa in use. 283 'crypto_metadata_size' is the size of the crypto context block, in bytes. */ 284 UINT (*nx_crypto_init)(struct NX_CRYPTO_METHOD_STRUCT *method, 285 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits, 286 VOID **handler, 287 VOID *crypto_metadata, 288 ULONG crypto_metadata_size); 289 290 /* When the SA is no longer needed, NetX IPSec calls nx_crypto_cleanup 291 function and passes in the handler, so that the underlying 292 method can clean up the resource, if needed. */ 293 UINT (*nx_crypto_cleanup)(VOID *crypto_metadata); 294 295 /* Function pointer to the actual crypto or hash operation. 296 For crypto operation, this function returns NX_CRYPTO_SUCCESS or 297 appropriate error code. 298 Note that both input and output buffers are prepared by the 299 caller. For encryption/decryption operations, the callee shall 300 use the output buffer for encrypted or decrypted data. For 301 authentication operations, the callee shall use the output 302 buffer for the digest. 303 'crypto_metadata' Pointer to a storage space managed by the underlying crypto method. 304 The content of this block is defined by each sa in use. 305 'crypto_metadata_size' is the size of the crypto context block, in bytes. */ 306 UINT (*nx_crypto_operation)(UINT op, /* Encrypt, Decrypt, Authenticate */ 307 VOID *handler, /* Crypto handler */ 308 struct NX_CRYPTO_METHOD_STRUCT *method, 309 UCHAR *key, 310 NX_CRYPTO_KEY_SIZE key_size_in_bits, 311 UCHAR *input, 312 ULONG input_length_in_byte, 313 UCHAR *iv_ptr, 314 UCHAR *output, 315 ULONG output_length_in_byte, 316 VOID *crypto_metadata, 317 ULONG crypto_metadata_size, 318 VOID *packet_ptr, 319 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status)); 320 } NX_CRYPTO_METHOD; 321 322 /* Define structure for extended usage of output argument in nx_crypto_operation. 323 * Crypto algorithm may return dynamic length of output, such as ECJPAKE.*/ 324 typedef struct NX_CRYPTO_EXTENDED_OUTPUT_STRUCT 325 { 326 327 /* Pointer to output buffer. */ 328 UCHAR *nx_crypto_extended_output_data; 329 330 /* Length of output buffer. */ 331 ULONG nx_crypto_extended_output_length_in_byte; 332 333 /* Actual size of output buffer used. */ 334 ULONG nx_crypto_extended_output_actual_size; 335 } NX_CRYPTO_EXTENDED_OUTPUT; 336 337 /* This defines the maximum number of cipher roles for a given ciphersuite. */ 338 #define NX_CRYPTO_MAX_CIPHER_ROLES 8 339 340 /* Structure to associate a NX_CRYPTO_METHOD ID with a particular 341 role (defined by the intended application, e.g. TLS, X.509). */ 342 typedef struct NX_CRYPTO_ROLE_ENTRY_STRUCT 343 { 344 /* Crypto method id. */ 345 UINT nx_crypto_role_cipher_id; 346 347 /* Crypto role id. */ 348 UINT nx_crypto_role_id; 349 } NX_CRYPTO_ROLE_ENTRY; 350 351 /* New-style API structures for TLS support. */ 352 typedef struct NX_CRYPTO_CIPHERSUITE_STRUCT 353 { 354 /* IANA-defined ciphersuite identifier (used by TLS). */ 355 USHORT nx_crypto_ciphersuite_id; 356 357 /* Disambiguation ID for overlapping ciphersuite IDs. (e.g. NX_CRYPTO_TLS, NX_CRYPTO_X509). */ 358 USHORT nx_crypto_internal_id; 359 360 /* We need the key size for TLS operations using symmetric key ciphers. For example, 361 unlike RSA and ECC, the AES key size is needed in TLS to calculate key material. 362 For ciphersuites not using a symmetric cipher (e.g. X.509 suites) this should be 0. */ 363 UINT nx_crypto_symmetric_key_size; 364 365 /* Array of cipher IDs and their associated roles. */ 366 NX_CRYPTO_ROLE_ENTRY nx_crypto_ciphers[NX_CRYPTO_MAX_CIPHER_ROLES]; 367 368 /* Bitmap for protocol versions which can use this ciphersuite. */ 369 UINT nx_crypto_version; 370 } NX_CRYPTO_CIPHERSUITE; 371 372 373 /* APIs. */ 374 #define nx_crypto_initialize _nx_crypto_initialize 375 376 UINT _nx_crypto_initialize(VOID); 377 378 #ifdef NX_CRYPTO_SELF_TEST 379 #define nx_crypto_method_self_test _nx_crypto_method_self_test 380 #define nx_crypto_module_state_get _nx_crypto_module_state_get 381 /* int nx_crypto_rand(void); */ 382 383 INT _nx_crypto_method_self_test(INT); 384 UINT _nx_crypto_module_state_get(VOID); 385 #endif 386 387 388 #ifdef __cplusplus 389 } 390 #endif 391 392 393 #endif /* _NX_CRYPTO_H_ */ 394 395