Repository: Mbed-TLS/mbedtls (2025-08-18T09:48:19Z)

Issue:
Simplify get-version string interface
Ever since PolarSSL in 3ac1b2d952ea200e66187c40e58729ebc84d8f11, the interface to get the PolarSSL then Mbed TLS version string has been:

```
/**
 * Get the version string ("x.y.z").
 *
 * \param string    The string that will receive the value.
 *                  (Should be at least 9 bytes in size)
 */
void mbedtls_version_get_string(char *string);

/**
 * Get the full version string ("Mbed TLS x.y.z").
 *
 * \param string    The string that will receive the value. The Mbed TLS version
 *                  string will use 18 bytes AT MOST including a terminating
 *                  null byte.
 *                  (So the buffer should be at least 18 bytes to receive this
 *                  version string).
 */
void mbedtls_version_get_string_full(char *string);
```

[As noted by Bence](https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/367#discussion_r2214335274) this is fragile and overly complex. We could just return a global string instead.

(The macro isn't good enough because applications need the version of the library they're running on, not the version they were compiled against.)

We aren't going to change to constructing the version string dynamically from parts. That would take more code than the string. So we don't need the additional flexibility.

If we were doing this from scratch, I think we should make it
```
const char *mbedtls_version_get_string(void);
const char *mbedtls_version_get_string_full(void);
```
Both functions returning globals.

For the sake of applications that want to support both Mbed TLS 3.x and 4.x, we may want to maintain compatibility and introduce the new functions with the new name. On the other hand, application compatibility is already possible by calling `mbedtls_version_get_number()` first.



Discussion:

Patch:
diff --git a/ChangeLog.d/runtime-version-interface.txt b/ChangeLog.d/runtime-version-interface.txt
new file mode 100644
index 000000000000..1cf42665ca99
--- /dev/null
+++ b/ChangeLog.d/runtime-version-interface.txt
@@ -0,0 +1,9 @@
+API changes
+   * Change the signature of the runtime version information methods that took
+     a char* as an argument to take zero arguments and return a const char*
+     instead. This aligns us with the interface used in TF PSA Crypto 1.0.
+     If you need to support linking against both Mbed TLS 3.x and 4.x, please
+     use the build-time version macros or mbedtls_version_get_number() to
+     determine the correct signature for mbedtls_version_get_string() and
+     mbedtls_version_get_string_full() before calling them.
+     Fixes issue #10308.
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index 837787bc7fae..4a0b216e3b2d 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -32,23 +32,14 @@ extern "C" {
 unsigned int mbedtls_version_get_number(void);
 
 /**
- * Get the version string ("x.y.z").
- *
- * \param string    The string that will receive the value.
- *                  (Should be at least 9 bytes in size)
+ * Get a pointer to the version string ("x.y.z").
  */
-void mbedtls_version_get_string(char *string);
+const char *mbedtls_version_get_string(void);
 
 /**
- * Get the full version string ("Mbed TLS x.y.z").
- *
- * \param string    The string that will receive the value. The Mbed TLS version
- *                  string will use 18 bytes AT MOST including a terminating
- *                  null byte.
- *                  (So the buffer should be at least 18 bytes to receive this
- *                  version string).
+ * Get a pointer to the full version string ("Mbed TLS x.y.z").
  */
-void mbedtls_version_get_string_full(char *string);
+const char *mbedtls_version_get_string_full(void);
 
 /**
  * \brief           Check if support for a feature was compiled into this
diff --git a/library/version.c b/library/version.c
index 2cd947da7241..e828673c0d3a 100644
--- a/library/version.c
+++ b/library/version.c
@@ -17,16 +17,14 @@ unsigned int mbedtls_version_get_number(void)
     return MBEDTLS_VERSION_NUMBER;
 }
 
-void mbedtls_version_get_string(char *string)
+const char *mbedtls_version_get_string(void)
 {
-    memcpy(string, MBEDTLS_VERSION_STRING,
-           sizeof(MBEDTLS_VERSION_STRING));
+    return MBEDTLS_VERSION_STRING;
 }
 
-void mbedtls_version_get_string_full(char *string)
+const char *mbedtls_version_get_string_full(void)
 {
-    memcpy(string, MBEDTLS_VERSION_STRING_FULL,
-           sizeof(MBEDTLS_VERSION_STRING_FULL));
+    return MBEDTLS_VERSION_STRING_FULL;
 }
 
 #endif /* MBEDTLS_VERSION_C */


Test patch:
diff --git a/programs/test/cmake_package/cmake_package.c b/programs/test/cmake_package/cmake_package.c
index f7d5230f4610..cd050e97bc18 100644
--- a/programs/test/cmake_package/cmake_package.c
+++ b/programs/test/cmake_package/cmake_package.c
@@ -18,10 +18,7 @@
  * linkage works, but that is all. */
 int main()
 {
-    /* This version string is 18 bytes long, as advised by version.h. */
-    char version[18];
-
-    mbedtls_version_get_string_full(version);
+    const char *version = mbedtls_version_get_string_full();
 
     mbedtls_printf("Built against %s\n", version);
 
diff --git a/programs/test/cmake_package_install/cmake_package_install.c b/programs/test/cmake_package_install/cmake_package_install.c
index fb68883feed2..a63f7dbb0fe3 100644
--- a/programs/test/cmake_package_install/cmake_package_install.c
+++ b/programs/test/cmake_package_install/cmake_package_install.c
@@ -19,10 +19,7 @@
  * linkage works, but that is all. */
 int main()
 {
-    /* This version string is 18 bytes long, as advised by version.h. */
-    char version[18];
-
-    mbedtls_version_get_string_full(version);
+    const char *version = mbedtls_version_get_string_full();
 
     mbedtls_printf("Built against %s\n", version);
 
diff --git a/programs/test/cmake_subproject/cmake_subproject.c b/programs/test/cmake_subproject/cmake_subproject.c
index efab78955338..69b5d0b819c5 100644
--- a/programs/test/cmake_subproject/cmake_subproject.c
+++ b/programs/test/cmake_subproject/cmake_subproject.c
@@ -19,10 +19,7 @@
  * linkage works, but that is all. */
 int main()
 {
-    /* This version string is 18 bytes long, as advised by version.h. */
-    char version[18];
-
-    mbedtls_version_get_string_full(version);
+    const char *version = mbedtls_version_get_string_full();
 
     mbedtls_printf("Built against %s\n", version);
 
diff --git a/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c b/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
index 635a70545ad8..9051f2053542 100644
--- a/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
+++ b/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
@@ -73,12 +73,12 @@ int psa_crypto_call(int function,
 
 psa_status_t psa_crypto_init(void)
 {
-    char mbedtls_version[18];
+    const char *mbedtls_version;
     uint8_t *result = NULL;
     size_t result_length;
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
 
-    mbedtls_version_get_string_full(mbedtls_version);
+    mbedtls_version = mbedtls_version_get_string_full();
     CLIENT_PRINT("%s", mbedtls_version);
 
     CLIENT_PRINT("My PID: %d", getpid());
diff --git a/tests/psa-client-server/psasim/src/psa_sim_generate.pl b/tests/psa-client-server/psasim/src/psa_sim_generate.pl
index 3eec226e1660..0f4c86f81741 100755
--- a/tests/psa-client-server/psasim/src/psa_sim_generate.pl
+++ b/tests/psa-client-server/psasim/src/psa_sim_generate.pl
@@ -390,12 +390,12 @@ sub client_calls_header
 
 psa_status_t psa_crypto_init(void)
 {
-    char mbedtls_version[18];
+    const char *mbedtls_version;
     uint8_t *result = NULL;
     size_t result_length;
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
 
-    mbedtls_version_get_string_full(mbedtls_version);
+    mbedtls_version = mbedtls_version_get_string_full();
     CLIENT_PRINT("%s", mbedtls_version);
 
     CLIENT_PRINT("My PID: %d", getpid());
diff --git a/tests/psa-client-server/psasim/src/server.c b/tests/psa-client-server/psasim/src/server.c
index 44939f1c2a1c..aa0c75a48856 100644
--- a/tests/psa-client-server/psasim/src/server.c
+++ b/tests/psa-client-server/psasim/src/server.c
@@ -56,8 +56,7 @@ int psa_server_main(int argc, char *argv[])
     extern psa_status_t psa_crypto_close(void);
 
 #if defined(MBEDTLS_VERSION_C)
-    char mbedtls_version[18];
-    mbedtls_version_get_string_full(mbedtls_version);
+    const char *mbedtls_version = mbedtls_version_get_string_full();
     SERVER_PRINT("%s", mbedtls_version);
 #endif
 
diff --git a/tests/suites/test_suite_version.function b/tests/suites/test_suite_version.function
index eeae51262651..af0eb86d2338 100644
--- a/tests/suites/test_suite_version.function
+++ b/tests/suites/test_suite_version.function
@@ -38,19 +38,17 @@ void check_compiletime_version(char *version_str)
 void check_runtime_version(char *version_str)
 {
     char build_str[100];
-    char get_str[100];
+    const char *get_str;
     char build_str_full[100];
-    char get_str_full[100];
+    const char *get_str_full;
     unsigned int get_int;
 
     memset(build_str, 0, 100);
-    memset(get_str, 0, 100);
     memset(build_str_full, 0, 100);
-    memset(get_str_full, 0, 100);
 
     get_int = mbedtls_version_get_number();
-    mbedtls_version_get_string(get_str);
-    mbedtls_version_get_string_full(get_str_full);
+    get_str = mbedtls_version_get_string();
+    get_str_full = mbedtls_version_get_string_full();
 
     mbedtls_snprintf(build_str, 100, "%u.%u.%u",
                      (get_int >> 24) & 0xFF,