We briefly mentioned the major changes from the 1.3 branch to the 2.0 branch in a previous blog article. This article describes the steps required to migrate your code from the latest 1.3 release to the 2.0 branch, starting with the highest impact changes and moving down to more specific ones, and including with step-by-step instructions of what changes are needed.

Things Deprecated in 1.3

If it has not already been done, the first change necessary is to ensure your code compiles with 1.3.11 (or a later version in the 1.3 branch) and POLARSSL_DEPRECATED_REMOVED enabled in config.h (or equally with GCC and Clang, POLARSSL_DEPRECATED_WARNING and no warnings generated). A description of how to replace any deprecated functions can be found in the 1.3 branch documentation.

In addition, you need to make sure you are not making use of the functions mdX_hmac_xxx(), shaXXX_hmac_xxx(), mdX_file(), shaXXX_file() or the equivalent RIPE-MD160 functions, and are using the generic message digest functions instead.

The Great Renaming

As described in the earlier blog all publicly visible symbols are being renamed to begin with MBEDTLS_ or mbedtls_. We provide two approaches to the problem of migrating your code to the new names - a script to migrate code and a compatibility header file, and in addition we have also provided a list of the renamed symbols that can be found in scripts/data_files/rename-1.3-2.0.txt to allow you write your own script.

Recommended Approach: The Renaming Script

This is the simplest approach. The rename script is scripts/rename.pl and has no dependency beyond a Perl interpreter. The script takes care of renaming all the identifiers and changing the directory names in any #include directives.

The script works by doing a partial tokenization of the input files in order to only replace full identifiers. By default, it recognizes C string literals and does not perform any replacement on their content. This can however be changed with the -s option, which may be useful, for instance if some of your debug messages contain functions names.

A typical invocation of the script looks like this:

cd your_source_directory
/path/to/mbedtls/scripts/rename.pl *.c *.h

If you are using a custom mbed TLS configuration file, you should also pass it through the script. If you are using a custom location for the configuration file, you should change POLARSSL_CONFIG_FILE to MBEDTLS_CONFIG_FILE in your build system.

The script however, only changes the symbolic name of a function. Where a function's definition has changed and parameters or the return type have changed, the code will still have to be changed manually, and where the interface has changed and a function has now become two functions, the code obviously will have to be changed.

Alternative Approach: The Compatibility Header

An alternative, temporary approach, is to delay renaming functions by using the compat-1.3.h header file. If you choose this approach you should:

  1. Add #include "mbedtls/compat-1.3.h" to all source files that use mbed TLS.
  2. The path for all mbed TLS header files should change the containing directory from polarssl to mbedtls, or alternatively a symbolic link can be created to redirect polarssl to mbedtls.
  3. If you are using a custom configuration file, you still need to move to the new names. If you are using a custom location for the configuration file, the name of the macro remains POLARSSL_CONFIG_FILE.

As with the renaming script, this approach does not help where functions have changed, and parameters or the return type have changed, so some code may still need reworking.

It should be emphasised that the compatibility header approach is only temporary, as compat-1.3.h will be removed in the 3.y branch. It may however be useful if you want to make your code compatible with both the 1.3.z and 2.y branch for the time being.

SSL API Changes

The TLS/SSL API has been changed to create a cleaner, more consistent interface, which will impact every application that makes use of SSL/TLS connections. For such code the following steps are recommended:

  1. Allocate memory for the new type of mbedtls_ssl_config. In the example applications this is done by declaring a new local variable of type mbedtls_ssl_config in the main function.
  2. Add a call to mbedtls_ssl_config_init() during initialisation of mbed TLS and a call to mbedtls_ssl_config_free() when mbed TLS is being deallocated and freed.
  3. Add a call to mbedtls_ssl_config_defaults() at the point during initialisation where the code is calling the mbedtls_ssl_set_xxx() functions. This function also replaces the call to mbedtls_ssl_set_endpoint().
  4. You should have a call to memset( &ssl, 0, sizeof( mbedtls_ssl_context ) ) near the declaration of the SSL context. Replace it with a call to mbedtls_ssl_init(). Remove your previous call to this function and replace it with a call to mbedtls_ssl_setup() which should be placed between the calls to mbedtls_ssl_conf_xxx() and the remaining calls to mbedtls_ssl_set_xxx().
  5. The rename script will have changed calls to the ssl_set_xxx() functions to a corresponding mbedtls_ssl_conf_xxx() equivalent function. For each call to mbedtls_ssl_conf_xxx(), the function call must be changed to pass as the first argument of the function a pointer to the mbedtls_ssl_config structure, instead of a pointer to the SSL context structure, which has been renamed to be mbedtls_ssl_context.
  6. In addition, there are other special cases that require further changes to the source code:
    • the definition of mbedtls_ssl_set_bio() has changed, and the parameters must be reordered (ssl, a, b, c, b) -> (ssl, b, c, a, NULL)
    • the definition of mbedtls_ssl_set_ca_chain() has changed and it has lost its last parameter, which should now be passed to mbedtls_ssl_set_hostname()
  7. If your application code is multi-threaded, calls to mbedtls_ssl_conf_xxx() will typically be in the main thread and calls to mbedtls_ssl_set_xxx() in the worker threads.

