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 Secure Component */
17 /** */
18 /** Transport Layer Security (TLS) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SECURE_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "nx_secure_crypto_table_self_test.h"
29
30
31 #ifdef NX_SECURE_POWER_ON_SELF_TEST_MODULE_INTEGRITY_CHECK
32
33 static const NX_SECURE_CRYPTO_SELF_TEST nx_crypto_self_test_map[] =
34 {
35 {NX_CRYPTO_ENCRYPTION_AES_CBC, _nx_secure_crypto_method_self_test_aes},
36 {NX_CRYPTO_ENCRYPTION_AES_CTR, _nx_secure_crypto_method_self_test_aes},
37 {NX_CRYPTO_ENCRYPTION_AES_GCM_16, _nx_secure_crypto_method_self_test_aes},
38 {NX_CRYPTO_ENCRYPTION_DES_CBC, _nx_secure_crypto_method_self_test_des},
39 {NX_CRYPTO_ENCRYPTION_3DES_CBC, _nx_secure_crypto_method_self_test_3des},
40 {NX_CRYPTO_HASH_SHA1, _nx_secure_crypto_method_self_test_sha},
41 {NX_CRYPTO_HASH_SHA256, _nx_secure_crypto_method_self_test_sha},
42 {NX_CRYPTO_HASH_SHA384, _nx_secure_crypto_method_self_test_sha},
43 {NX_CRYPTO_HASH_SHA512, _nx_secure_crypto_method_self_test_sha},
44 {NX_CRYPTO_HASH_MD5, _nx_secure_crypto_method_self_test_md5},
45 {NX_CRYPTO_KEY_EXCHANGE_RSA, _nx_secure_crypto_method_self_test_rsa},
46 {NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_96, _nx_secure_crypto_method_self_test_hmac_sha},
47 {NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_160, _nx_secure_crypto_method_self_test_hmac_sha},
48 {NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_256, _nx_secure_crypto_method_self_test_hmac_sha},
49 {NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_384, _nx_secure_crypto_method_self_test_hmac_sha},
50 {NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_512, _nx_secure_crypto_method_self_test_hmac_sha},
51 {NX_CRYPTO_AUTHENTICATION_HMAC_MD5_96, _nx_secure_crypto_method_self_test_hmac_md5},
52 {NX_CRYPTO_AUTHENTICATION_HMAC_MD5_128, _nx_secure_crypto_method_self_test_hmac_md5},
53 {NX_CRYPTO_PRF_HMAC_SHA1, _nx_secure_crypto_method_self_test_prf},
54 {NX_CRYPTO_PRF_HMAC_SHA2_256, _nx_secure_crypto_method_self_test_prf},
55 };
56
57 /* Define an array to avoid duplicate self testing for identical crypto method. */
58 static const NX_CRYPTO_METHOD *nx_crypto_self_test_methods[sizeof(nx_crypto_self_test_map) / sizeof(NX_SECURE_CRYPTO_SELF_TEST)];
59
60 UINT _nx_secure_crypto_method_self_test(const NX_CRYPTO_METHOD *crypto_method,
61 VOID *metadata, UINT metadata_size);
62
63 #endif
64
65 /**************************************************************************/
66 /* */
67 /* FUNCTION RELEASE */
68 /* */
69 /* _nx_secure_crypto_table_self_test PORTABLE C */
70 /* 6.1 */
71 /* AUTHOR */
72 /* */
73 /* Timothy Stapko, Microsoft Corporation */
74 /* */
75 /* DESCRIPTION */
76 /* */
77 /* This function runs through the TLS crypto table self test. */
78 /* The self test is in the form of Known Answer Test. */
79 /* NetX Secure provides a number of vectors that can be used to test */
80 /* crypto methods supported by NetX Secure. */
81 /* */
82 /* INPUT */
83 /* */
84 /* crypto_table Pointer to the crypto method */
85 /* table to be tested */
86 /* metadata_buffer Crypto metadata area */
87 /* metadata_size crypto metadata size */
88 /* */
89 /* OUTPUT */
90 /* */
91 /* status Completion status */
92 /* */
93 /* CALLS */
94 /* */
95 /* None */
96 /* */
97 /* CALLED BY */
98 /* */
99 /* Application Code */
100 /* */
101 /* RELEASE HISTORY */
102 /* */
103 /* DATE NAME DESCRIPTION */
104 /* */
105 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
106 /* 09-30-2020 Timothy Stapko Modified comment(s), */
107 /* resulting in version 6.1 */
108 /* */
109 /**************************************************************************/
_nx_secure_crypto_table_self_test(const NX_SECURE_TLS_CRYPTO * crypto_table,VOID * metadata,UINT metadata_size)110 UINT _nx_secure_crypto_table_self_test(const NX_SECURE_TLS_CRYPTO *crypto_table,
111 VOID *metadata, UINT metadata_size)
112 {
113 #ifdef NX_SECURE_POWER_ON_SELF_TEST_MODULE_INTEGRITY_CHECK
114 UINT i;
115 UINT crypto_table_size;
116 NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite;
117 #ifndef NX_SECURE_DISABLE_X509
118 NX_SECURE_X509_CRYPTO *x509_crypto;
119 #endif
120 UINT status = NX_SECURE_TLS_SUCCESS;
121
122 /* Validate the crypto method */
123 if(crypto_table == NX_NULL)
124 return(NX_PTR_ERROR);
125
126 /* Initialize the crypto method list that is tested. */
127 NX_CRYPTO_MEMSET(nx_crypto_self_test_methods, 0, sizeof(nx_crypto_self_test_methods));
128
129 /* Go through our internal Known Answer Test table, and run through the matching
130 test. */
131 /* For now we shall be able to test the following algorithms, based on the value in
132 nx_crypto_algorithm:
133 NX_CRYPTO_KEY_EXCHANGE_RSA (1024/2048/4096 bit key)
134 NX_CRYPTO_ENCRYPTION_DES_CBC
135 NX_CRYPTO_ENCRYPTION_3DES_CBC
136 NX_CRYPTO_ENCRYPTION_AES_CBC (check key_size field)
137 NX_CRYPTO_ENCRYPTION_AES_CTR
138 NX_CRYPTO_HASH_SHA1
139 NX_CRYPTO_HASH_SHA256
140 NX_CRYPTO_HASH_SHA384
141 NX_CRYPTO_HASH_SHA512
142 NX_CRYPTO_HASH_MD5
143 NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_96
144 NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_160
145 NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_256
146 NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_384
147 NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_512
148 NX_CRYPTO_AUTHENTICATION_HMAC_MD5_96
149 NX_CRYPTO_AUTHENTICATION_HMAC_MD5_128
150 NX_CRYPTO_PRF_HMAC_SHA1
151 NX_CRYPTO_PRF_HMAC_SHA2_256
152 */
153
154 crypto_table_size = crypto_table -> nx_secure_tls_ciphersuite_lookup_table_size;
155
156 /* Loop through cipher table and perform self tests. */
157 for (i = 0; i < crypto_table_size; ++i)
158 {
159 ciphersuite = &crypto_table -> nx_secure_tls_ciphersuite_lookup_table[i];
160 status = _nx_secure_crypto_method_self_test(ciphersuite -> nx_secure_tls_public_cipher, metadata, metadata_size);
161 if (status)
162 {
163 return(status);
164 }
165
166 status = _nx_secure_crypto_method_self_test(ciphersuite -> nx_secure_tls_public_auth, metadata, metadata_size);
167 if (status)
168 {
169 return(status);
170 }
171
172 status = _nx_secure_crypto_method_self_test(ciphersuite -> nx_secure_tls_session_cipher, metadata, metadata_size);
173 if (status)
174 {
175 return(status);
176 }
177
178 status = _nx_secure_crypto_method_self_test(ciphersuite -> nx_secure_tls_hash, metadata, metadata_size);
179 if (status)
180 {
181 return(status);
182 }
183
184 status = _nx_secure_crypto_method_self_test(ciphersuite -> nx_secure_tls_prf, metadata, metadata_size);
185 if (status)
186 {
187 return(status);
188 }
189
190 }
191
192 #ifndef NX_SECURE_DISABLE_X509
193 crypto_table_size = crypto_table -> nx_secure_tls_x509_cipher_table_size;
194
195 /* Loop through X.509 crypto table and perform self tests. */
196 for (i = 0; i < crypto_table_size; ++i)
197 {
198 x509_crypto = &crypto_table -> nx_secure_tls_x509_cipher_table[i];
199
200 status = _nx_secure_crypto_method_self_test(x509_crypto -> nx_secure_x509_public_cipher_method, metadata, metadata_size);
201 if (status)
202 {
203 return(status);
204 }
205
206 status = _nx_secure_crypto_method_self_test(x509_crypto -> nx_secure_x509_hash_method, metadata, metadata_size);
207 if (status)
208 {
209 return(status);
210 }
211
212 }
213 #endif
214
215
216 /* We will also need to maintain the testing information. If a crypto method has been
217 tested, we don't want to test it again. This happens when the same algorithm apeears
218 multiple times in the lookup table.
219 */
220
221
222 return(NX_CRYPTO_SUCCESS);
223 #else
224 NX_PARAMETER_NOT_USED(crypto_table);
225 NX_PARAMETER_NOT_USED(metadata);
226 NX_PARAMETER_NOT_USED(metadata_size);
227 return(NX_CRYPTO_SUCCESS);
228 #endif
229 }
230 #ifdef NX_SECURE_POWER_ON_SELF_TEST_MODULE_INTEGRITY_CHECK
231
_nx_secure_crypto_method_self_test(const NX_CRYPTO_METHOD * crypto_method,VOID * metadata,UINT metadata_size)232 UINT _nx_secure_crypto_method_self_test(const NX_CRYPTO_METHOD *crypto_method,
233 VOID *metadata, UINT metadata_size)
234 {
235 UINT i;
236 UINT crypto_algorithm;
237 UINT status;
238
239 /* Validate the crypto method */
240 if(crypto_method == NX_NULL)
241 return(NX_PTR_ERROR);
242
243 crypto_algorithm = crypto_method -> nx_crypto_algorithm;
244
245 /* No necessary to verify NULL or None algorithms. */
246 if ((crypto_algorithm == NX_CRYPTO_ENCRYPTION_NULL) ||
247 (crypto_algorithm == NX_CRYPTO_NONE) ||
248 (crypto_algorithm == NX_CRYPTO_AUTHENTICATION_NONE) ||
249 (crypto_algorithm == NX_CRYPTO_HASH_NONE) ||
250 (crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_NONE))
251 return(NX_CRYPTO_SUCCESS);
252
253 /* Loop through the self test map and find the self test function for the crypto method. */
254 for (i = 0; i < sizeof(nx_crypto_self_test_map) / sizeof(NX_SECURE_CRYPTO_SELF_TEST); ++i)
255 {
256 if (crypto_algorithm == nx_crypto_self_test_map[i].nx_crypto_algorithm)
257 {
258 if (crypto_method != nx_crypto_self_test_methods[i])
259 {
260 /* Cast away const since self-test functions take non-const methods (but shouldn't!). */
261 status = nx_crypto_self_test_map[i].self_test_function((NX_CRYPTO_METHOD*)crypto_method, metadata, metadata_size);
262 nx_crypto_self_test_methods[i] = crypto_method;
263 return(status);
264 }
265 else
266 {
267
268 /* Duplicate crypto method. */
269 return(NX_SECURE_TLS_SUCCESS);
270 }
271 }
272 }
273
274 /* Unknown crypto method. */
275 return(NX_NOT_SUCCESSFUL);
276 }
277 #endif
278