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 Self Test                                                    */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_CRYPTO_SOURCE_CODE
23 
24 
25 /* Include necessary system files.  */
26 #include "nx_crypto_method_self_test.h"
27 #include "nx_crypto_drbg.h"
28 #include "nx_crypto_aes.h"
29 
30 #ifdef NX_CRYPTO_SELF_TEST
31 
32 /*
33 [AES-128 use df]
34 [PredictionResistance = True]
35 [EntropyInputLen = 128]
36 [NonceLen = 64]
37 [PersonalizationStringLen = 128]
38 [AdditionalInputLen = 128]
39 [ReturnedBitsLen = 512]
40 
41 COUNT = 0
42 EntropyInput = c87bcfa53ded926698bb792254eba853
43 Nonce = 1165ebdb6fe78232
44 PersonalizationString = 7ee8c40ebd3551fe103c8349377ea7cc
45 AdditionalInput = db2422dba1157857785ce57b43bc938e
46 EntropyInputPR = da60722bd8d6d4313d47ce07c4f63c29
47 AdditionalInput = 06b93f6b069e4859a8c76247a4825a64
48 EntropyInputPR = 933623ef7527bc0449ca8d629d84a91f
49 ReturnedBits = fd76ace1287a800d01a969fc99d6db8b3f309f6cf5b2b07eec12e3f0169cbbcdebf9a1485a57ed0f5ecc14de122c5eee9c39f48ee8e98e5bb58141e9dc33121e
50 
51 [AES-128 use df]
52 [PredictionResistance = False]
53 [EntropyInputLen = 128]
54 [NonceLen = 64]
55 [PersonalizationStringLen = 128]
56 [AdditionalInputLen = 128]
57 [ReturnedBitsLen = 512]
58 
59 COUNT = 0
60 EntropyInput = 63f226b4a964681df99ac1965cecac3a
61 Nonce = d888574290239f93
62 PersonalizationString = d0ef2ed4a740a78ee06b461758a67912
63 EntropyInputReseed = 5d093a54a1201f46ab562e8abf77fa8f
64 AdditionalInputReseed = 39232ea4871483ae596a8fa56fec03d6
65 AdditionalInput = b8f5e41effe52e62f2a258c9e29ad5b3
66 AdditionalInput = bb8fd9404da2c601b0209e0f4b1a5094
67 ReturnedBits = 22e3066c23bbaae85b118dffc21c3572dcbede7a7c7a7c73bcdee8a060500ef67af6c13cee6f4da309f8b3e3fa8dc4c37f94d99b591a1cede6aec30b200c81f7
68 */
69 
70 static UCHAR entropy_input_aes128[] = {
71 0xc8, 0x7b, 0xcf, 0xa5, 0x3d, 0xed, 0x92, 0x66, 0x98, 0xbb, 0x79, 0x22, 0x54, 0xeb, 0xa8, 0x53
72 };
73 static UINT entropy_input_len_aes128 = 16;
74 static UCHAR nonce_aes128[] = {
75 0x11, 0x65, 0xeb, 0xdb, 0x6f, 0xe7, 0x82, 0x32 };
76 static UCHAR personalization_string_aes128[] = {
77 0x7e, 0xe8, 0xc4, 0x0e, 0xbd, 0x35, 0x51, 0xfe, 0x10, 0x3c, 0x83, 0x49, 0x37, 0x7e, 0xa7, 0xcc
78 };
79 static UCHAR additional_input_0_aes128[] = {
80 0xdb, 0x24, 0x22, 0xdb, 0xa1, 0x15, 0x78, 0x57, 0x78, 0x5c, 0xe5, 0x7b, 0x43, 0xbc, 0x93, 0x8e
81 };
82 static UCHAR entropy_input_pr_0_aes128[] = {
83 0xda, 0x60, 0x72, 0x2b, 0xd8, 0xd6, 0xd4, 0x31, 0x3d, 0x47, 0xce, 0x07, 0xc4, 0xf6, 0x3c, 0x29
84 };
85 static UCHAR additional_input_1_aes128[] = {
86 0x06, 0xb9, 0x3f, 0x6b, 0x06, 0x9e, 0x48, 0x59, 0xa8, 0xc7, 0x62, 0x47, 0xa4, 0x82, 0x5a, 0x64
87 };
88 static UCHAR entropy_input_pr_1_aes128[] = {
89 0x93, 0x36, 0x23, 0xef, 0x75, 0x27, 0xbc, 0x04, 0x49, 0xca, 0x8d, 0x62, 0x9d, 0x84, 0xa9, 0x1f
90 };
91 static UCHAR returned_bits_aes128[] = {
92 0xfd, 0x76, 0xac, 0xe1, 0x28, 0x7a, 0x80, 0x0d, 0x01, 0xa9, 0x69, 0xfc, 0x99, 0xd6, 0xdb, 0x8b,
93 0x3f, 0x30, 0x9f, 0x6c, 0xf5, 0xb2, 0xb0, 0x7e, 0xec, 0x12, 0xe3, 0xf0, 0x16, 0x9c, 0xbb, 0xcd,
94 0xeb, 0xf9, 0xa1, 0x48, 0x5a, 0x57, 0xed, 0x0f, 0x5e, 0xcc, 0x14, 0xde, 0x12, 0x2c, 0x5e, 0xee,
95 0x9c, 0x39, 0xf4, 0x8e, 0xe8, 0xe9, 0x8e, 0x5b, 0xb5, 0x81, 0x41, 0xe9, 0xdc, 0x33, 0x12, 0x1e
96 };
97 
98 static UCHAR entropy_input_npr_aes128[] = {
99 0x63, 0xf2, 0x26, 0xb4, 0xa9, 0x64, 0x68, 0x1d, 0xf9, 0x9a, 0xc1, 0x96, 0x5c, 0xec, 0xac, 0x3a
100 };
101 static UINT entropy_input_len_npr_aes128 = 16;
102 static UCHAR nonce_npr_aes128[] = {
103 0xd8, 0x88, 0x57, 0x42, 0x90, 0x23, 0x9f, 0x93
104 };
105 static UCHAR personalization_string_npr_aes128[] = {
106 0xd0, 0xef, 0x2e, 0xd4, 0xa7, 0x40, 0xa7, 0x8e, 0xe0, 0x6b, 0x46, 0x17, 0x58, 0xa6, 0x79, 0x12
107 };
108 static UCHAR entropy_input_reseed_npr_aes128[] = {
109 0x5d, 0x09, 0x3a, 0x54, 0xa1, 0x20, 0x1f, 0x46, 0xab, 0x56, 0x2e, 0x8a, 0xbf, 0x77, 0xfa, 0x8f
110 };
111 static UCHAR additional_input_reseed_npr_aes128[] = {
112 0x39, 0x23, 0x2e, 0xa4, 0x87, 0x14, 0x83, 0xae, 0x59, 0x6a, 0x8f, 0xa5, 0x6f, 0xec, 0x03, 0xd6
113 };
114 static UCHAR additional_input_0_npr_aes128[] = {
115 0xb8, 0xf5, 0xe4, 0x1e, 0xff, 0xe5, 0x2e, 0x62, 0xf2, 0xa2, 0x58, 0xc9, 0xe2, 0x9a, 0xd5, 0xb3
116 };
117 static UCHAR additional_input_1_npr_aes128[] = {
118 0xbb, 0x8f, 0xd9, 0x40, 0x4d, 0xa2, 0xc6, 0x01, 0xb0, 0x20, 0x9e, 0x0f, 0x4b, 0x1a, 0x50, 0x94
119 };
120 static UCHAR returned_bits_npr_aes128[] = {
121 0x22, 0xe3, 0x06, 0x6c, 0x23, 0xbb, 0xaa, 0xe8, 0x5b, 0x11, 0x8d, 0xff, 0xc2, 0x1c, 0x35, 0x72,
122 0xdc, 0xbe, 0xde, 0x7a, 0x7c, 0x7a, 0x7c, 0x73, 0xbc, 0xde, 0xe8, 0xa0, 0x60, 0x50, 0x0e, 0xf6,
123 0x7a, 0xf6, 0xc1, 0x3c, 0xee, 0x6f, 0x4d, 0xa3, 0x09, 0xf8, 0xb3, 0xe3, 0xfa, 0x8d, 0xc4, 0xc3,
124 0x7f, 0x94, 0xd9, 0x9b, 0x59, 0x1a, 0x1c, 0xed, 0xe6, 0xae, 0xc3, 0x0b, 0x20, 0x0c, 0x81, 0xf7
125 };
126 
127 /* Output.  */
128 static UCHAR output[64];
129 static NX_CRYPTO_AES aes_metadata;
130 
131 /* Global variable.  */
132 static UCHAR drbg_test_entropy_count_pr;
133 static UCHAR drbg_test_entropy_count_npr;
134 
135 /**************************************************************************/
136 /*                                                                        */
137 /*  FUNCTION                                               RELEASE        */
138 /*                                                                        */
139 /*    drbg_test_get_entropy_pr                            PORTABLE C      */
140 /*                                                           6.1.7        */
141 /*  AUTHOR                                                                */
142 /*                                                                        */
143 /*    Timothy Stapko, Microsoft Corporation                               */
144 /*                                                                        */
145 /*  DESCRIPTION                                                           */
146 /*                                                                        */
147 /*    This function serves an entrpoy source for the DRBG module, for the */
148 /*    purpose of the self test.                                           */
149 /*                                                                        */
150 /*  INPUT                                                                 */
151 /*                                                                        */
152 /*    entropy                               Pointer to the buffer for     */
153 /*                                            the value to be returned    */
154 /*    entropy_len                           Number of valid bytes written */
155 /*    entrypy_max_len                       Size of the input buffer      */
156 /*                                                                        */
157 /*  OUTPUT                                                                */
158 /*                                                                        */
159 /*    status                                Completion status             */
160 /*                                                                        */
161 /*  CALLS                                                                 */
162 /*                                                                        */
163 /*    NX_CRYPTO_MEMCPY                                                    */
164 /*                                                                        */
165 /*  CALLED BY                                                             */
166 /*                                                                        */
167 /*    DRBG internal logic                                                 */
168 /*                                                                        */
169 /*  RELEASE HISTORY                                                       */
170 /*                                                                        */
171 /*    DATE              NAME                      DESCRIPTION             */
172 /*                                                                        */
173 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
174 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
175 /*                                            verified memcpy use cases,  */
176 /*                                            resulting in version 6.1    */
177 /*  06-02-2021     Bhupendra Naphade        Modified comment(s),          */
178 /*                                            renamed FIPS symbol to      */
179 /*                                            self-test,                  */
180 /*                                            resulting in version 6.1.7  */
181 /*                                                                        */
182 /**************************************************************************/
drbg_test_get_entropy_pr(UCHAR * entropy,UINT * entropy_len,UINT entropy_max_len)183 NX_CRYPTO_KEEP static UINT drbg_test_get_entropy_pr(UCHAR *entropy, UINT *entropy_len, UINT entropy_max_len)
184 {
185     if (entropy_input_len_aes128 < *entropy_len)
186     {
187         return(NX_CRYPTO_SIZE_ERROR);
188     }
189 
190     if (entropy_input_len_aes128 > entropy_max_len)
191     {
192         return(NX_CRYPTO_SIZE_ERROR);
193     }
194 
195     if (drbg_test_entropy_count_pr == 0)
196     {
197         NX_CRYPTO_MEMCPY(entropy, entropy_input_aes128, entropy_input_len_aes128); /* Use case of memcpy is verified. */
198         *entropy_len = entropy_input_len_aes128;
199     }
200     else if (drbg_test_entropy_count_pr == 1)
201     {
202         NX_CRYPTO_MEMCPY(entropy, entropy_input_pr_0_aes128, entropy_input_len_aes128); /* Use case of memcpy is verified. */
203         *entropy_len = entropy_input_len_aes128;
204     }
205     else if (drbg_test_entropy_count_pr == 2)
206     {
207         NX_CRYPTO_MEMCPY(entropy, entropy_input_pr_1_aes128, entropy_input_len_aes128); /* Use case of memcpy is verified. */
208         *entropy_len = entropy_input_len_aes128;
209     }
210     else
211     {
212         return(1);
213     }
214 
215     drbg_test_entropy_count_pr++;
216 
217     return(NX_CRYPTO_SUCCESS);
218 }
219 
220 /**************************************************************************/
221 /*                                                                        */
222 /*  FUNCTION                                               RELEASE        */
223 /*                                                                        */
224 /*    drbg_test_get_entropy_npr                           PORTABLE C      */
225 /*                                                           6.1          */
226 /*  AUTHOR                                                                */
227 /*                                                                        */
228 /*    Timothy Stapko, Microsoft Corporation                               */
229 /*                                                                        */
230 /*  DESCRIPTION                                                           */
231 /*                                                                        */
232 /*    This function serves an entrpoy source for the DRBG module, for the */
233 /*    purpose of the self test.                                           */
234 /*                                                                        */
235 /*  INPUT                                                                 */
236 /*                                                                        */
237 /*    entropy                               Pointer to the buffer for     */
238 /*                                            the value to be returned    */
239 /*    entropy_len                           Number of valid bytes written */
240 /*    entrypy_max_len                       Size of the input buffer      */
241 /*                                                                        */
242 /*  OUTPUT                                                                */
243 /*                                                                        */
244 /*    status                                Completion status             */
245 /*                                                                        */
246 /*  CALLS                                                                 */
247 /*                                                                        */
248 /*    NX_CRYPTO_MEMCPY                                                    */
249 /*                                                                        */
250 /*  CALLED BY                                                             */
251 /*                                                                        */
252 /*    DRBG internal logic                                                 */
253 /*                                                                        */
254 /*  RELEASE HISTORY                                                       */
255 /*                                                                        */
256 /*    DATE              NAME                      DESCRIPTION             */
257 /*                                                                        */
258 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
259 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
260 /*                                            verified memcpy use cases,  */
261 /*                                            resulting in version 6.1    */
262 /*                                                                        */
263 /**************************************************************************/
drbg_test_get_entropy_npr(UCHAR * entropy,UINT * entropy_len,UINT entropy_max_len)264 NX_CRYPTO_KEEP static UINT drbg_test_get_entropy_npr(UCHAR *entropy, UINT *entropy_len, UINT entropy_max_len)
265 {
266     if (entropy_input_len_npr_aes128 < *entropy_len)
267     {
268         return(NX_CRYPTO_SIZE_ERROR);
269     }
270 
271     if (entropy_input_len_npr_aes128 > entropy_max_len)
272     {
273         return(NX_CRYPTO_SIZE_ERROR);
274     }
275 
276     if (drbg_test_entropy_count_npr == 0)
277     {
278         NX_CRYPTO_MEMCPY(entropy, entropy_input_npr_aes128, entropy_input_len_npr_aes128); /* Use case of memcpy is verified. */
279         *entropy_len = entropy_input_len_npr_aes128;
280     }
281     else if (drbg_test_entropy_count_npr == 1)
282     {
283         NX_CRYPTO_MEMCPY(entropy, entropy_input_reseed_npr_aes128, entropy_input_len_npr_aes128); /* Use case of memcpy is verified. */
284         *entropy_len = entropy_input_len_npr_aes128;
285     }
286     else
287     {
288         return(NX_CRYPTO_NOT_SUCCESSFUL);
289     }
290 
291     drbg_test_entropy_count_npr++;
292 
293     return(NX_CRYPTO_SUCCESS);
294 }
295 
296 /**************************************************************************/
297 /*                                                                        */
298 /*  FUNCTION                                               RELEASE        */
299 /*                                                                        */
300 /*    nx_crypto_method_self_test_drbg                     PORTABLE C      */
301 /*                                                           6.1          */
302 /*  AUTHOR                                                                */
303 /*                                                                        */
304 /*    Timothy Stapko, Microsoft Corporation                               */
305 /*                                                                        */
306 /*  DESCRIPTION                                                           */
307 /*                                                                        */
308 /*    This function performs the Known Answer Test for DRBG crypto method.*/
309 /*                                                                        */
310 /*  INPUT                                                                 */
311 /*                                                                        */
312 /*    method_ptr                            Pointer to the crypto method  */
313 /*                                            to be tested.               */
314 /*    metadata                              Metadata area required by     */
315 /*                                            the DRBG module             */
316 /*    metadata_size                         Size of the metadata area     */
317 /*                                                                        */
318 /*  OUTPUT                                                                */
319 /*                                                                        */
320 /*    status                                Completion status             */
321 /*                                                                        */
322 /*  CALLS                                                                 */
323 /*                                                                        */
324 /*    NX_CRYPTO_MEMCPY                                                    */
325 /*    NX_CRYPTO_MEMCMP                                                    */
326 /*                                                                        */
327 /*                                                                        */
328 /*  CALLED BY                                                             */
329 /*                                                                        */
330 /*    Application Code                                                    */
331 /*                                                                        */
332 /*  RELEASE HISTORY                                                       */
333 /*                                                                        */
334 /*    DATE              NAME                      DESCRIPTION             */
335 /*                                                                        */
336 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
337 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
338 /*                                            resulting in version 6.1    */
339 /*                                                                        */
340 /**************************************************************************/
_nx_crypto_method_self_test_drbg(NX_CRYPTO_METHOD * crypto_method_drbg,VOID * metadata,UINT metadata_size)341 NX_CRYPTO_KEEP UINT _nx_crypto_method_self_test_drbg(NX_CRYPTO_METHOD *crypto_method_drbg,
342                                                      VOID *metadata, UINT metadata_size)
343 {
344 NX_CRYPTO_DRBG_OPTIONS   drbg_opt;
345 UCHAR                   *personalization_string;
346 UINT                     personalization_string_len;
347 UCHAR                   *additional_input[2];
348 UINT                     additional_input_len;
349 UCHAR                   *nonce;
350 UINT                     nonce_len;
351 UCHAR                   *returned_bits;
352 UINT                     returned_bits_len;
353 UINT                     status;
354 VOID                    *handler = NX_CRYPTO_NULL;
355 
356 
357     /* Validate the crypto method */
358     if(crypto_method_drbg == NX_CRYPTO_NULL)
359         return(NX_CRYPTO_PTR_ERROR);
360 
361     /* Set the test data.  */
362     drbg_opt.crypto_method = &crypto_method_aes_cbc_128;
363     drbg_opt.crypto_metadata = (UCHAR *)&aes_metadata;
364     drbg_opt.entropy_input = drbg_test_get_entropy_pr;
365     drbg_opt.use_df = 1;
366     drbg_opt.prediction_resistance = 1;
367     drbg_opt.security_strength = entropy_input_len_aes128;
368 
369     personalization_string = personalization_string_aes128;
370     personalization_string_len = sizeof(personalization_string_aes128);
371     nonce = nonce_aes128;
372     nonce_len = sizeof(nonce_aes128);
373     additional_input[0] = additional_input_0_aes128;
374     additional_input[1] = additional_input_1_aes128;
375     additional_input_len = sizeof(additional_input_0_aes128);
376     returned_bits = returned_bits_aes128;
377     returned_bits_len = sizeof(returned_bits_aes128);
378 
379     /* Clear the output buffer.  */
380     NX_CRYPTO_MEMSET(output, 0, sizeof(output));
381     drbg_test_entropy_count_pr = 0;
382 
383     /* Call the crypto initialization function.  */
384     if (crypto_method_drbg -> nx_crypto_init)
385     {
386         status = crypto_method_drbg -> nx_crypto_init(crypto_method_drbg,
387                                                       NX_CRYPTO_NULL,
388                                                       0,
389                                                       &handler,
390                                                       metadata,
391                                                       metadata_size);
392 
393         /* Check the status.  */
394         if(status != NX_CRYPTO_SUCCESS)
395         {
396             return(status);
397         }
398     }
399 
400     if (crypto_method_drbg -> nx_crypto_operation == NX_CRYPTO_NULL)
401     {
402         return(NX_CRYPTO_PTR_ERROR);
403     }
404 
405     /* Call the crypto operation function.  */
406     status = crypto_method_drbg -> nx_crypto_operation(NX_CRYPTO_DRBG_OPTIONS_SET,
407                                                        handler,
408                                                        crypto_method_drbg,
409                                                        NX_CRYPTO_NULL,
410                                                        0,
411                                                        (UCHAR *)&drbg_opt,
412                                                        sizeof(drbg_opt),
413                                                        NX_CRYPTO_NULL,
414                                                        NX_CRYPTO_NULL,
415                                                        0,
416                                                        metadata,
417                                                        metadata_size,
418                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
419 
420     /* Check the status.  */
421     if(status != NX_CRYPTO_SUCCESS)
422     {
423         return(status);
424     }
425 
426     /* Call the crypto operation function.  */
427     status = crypto_method_drbg -> nx_crypto_operation(NX_CRYPTO_DRBG_INSTANTIATE,
428                                                        handler,
429                                                        crypto_method_drbg,
430                                                        nonce,
431                                                        nonce_len << 3,
432                                                        personalization_string,
433                                                        personalization_string_len,
434                                                        NX_CRYPTO_NULL,
435                                                        NX_CRYPTO_NULL,
436                                                        0,
437                                                        metadata,
438                                                        metadata_size,
439                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
440 
441     /* Check the status.  */
442     if(status != NX_CRYPTO_SUCCESS)
443     {
444         return(status);
445     }
446 
447     /* Call the crypto operation function.  */
448     status = crypto_method_drbg -> nx_crypto_operation(NX_CRYPTO_DRBG_GENERATE,
449                                                        handler,
450                                                        crypto_method_drbg,
451                                                        NX_CRYPTO_NULL,
452                                                        0,
453                                                        additional_input[0],
454                                                        additional_input_len,
455                                                        NX_CRYPTO_NULL,
456                                                        output,
457                                                        returned_bits_len,
458                                                        metadata,
459                                                        metadata_size,
460                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
461 
462     /* Check the status.  */
463     if(status != NX_CRYPTO_SUCCESS)
464     {
465         return(status);
466     }
467 
468     /* Call the crypto operation function.  */
469     status = crypto_method_drbg -> nx_crypto_operation(NX_CRYPTO_DRBG_GENERATE,
470                                                        handler,
471                                                        crypto_method_drbg,
472                                                        NX_CRYPTO_NULL,
473                                                        0,
474                                                        additional_input[1],
475                                                        additional_input_len,
476                                                        NX_CRYPTO_NULL,
477                                                        output,
478                                                        returned_bits_len,
479                                                        metadata,
480                                                        metadata_size,
481                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
482 
483     /* Check the status.  */
484     if(status != NX_CRYPTO_SUCCESS)
485     {
486         return(status);
487     }
488 
489     /* Validate the output.  */
490     if(NX_CRYPTO_MEMCMP(output, returned_bits, returned_bits_len) != 0)
491     {
492         return(NX_CRYPTO_NOT_SUCCESSFUL);
493     }
494 
495     if (crypto_method_drbg -> nx_crypto_cleanup)
496     {
497         status = crypto_method_drbg -> nx_crypto_cleanup(metadata);
498     }
499 
500     /* Check the status.  */
501     if(status != NX_CRYPTO_SUCCESS)
502     {
503         return(status);
504     }
505 
506 
507     /* Set the test data for reseed.  */
508     drbg_opt.crypto_method = &crypto_method_aes_cbc_128;
509     drbg_opt.crypto_metadata = (UCHAR *)&aes_metadata;
510     drbg_opt.entropy_input = drbg_test_get_entropy_npr;
511     drbg_opt.use_df = 1;
512     drbg_opt.prediction_resistance = 0;
513     drbg_opt.security_strength = entropy_input_len_npr_aes128;
514 
515     /* Clear the output buffer.  */
516     NX_CRYPTO_MEMSET(output, 0, sizeof(output));
517     drbg_test_entropy_count_npr = 0;
518 
519     /* Call the crypto initialization function.  */
520     if (crypto_method_drbg -> nx_crypto_init)
521     {
522         status = crypto_method_drbg -> nx_crypto_init(crypto_method_drbg,
523                                                       NX_CRYPTO_NULL,
524                                                       0,
525                                                       &handler,
526                                                       metadata,
527                                                       metadata_size);
528 
529         /* Check the status.  */
530         if(status != NX_CRYPTO_SUCCESS)
531         {
532             return(status);
533         }
534     }
535 
536     if (crypto_method_drbg -> nx_crypto_operation == NX_CRYPTO_NULL)
537     {
538         return(NX_CRYPTO_PTR_ERROR);
539     }
540 
541     /* Call the crypto operation function.  */
542     status = crypto_method_drbg -> nx_crypto_operation(NX_CRYPTO_DRBG_OPTIONS_SET,
543                                                        handler,
544                                                        crypto_method_drbg,
545                                                        NX_CRYPTO_NULL,
546                                                        0,
547                                                        (UCHAR *)&drbg_opt,
548                                                        sizeof(drbg_opt),
549                                                        NX_CRYPTO_NULL,
550                                                        NX_CRYPTO_NULL,
551                                                        0,
552                                                        metadata,
553                                                        metadata_size,
554                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
555 
556     /* Check the status.  */
557     if(status != NX_CRYPTO_SUCCESS)
558     {
559         return(status);
560     }
561 
562     /* Call the crypto operation function.  */
563     status = crypto_method_drbg -> nx_crypto_operation(NX_CRYPTO_DRBG_INSTANTIATE,
564                                                        handler,
565                                                        crypto_method_drbg,
566                                                        nonce_npr_aes128,
567                                                        sizeof(nonce_npr_aes128) << 3,
568                                                        personalization_string_npr_aes128,
569                                                        sizeof(personalization_string_npr_aes128),
570                                                        NX_CRYPTO_NULL,
571                                                        NX_CRYPTO_NULL,
572                                                        0,
573                                                        metadata,
574                                                        metadata_size,
575                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
576 
577     /* Check the status.  */
578     if(status != NX_CRYPTO_SUCCESS)
579     {
580         return(status);
581     }
582 
583     /* Call the crypto operation function.  */
584     status = crypto_method_drbg -> nx_crypto_operation(NX_CRYPTO_DRBG_RESEED,
585                                                        handler,
586                                                        crypto_method_drbg,
587                                                        NX_CRYPTO_NULL,
588                                                        0,
589                                                        additional_input_reseed_npr_aes128,
590                                                        sizeof(additional_input_reseed_npr_aes128),
591                                                        NX_CRYPTO_NULL,
592                                                        NX_CRYPTO_NULL,
593                                                        0,
594                                                        metadata,
595                                                        metadata_size,
596                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
597 
598     /* Check the status.  */
599     if(status != NX_CRYPTO_SUCCESS)
600     {
601         return(status);
602     }
603 
604     /* Call the crypto operation function.  */
605     status = crypto_method_drbg -> nx_crypto_operation(NX_CRYPTO_DRBG_GENERATE,
606                                                        handler,
607                                                        crypto_method_drbg,
608                                                        NX_CRYPTO_NULL,
609                                                        0,
610                                                        additional_input_0_npr_aes128,
611                                                        sizeof(additional_input_0_npr_aes128),
612                                                        NX_CRYPTO_NULL,
613                                                        output,
614                                                        sizeof(returned_bits_npr_aes128),
615                                                        metadata,
616                                                        metadata_size,
617                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
618 
619     /* Check the status.  */
620     if(status != NX_CRYPTO_SUCCESS)
621     {
622         return(status);
623     }
624 
625     /* Call the crypto operation function.  */
626     status = crypto_method_drbg -> nx_crypto_operation(NX_CRYPTO_DRBG_GENERATE,
627                                                        handler,
628                                                        crypto_method_drbg,
629                                                        NX_CRYPTO_NULL,
630                                                        0,
631                                                        additional_input_1_npr_aes128,
632                                                        sizeof(additional_input_1_npr_aes128),
633                                                        NX_CRYPTO_NULL,
634                                                        output,
635                                                        sizeof(returned_bits_npr_aes128),
636                                                        metadata,
637                                                        metadata_size,
638                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
639 
640     /* Check the status.  */
641     if(status != NX_CRYPTO_SUCCESS)
642     {
643         return(status);
644     }
645 
646     /* Validate the output.  */
647     if(NX_CRYPTO_MEMCMP(output, returned_bits_npr_aes128, sizeof(returned_bits_npr_aes128)) != 0)
648     {
649         return(NX_CRYPTO_NOT_SUCCESSFUL);
650     }
651 
652     if (crypto_method_drbg -> nx_crypto_cleanup)
653     {
654         status = crypto_method_drbg -> nx_crypto_cleanup(metadata);
655     }
656 
657     return(status);
658 }
659 #endif
660