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