Specific changes in the SSL layer

This step applies only if you are using SSL/TLS as a server for the following specified features.

Session tickets

  1. Remove the call to mbedlts_ssl_conf_session_tickets().
  2. Declare a new variable of type mbedtls_ssl_ticket_context in your main function, then add calls to mbedtls_ssl_ticket_init() and mbedtls_ssl_free() near the beginning and end of the main function.
  3. Add calls to mbedtls_ssl_ticket_setup() then mbedtls_ssl_conf_session_tickets_cb() at the same place as other calls to mbedtls_ssl_conf_xxx().

SNI and PSK callbacks

In you callback implementation, replace calls to mbedtls_ssl_set_xxx() functions with calls to the corresponding mbedtls_ssl_set_hs_xxx(). Note that for PSK, the prototype is also changed.

Session cache

The prototype of mbedtls_ssl_conf_session_cache() changed, the arguments should be rearranged as: (conf, a, b, c, b) -> (conf, b, a, c).

Verify callback

If you are using the verify callback, you should update the signature of your callback implementation to reflect the fact that flags is now and unint32_t.

Miscellaneous medium changes

  • In the network layer (net.c), all functions that accepted int as parameters for file descriptors now take a pointer to the mbedtls_net_context instead, for future extensibility. This context should be initialized with mbedtls_net_init() before using it, and freed with mbedtls_net_free() to terminate the connection. If you are using your own network callbacks instead of our network layer, then you don't need to change anything.

  • The following _init() functions that could return errors have been split into an _init() that returns void and another function that should generally be the first function called on this context after init:

    mbedtls_ssl_init() -> mbedtls_ssl_setup()
    mbedtls_ccm_init() -> mbedtls_ccm_setkey()
    mbedtls_gcm_init() -> mbedtls_gcm_setkey()
    mbedtls_hmac_drbg_init() -> mbedtls_hmac_drbg_seed(_buf)()
    mbedtls_ctr_drbg_init()  -> mbedtls_ctr_drbg_seed()
    
  • X.509 verification flags are now an uint32_t. Affects the signature of:

    mbedtls_ssl_get_verify_result()
    mbedtls_x509_ctr_verify_info()
    mbedtls_x509_crt_verify() // flags, f_vrfy -> needs to be updated
    mbedtls_ssl_conf_verify() // f_vrfy -> needs to be updated
    
  • Functions mbedtls_x509_xxx_parse(), mbedtls_pk_parse_key(), mbedtls_pk_parse_public_key() and mbedtls_dhm_parse_dhm() now expect the length parameter to include the terminating null byte for PEM input.

    • The following functions are now case-sensitive:

      mbedtls_cipher_info_from_string() mbedtls_ecp_curve_info_from_name() mbedtls_md_info_from_string() mbedtls_ssl_ciphersuite_from_string() mbedtls_version_check_feature()

  • In the threading layer, mbedtls_mutex_init() and mbedtls_mutex_free() now return void.

  • calloc() is now used instead of malloc()everywhere. API of platform layer and the memory_buffer_alloc module changed accordingly.

Miscellaneous smaller changes

There are a number of changes that will typically affect only a few users, and/or have very small impact. We're not listing them here and instead refer you to the ChangeLog file held in the root of the source code for the full list.

Did this help?