summaryrefslogtreecommitdiff
path: root/nx_secure/src/nx_secure_crypto_table_self_test.c
blob: c9bc7cb1145f4a3b91d9647abd49ee7b7e692063 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/***************************************************************************
 * Copyright (c) 2024 Microsoft Corporation
 * Copyright (c) 2025-present Eclipse ThreadX Contributors
 *
 * This program and the accompanying materials are made available under the
 * terms of the MIT License which is available at
 * https://opensource.org/licenses/MIT.
 *
 * SPDX-License-Identifier: MIT
 **************************************************************************/


/**************************************************************************/
/**************************************************************************/
/**                                                                       */
/** NetX Secure Component                                                 */
/**                                                                       */
/**    Transport Layer Security (TLS)                                     */
/**                                                                       */
/**************************************************************************/
/**************************************************************************/

#define NX_SECURE_SOURCE_CODE


/* Include necessary system files.  */

#include "nx_secure_crypto_table_self_test.h"


#ifdef NX_SECURE_POWER_ON_SELF_TEST_MODULE_INTEGRITY_CHECK

static const NX_SECURE_CRYPTO_SELF_TEST nx_crypto_self_test_map[] =
{
    {NX_CRYPTO_ENCRYPTION_AES_CBC, _nx_secure_crypto_method_self_test_aes},
    {NX_CRYPTO_ENCRYPTION_AES_CTR, _nx_secure_crypto_method_self_test_aes},
    {NX_CRYPTO_ENCRYPTION_AES_GCM_16, _nx_secure_crypto_method_self_test_aes},
    {NX_CRYPTO_ENCRYPTION_DES_CBC, _nx_secure_crypto_method_self_test_des},
    {NX_CRYPTO_ENCRYPTION_3DES_CBC, _nx_secure_crypto_method_self_test_3des},
    {NX_CRYPTO_HASH_SHA1, _nx_secure_crypto_method_self_test_sha},
    {NX_CRYPTO_HASH_SHA256, _nx_secure_crypto_method_self_test_sha},
    {NX_CRYPTO_HASH_SHA384, _nx_secure_crypto_method_self_test_sha},
    {NX_CRYPTO_HASH_SHA512, _nx_secure_crypto_method_self_test_sha},
    {NX_CRYPTO_HASH_MD5, _nx_secure_crypto_method_self_test_md5},
    {NX_CRYPTO_KEY_EXCHANGE_RSA, _nx_secure_crypto_method_self_test_rsa},
    {NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_96, _nx_secure_crypto_method_self_test_hmac_sha},
    {NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_160, _nx_secure_crypto_method_self_test_hmac_sha},
    {NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_256, _nx_secure_crypto_method_self_test_hmac_sha},
    {NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_384, _nx_secure_crypto_method_self_test_hmac_sha},
    {NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_512, _nx_secure_crypto_method_self_test_hmac_sha},
    {NX_CRYPTO_AUTHENTICATION_HMAC_MD5_96, _nx_secure_crypto_method_self_test_hmac_md5},
    {NX_CRYPTO_AUTHENTICATION_HMAC_MD5_128, _nx_secure_crypto_method_self_test_hmac_md5},
    {NX_CRYPTO_PRF_HMAC_SHA1, _nx_secure_crypto_method_self_test_prf},
    {NX_CRYPTO_PRF_HMAC_SHA2_256, _nx_secure_crypto_method_self_test_prf},
};

/* Define an array to avoid duplicate self testing for identical crypto method. */
static const NX_CRYPTO_METHOD *nx_crypto_self_test_methods[sizeof(nx_crypto_self_test_map) / sizeof(NX_SECURE_CRYPTO_SELF_TEST)];

UINT _nx_secure_crypto_method_self_test(const NX_CRYPTO_METHOD *crypto_method,
                                        VOID *metadata, UINT metadata_size);

#endif

