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