1 
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <time.h>
5 #include "nx_crypto_ecdsa.h"
6 #include "nx_crypto_ec.h"
7 #include "tls_test_utility.h"
8 #ifndef NX_CRYPTO_STANDALONE_ENABLE
9 #include "nx_secure_tls.h"
10 #endif
11 
12 #define LOOP 100
13 
14 #include "nx_secure_ecdsa_test_data.c"
15 
16 extern NX_CRYPTO_METHOD crypto_method_ec_secp192;
17 extern NX_CRYPTO_METHOD crypto_method_ec_secp224;
18 extern NX_CRYPTO_METHOD crypto_method_ec_secp256;
19 extern NX_CRYPTO_METHOD crypto_method_ec_secp384;
20 extern NX_CRYPTO_METHOD crypto_method_ec_secp521;
21 extern NX_CRYPTO_METHOD crypto_method_ecdsa;
22 extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp256r1;
23 extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp521r1;
24 
25 static UCHAR scratch_buffer[4000];
26 static NX_CRYPTO_ECDSA ecdsa;
27 
28 static UCHAR hash_data[80];
29 static UCHAR signature[256];
30 
31 static UCHAR hash[32] = { 0 }; /* arbitrary */
32 
33 static UCHAR testpubkey[65] = { /* arbitrary */
34          0x04, 0xc5, 0xd7, 0xd0, 0x22, 0xbc, 0x2b, 0xa3, 0x7a, 0x58,
35          0x17, 0xe7, 0x52, 0x0a, 0xf8, 0x7c, 0x66, 0xa4, 0xa0, 0xd0,
36          0x25, 0x1b, 0x1c, 0xf7, 0x99, 0xd5, 0x6c, 0x06, 0xe0, 0x58,
37          0x29, 0x6b, 0x04, 0x16, 0x19, 0x01, 0x94, 0xf6, 0x8c, 0x36,
38          0xec, 0xe6, 0x2b, 0x07, 0x63, 0x76, 0xfb, 0xa3, 0x06, 0x4a,
39          0x35, 0x60, 0x4d, 0x83, 0xa3, 0x67, 0xf8, 0x25, 0x53, 0x99,
40          0xd0, 0x17, 0x11, 0x64, 0x85
41 };
42 
43 static UCHAR zerosignature[] = {
44         0x30, 0x80, 0x44, /* 0x44 byte asn1 sequence */
45         0x02, 0x20, /* r tag, size, r */
46         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49         0x00, 0x00,
50         0x02, 0x20, /* s tag, size, s */
51         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54         0x00, 0x00,
55 };
56 
57 static UCHAR maxsignature[] = {
58         0x30, 0x80, 0x46, /* 0x46 byte asn1 sequence */
59         0x02, 0x21, /* r tag, size, r */
60         0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
61         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
62         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
63         0xFF, 0xFF,
64         0x02, 0x21, /* s tag, size, s */
65         0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
66         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
67         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
68         0xFF, 0xFF,
69 };
70 
71 #ifndef NX_CRYPTO_STANDALONE_ENABLE
72 static TX_THREAD thread_0;
73 #endif
74 
75 static VOID thread_0_entry(ULONG thread_input);
76 
77 #ifdef CTEST
78 void test_application_define(void *first_unused_memory);
test_application_define(void * first_unused_memory)79 void test_application_define(void *first_unused_memory)
80 #else
81 void nx_secure_ecdsa_test_application_define(void *first_unused_memory)
82 #endif
83 {
84 #ifndef NX_CRYPTO_STANDALONE_ENABLE
85     tx_thread_create(&thread_0, "Thread 0", thread_0_entry, 0,
86                      first_unused_memory, 4096,
87                      16, 16, 4, TX_AUTO_START);
88 #else
89     thread_0_entry(0);
90 #endif
91 }
92 
93 
thread_0_entry(ULONG thread_input)94 static VOID thread_0_entry(ULONG thread_input)
95 {
96 UINT i, j, status, backup;
97 NX_CRYPTO_HUGE_NUMBER private_key;
98 NX_CRYPTO_EC_POINT    public_key;
99 UCHAR                *privkey;
100 UCHAR                *pubkey;
101 UINT                  pubkey_length;
102 NX_CRYPTO_EC         *curve;
103 UINT                  buffer_size;
104 ULONG                 signature_length;
105 HN_UBASE             *scratch;
106 NX_CRYPTO_METHOD     *curve_method;
107 VOID                 *handler = NX_CRYPTO_NULL;
108 
109     /* Print out test information banner.  */
110     printf("NetX Secure Test:   ECDSA Test.........................................");
111 
112     srand(time(0));
113 
114     curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp256r1;
115 
116     /* Test the input validation of ECDSA verify. */
117     status = _nx_crypto_ecdsa_verify(curve, hash, sizeof(hash),
118                                      testpubkey, sizeof(testpubkey),
119                                      zerosignature, sizeof(zerosignature),
120                                      (HN_UBASE*)scratch_buffer);
121     EXPECT_EQ(NX_CRYPTO_NOT_SUCCESSFUL, status);
122 
123     status = _nx_crypto_ecdsa_verify(curve, hash, sizeof(hash),
124                                      testpubkey, sizeof(testpubkey),
125                                      maxsignature, sizeof(maxsignature),
126                                      (HN_UBASE*)scratch_buffer);
127     EXPECT_EQ(NX_CRYPTO_NOT_SUCCESSFUL, status);
128 
129 
130     for (i = 0; i < LOOP; i++)
131     {
132         if (i == 0)
133         {
134 
135             /* Add a special test of hash data is zero. */
136             memset(hash_data, 0, sizeof(hash_data));
137         }
138         else
139         {
140             for (j = 0; j < sizeof(hash_data); j++)
141             {
142                 hash_data[j] = rand();
143             }
144         }
145 
146         curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp521r1;
147         buffer_size = curve->nx_crypto_ec_n.nx_crypto_huge_buffer_size;
148         scratch = (HN_UBASE*)(&scratch_buffer[3 * buffer_size + 4]);
149         privkey = scratch_buffer;
150         pubkey = &scratch_buffer[buffer_size];
151         NX_CRYPTO_EC_POINT_INITIALIZE(&public_key, NX_CRYPTO_EC_POINT_AFFINE, scratch, buffer_size);
152         NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&private_key, scratch, buffer_size + 8);
153 
154         /* Generate the key pair. */
155         do
156         {
157             _nx_crypto_ec_key_pair_generation_extra(curve, &curve -> nx_crypto_ec_g, &private_key,
158                                                     &public_key, scratch);
159         } while (_nx_crypto_huge_number_is_zero(&private_key));
160 
161         status = _nx_crypto_huge_number_extract_fixed_size(&private_key, privkey, buffer_size);
162         EXPECT_EQ(NX_CRYPTO_SUCCESS, status);
163 
164         pubkey_length = 0;
165         _nx_crypto_ec_point_extract_uncompressed(curve, &public_key, pubkey, 4 + 2 * buffer_size, &pubkey_length);
166         EXPECT_TRUE(pubkey_length != 0);
167 
168         signature_length = sizeof(signature);
169 
170         /* Sign the hash data using ECDSA. */
171         _nx_crypto_ecdsa_sign(curve, hash_data, sizeof(hash_data), privkey, buffer_size, signature, signature_length, &signature_length, scratch);
172 
173         /* Verify the signature. */
174         EXPECT_EQ(NX_CRYPTO_SUCCESS, _nx_crypto_ecdsa_verify(curve, hash_data, sizeof(hash_data), pubkey, pubkey_length, signature, signature_length, scratch));
175 
176     }
177 
178     for (i = 0; i < sizeof(ecdsa_data) / sizeof(ECDSA_DATA); i++)
179     {
180         if (!strcmp(ecdsa_data[i].curve, "secp192r1"))
181         {
182             curve_method = &crypto_method_ec_secp192;
183         }
184         else if (!strcmp(ecdsa_data[i].curve, "secp224r1"))
185         {
186             curve_method = &crypto_method_ec_secp224;
187         }
188         else if (!strcmp(ecdsa_data[i].curve, "secp256r1"))
189         {
190             curve_method = &crypto_method_ec_secp256;
191         }
192         else if (!strcmp(ecdsa_data[i].curve, "secp384r1"))
193         {
194             curve_method = &crypto_method_ec_secp384;
195         }
196         else if (!strcmp(ecdsa_data[i].curve, "secp521r1"))
197         {
198             curve_method = &crypto_method_ec_secp521;
199         }
200 
201         status = crypto_method_ecdsa.nx_crypto_init(&crypto_method_ecdsa,
202                                                     ecdsa_data[i].public_key,
203                                                     (NX_CRYPTO_KEY_SIZE)(ecdsa_data[i].public_key_len << 3),
204                                                     &handler,
205                                                     &ecdsa,
206                                                     sizeof(ecdsa));
207         EXPECT_EQ(NX_CRYPTO_SUCCESS, status);
208 
209         status = crypto_method_ecdsa.nx_crypto_operation(NX_CRYPTO_EC_CURVE_SET, handler,
210                                                          &crypto_method_ecdsa, NX_CRYPTO_NULL, 0,
211                                                          (UCHAR *)curve_method, sizeof(NX_CRYPTO_METHOD *), NX_CRYPTO_NULL,
212                                                          NX_CRYPTO_NULL, 0,
213                                                          &ecdsa,
214                                                          sizeof(ecdsa),
215                                                          NX_CRYPTO_NULL, NX_CRYPTO_NULL);
216         EXPECT_EQ(NX_CRYPTO_SUCCESS, status);
217 
218         status = crypto_method_ecdsa.nx_crypto_operation(NX_CRYPTO_VERIFY, handler,
219                                                          &crypto_method_ecdsa,
220                                                          ecdsa_data[i].public_key,
221                                                          (NX_CRYPTO_KEY_SIZE)(ecdsa_data[i].public_key_len << 3),
222                                                          ecdsa_data[i].hash,
223                                                          ecdsa_data[i].hash_len,
224                                                          NX_CRYPTO_NULL,
225                                                          ecdsa_data[i].signature,
226                                                          ecdsa_data[i].signature_len,
227                                                          &ecdsa,
228                                                          sizeof(ecdsa),
229                                                          NX_CRYPTO_NULL, NX_CRYPTO_NULL);
230         EXPECT_EQ(NX_CRYPTO_SUCCESS, status);
231     }
232 
233     printf("SUCCESS!\n");
234     test_control_return(0);
235 }
236