/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _nx_secure_crypto_table_self_test                   PORTABLE C      */
/*                                                           6.4.3        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Timothy Stapko, Microsoft Corporation                               */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function runs through the TLS crypto table self test.          */
/*    The self test is in the form of Known Answer Test.                  */
/*    NetX Secure provides a number of vectors that can be used to test   */
/*    crypto methods supported by NetX Secure.                            */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    crypto_table                          Pointer to the crypto method  */
/*                                            table to be tested          */
/*    metadata_buffer                       Crypto metadata area          */
/*    metadata_size                         crypto metadata size          */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    status                                Completion status             */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    Application Code                                                    */
/*                                                                        */
/**************************************************************************/
UINT _nx_secure_crypto_table_self_test(const NX_SECURE_TLS_CRYPTO *crypto_table,
                                       VOID *metadata, UINT metadata_size)
{
#ifdef NX_SECURE_POWER_ON_SELF_TEST_MODULE_INTEGRITY_CHECK
UINT i;
UINT crypto_table_size;
NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite;
#ifndef NX_SECURE_DISABLE_X509
NX_SECURE_X509_CRYPTO *x509_crypto;
#endif
UINT status = NX_SECURE_TLS_SUCCESS;

    /* Validate the crypto method */
    if(crypto_table == NX_NULL)
        return(NX_PTR_ERROR);

    /* Initialize the crypto method list that is tested. */
    NX_CRYPTO_MEMSET(nx_crypto_self_test_methods, 0, sizeof(nx_crypto_self_test_methods));

    /* Go through our internal Known Answer Test table, and run through the matching
       test. */
    /* For now we shall be able to test the following algorithms, based on the value in
       nx_crypto_algorithm:
       NX_CRYPTO_KEY_EXCHANGE_RSA (1024/2048/4096 bit key)
       NX_CRYPTO_ENCRYPTION_DES_CBC
       NX_CRYPTO_ENCRYPTION_3DES_CBC
       NX_CRYPTO_ENCRYPTION_AES_CBC (check key_size field)
       NX_CRYPTO_ENCRYPTION_AES_CTR
       NX_CRYPTO_HASH_SHA1
       NX_CRYPTO_HASH_SHA256
       NX_CRYPTO_HASH_SHA384
       NX_CRYPTO_HASH_SHA512
       NX_CRYPTO_HASH_MD5
       NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_96
       NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_160
       NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_256
       NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_384
       NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_512
       NX_CRYPTO_AUTHENTICATION_HMAC_MD5_96
       NX_CRYPTO_AUTHENTICATION_HMAC_MD5_128
       NX_CRYPTO_PRF_HMAC_SHA1
       NX_CRYPTO_PRF_HMAC_SHA2_256
    */

    crypto_table_size = crypto_table -> nx_secure_tls_ciphersuite_lookup_table_size;

    /* Loop through cipher table and perform self tests. */
    for (i = 0; i < crypto_table_size; ++i)
    {
        ciphersuite = &crypto_table -> nx_secure_tls_ciphersuite_lookup_table[i];
        status = _nx_secure_crypto_method_self_test(ciphersuite -> nx_secure_tls_public_cipher, metadata, metadata_size);
        if (status)
        {
            return(status);
        }

        status = _nx_secure_crypto_method_self_test(ciphersuite -> nx_secure_tls_public_auth, metadata, metadata_size);
        if (status)
        {
            return(status);
        }

        status = _nx_secure_crypto_method_self_test(ciphersuite -> nx_secure_tls_session_cipher, metadata, metadata_size);
        if (status)
        {
            return(status);
        }

        status = _nx_secure_crypto_method_self_test(ciphersuite -> nx_secure_tls_hash, metadata, metadata_size);
        if (status)
        {
            return(status);
        }

        status = _nx_secure_crypto_method_self_test(ciphersuite -> nx_secure_tls_prf, metadata, metadata_size);
        if (status)
        {
            return(status);
        }

    }

#ifndef NX_SECURE_DISABLE_X509
    crypto_table_size = crypto_table -> nx_secure_tls_x509_cipher_table_size;

    /* Loop through X.509 crypto table and perform self tests. */
    for (i = 0; i < crypto_table_size; ++i)
    {
        x509_crypto = &crypto_table -> nx_secure_tls_x509_cipher_table[i];

        status = _nx_secure_crypto_method_self_test(x509_crypto -> nx_secure_x509_public_cipher_method, metadata, metadata_size);
        if (status)
        {
            return(status);
        }

        status = _nx_secure_crypto_method_self_test(x509_crypto -> nx_secure_x509_hash_method, metadata, metadata_size);
        if (status)
        {
            return(status);
        }

    }
#endif


    /* We will also need to maintain the testing information. If a crypto method has been
       tested, we don't want to test it again.  This happens when the same algorithm apeears
       multiple times in the lookup table.
    */


    return(NX_CRYPTO_SUCCESS);
#else
    NX_PARAMETER_NOT_USED(crypto_table);
    NX_PARAMETER_NOT_USED(metadata);
    NX_PARAMETER_NOT_USED(metadata_size);
    return(NX_CRYPTO_SUCCESS);
#endif
}
#ifdef NX_SECURE_POWER_ON_SELF_TEST_MODULE_INTEGRITY_CHECK

UINT _nx_secure_crypto_method_self_test(const NX_CRYPTO_METHOD *crypto_method,
                                        VOID *metadata, UINT metadata_size)
{
UINT i;
UINT crypto_algorithm;
UINT status;

    /* Validate the crypto method */
    if(crypto_method == NX_NULL)
        return(NX_PTR_ERROR);

    crypto_algorithm = crypto_method -> nx_crypto_algorithm;

    /* No necessary to verify NULL or None algorithms. */
    if ((crypto_algorithm == NX_CRYPTO_ENCRYPTION_NULL) ||
        (crypto_algorithm == NX_CRYPTO_NONE) ||
        (crypto_algorithm == NX_CRYPTO_AUTHENTICATION_NONE) ||
        (crypto_algorithm == NX_CRYPTO_HASH_NONE) ||
        (crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_NONE))
        return(NX_CRYPTO_SUCCESS);

    /* Loop through the self test map and find the self test function for the crypto method. */
    for (i = 0; i < sizeof(nx_crypto_self_test_map) / sizeof(NX_SECURE_CRYPTO_SELF_TEST); ++i)
    {
        if (crypto_algorithm == nx_crypto_self_test_map[i].nx_crypto_algorithm)
        {
            if (crypto_method != nx_crypto_self_test_methods[i])
            {
                /* Cast away const since self-test functions take non-const methods (but shouldn't!). */
                status = nx_crypto_self_test_map[i].self_test_function((NX_CRYPTO_METHOD*)crypto_method, metadata, metadata_size);
                nx_crypto_self_test_methods[i] = crypto_method;
                return(status);
            }
            else
            {

                /* Duplicate crypto method. */
                return(NX_SECURE_TLS_SUCCESS);
            }
        }
    }

    /* Unknown crypto method. */
    return(NX_NOT_SUCCESSFUL);
}
#endif