-
Notifications
You must be signed in to change notification settings - Fork 69
Adding new algorithms
When adding a new algorithm, it may be the most helpful to follow the example of an algorithm that is already supported in the library.
Here is a step by step guide to the code touch-points when adding new algorithm support to the libacvp client library: (summary table is at the bottom)
-
Add new algorithm to the ACVP_CIPHER struct in acvp.h with a consistent name (usually ACVP_<alg_name>) as well as to ACVP_CAP_TYPE in acvp_lcl.h
-
#define the string name for the algorithm in acvp_lcl.h with a consistent name (usually ACVP_ALG_<alg_name>. The strings that are compatible with the NIST ACVP server can be found in https://github.com/usnistgov/ACVP/blob/master/artifacts/draft-vassilev-acvp-iana-00.txt
- if the new algorithm is split into modes, you can follow the example of DSA, RSA, KDF, etc (look in alg_tbl in acvp.c for more) to include those
-
Define a new structure for the <alg_name> test case in acvp.h with a consistent name (usually ACVP_<alg_name>_TC). Then add this test case type to the ACVP_TEST_CASE union also defined in acvp.h. For a simple example, look for ACVP_HASH_TC in acvp.h. This structure will hold all of the attributes of a vector test for that algorithm.
- for a list of attributes for each algorithm supported by the NIST ACVP server, look in the corresponding specification in https://github.com/usnistgov/ACVP/tree/master/artifacts
-
Make new acvp_<alg_name>.c in src directory for new alg:
- generally if you are just adding a new mode, this can be added to the existing algorithm file
- otherwise, this file contains:
- acvp_<alg_name>_output_tc which builds the json with appropriate info
- acvp_<alg_name>_init_tc which allocates memory and copies relevant info from vector sets to be accessible to app crypto handlers
- acvp_<alg_name>_release_tc which frees memory
- acvp_<alg_name>_kat_handler which parses the known answer test vector sets from the server. This includes allocating memory for test cases, invoking the app crypto handler, then freeing the associated test cases. This also needs a forward definition in acvp_lcl.h
-
Add new algorithm to alg_tbl in acvp.c. You'll list the new algorithm with it's name from step 1, the name of the kat handler from step 4, and the string name from step 2 (or relevant mode names, follow example of other algs).
-
Add API to register this new capability:
- in acvp_capabilities.c you'll need an acvp_cap_<alg_name>_enable method. For a simple example, look for acvp_cap_hash_enable in src/acvp_capabilities.c. This method also needs to be defined in acvp.h so that it is accessible to an application leveraging the library (also include the relevant doxygen comments)
- following the pattern of the existing API, this method will also require the new algorithm be added to acvp_cap_list_append method. You can follow the example of the other algorithms to allocate necessary memory based on the ACVP_CAP_TYPE value you defined in step 1.
- in addition to an acvp_cap_<alg_name>_enable API, you'll also need API to set parameters. A simple example can be seen with acvp_cap_hash_set_parm which supports the limited set of configurable options for the hash capability. More complex examples can be seen with RSA or DRBG.
- for parameters with min/max/increment, look for acvp_cap_hmac_set_domain for an example of how we have set this up for existing algs. There are also examples for enabling exponents, etc.
- This API will also require the definition of acvp_validate_<alg_name>_parm_value, or another method of checking input values.
- enums for parameters will be defined in acvp.h, for example look for ACVP_KDF135_SRTP_PARAM in acvp.h
-
Now we need to add the new algorithm to the part of the library that builds the JSON registration. This is kicked off with the acvp_register API in acvp.c but leverages code in acvp_build_register.c as well as structures in acvp_lcl.h
- add the new algorithm to the switch inside acvp_validate_prereq_val in acvp_capabilities.c with the corresponding algorithms that are considered valid prereqs for your algorithm
- define an ACVP_<alg_name>_CAP struct in acvp_lcl.h, then add it to the union within ACVP_CAPS_LIST in acvp_lcl.h. This will hold all the parameters relevant to the algorithm you want to test
- add the new algorithm to the switch in acvp_build_test_session in acvp_build_register.c
- define a method that build the json for your algorithm, usually acvp_build_<alg_name>_register_cap. The existing supported algorithms in that method will have multiple simple examples (hash or hmac) as well as a few that are more complex, for example DSA also takes the mode as a parameter to this method.
- this json should be built according to the specifications to the new algorithm (remember, for NIST ACVP server support, these are defined in https://github.com/usnistgov/ACVP/tree/master/artifacts)
- you can look in the methods defined for other algorithms to see which json API are available and how they are used. parson.h also defines the entire json building/parsing API
-
Add API to acvp.c to free the capability from the ACVP client context when finished. This API is usually named acvp_cap_free_ and needs to be invoked from acvp_free_test_session (also in acvp.c)
-
Add the new algorithm to the example application:
- add support for a new algorithm in the app by adding a new alg into APP_CONFIG, adding a flag in ingest_cli within app/app_main.c and add your new flag to the print_usage method
- in main(), check the config and call a newly defined method called enable_<alg_name> (you can look at examples from other algs here). Your new method will call all of the relevant API: set the prerequisites, enable the algorithm, set parameters
- define a new method that takes ACVP_TEST_CASE as a parameter and does the cryptographic processing. This method is called app_<alg_name>_handler, and it is passed to the acvp_cap_<alg_name>_enable API to register a callback with the library
- examples of these handlers can be seen by looking at the correspondingly named function for other algorithms. The method will use the appropriate vector set information that the library populated, call the cryptographic API, and populate relevant answers to be validated by the server
Filename | Additions |
---|---|
src/acvp.h | add alg to ACVP_CIPHER create test case struct add to ACVP_TEST_CASE union add acvp_cap_enable, acvp_cap_set_parm and other API any necessary parameter enums |
src/acvp_lcl.h | add alg to ACVP_CAP_TYPE #define ACVP_ALG_<alg_name> string name acvp_<alg_name>kat_handler forward declaration define an ACVP<alg_name>_CAP struct add cap struct to ACVP_CAPS_LIST union |
src/acvp_<alg_name>.c | new file containing kat handler and tc manipulation API |
src/acvp.c | add alg to alg_tbl add acvp_cap_free_<alg_name> and invoke in acvp_free_test_session |
src/acvp_capabilities.c | add acvp_cap_<alg_name>_enable update acvp_cap_list_append to support new alg update acvp_validate_prereq_val with new alg and valid prereqs |
src/acvp_build_register.c | add alg to switch in acvp_build_test_session write acvp_build_<alg_name>_register_cap |
app/app_main.c | add alg to APP_CONFIG add flag to ingest_cli and print_usage add enable_ which calls registration API write app_<alg_name>_handler |