Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to build simple c++ example with Visual Studio 15 2017 #7087

Open
swex opened this issue Feb 11, 2023 · 28 comments
Open

Unable to build simple c++ example with Visual Studio 15 2017 #7087

swex opened this issue Feb 11, 2023 · 28 comments
Labels
bug component-psa PSA keystore/dispatch layer (storage, drivers, …) component-test Test framework and CI scripts priority-medium Medium priority - this can be reviewed as time permits size-m Estimated task size: medium (~1w)

Comments

@swex
Copy link

swex commented Feb 11, 2023

Summary

Its impossible to build simple ssl_client based single cpp file project with 3.3.0. 3.2.1 works ok!

System information

Mbed TLS version v3.3.0:
Operating system and version: windows xp and later
Configuration (if not default, please attach mbedtls_config.h): platform default
Compiler and options (if you used a pre-built binary, please indicate how you obtained it): Visual Studio 15 2017 -Tv141_xp so its MSVC with xp toolchain.

Additional environment information:
buld with cpp17 standard

Expected behavior

success build!

Actual behavior

bunch of error messages:

c:\proj\_deps\mbedtls-src\include\psa/crypto.h(118): error C2526: 'psa_key_attributes_init': C linkage function cannot return C++ class 'psa_key_attributes_s' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa\crypto_types.h(437): note: see declaration of 'psa_key_attributes_s'
c:\proj\_deps\mbedtls-src\include\psa/crypto.h(940): error C2526: 'psa_hash_operation_init': C linkage function cannot return C++ class 'psa_hash_operation_s' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(930): note: see declaration of 'psa_hash_operation_s'
c:\proj\_deps\mbedtls-src\include\psa/crypto.h(1299): error C2526: 'psa_mac_operation_init': C linkage function cannot return C++ class 'psa_mac_operation_s' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(1289): note: see declaration of 'psa_mac_operation_s'
c:\proj\_deps\mbedtls-src\include\psa/crypto.h(1712): error C2526: 'psa_cipher_operation_init': C linkage function cannot return C++ class 'psa_cipher_operation_s' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(1702): note: see declaration of 'psa_cipher_operation_s'
c:\proj\_deps\mbedtls-src\include\psa/crypto.h(2230): error C2526: 'psa_aead_operation_init': C linkage function cannot return C++ class 'psa_aead_operation_s' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(2220): note: see declaration of 'psa_aead_operation_s'
c:\proj\_deps\mbedtls-src\include\psa/crypto.h(3217): error C2526: 'psa_key_derivation_operation_init': C linkage function cannot return C++ class 'psa_key_derivation_s' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(3207): note: see declaration of 'psa_key_derivation_s'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(96): error C2556: 'psa_hash_operation_s psa_hash_operation_init(void)': overloaded function differs only by return type from 'void psa_hash_operation_init(void)' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(940): note: see declaration of 'psa_hash_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(95): error C2371: 'psa_hash_operation_init': redefinition; different basic types [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(940): note: see declaration of 'psa_hash_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(121): error C2556: 'psa_cipher_operation_s psa_cipher_operation_init(void)': overloaded function differs only by return type from 'void psa_cipher_operation_init(void)' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(1712): note: see declaration of 'psa_cipher_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(120): error C2371: 'psa_cipher_operation_init': redefinition; different basic types [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(1712): note: see declaration of 'psa_cipher_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(146): error C2556: 'psa_mac_operation_s psa_mac_operation_init(void)': overloaded function differs only by return type from 'void psa_mac_operation_init(void)' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(1299): note: see declaration of 'psa_mac_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(145): error C2371: 'psa_mac_operation_init': redefinition; different basic types [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(1299): note: see declaration of 'psa_mac_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(179): error C2556: 'psa_aead_operation_s psa_aead_operation_init(void)': overloaded function differs only by return type from 'void psa_aead_operation_init(void)' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(2230): note: see declaration of 'psa_aead_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(178): error C2371: 'psa_aead_operation_init': redefinition; different basic types [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(2230): note: see declaration of 'psa_aead_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(286): error C2556: 'psa_key_derivation_s psa_key_derivation_operation_init(void)': overloaded function differs only by return type from 'void psa_key_derivation_operation_init(void)' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(3217): note: see declaration of 'psa_key_derivation_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(284): error C2371: 'psa_key_derivation_operation_init': redefinition; different basic types [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(3217): note: see declaration of 'psa_key_derivation_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(374): error C2556: 'psa_key_attributes_s psa_key_attributes_init(void)': overloaded function differs only by return type from 'void psa_key_attributes_init(void)' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(118): note: see declaration of 'psa_key_attributes_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_struct.h(373): error C2371: 'psa_key_attributes_init': redefinition; different basic types [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa/crypto.h(118): note: see declaration of 'psa_key_attributes_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1165): error C2526: 'psa_pake_cipher_suite_init': C linkage function cannot return C++ class 'psa_pake_cipher_suite_s' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1161): note: see declaration of 'psa_pake_cipher_suite_s'
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1292): error C2526: 'psa_pake_operation_init': C linkage function cannot return C++ class 'psa_pake_operation_s' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1288): note: see declaration of 'psa_pake_operation_s'
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1941): error C2556: 'psa_pake_cipher_suite_s psa_pake_cipher_suite_init(void)': overloaded function differs only by return type from 'void psa_pake_cipher_suite_init(void)' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1165): note: see declaration of 'psa_pake_cipher_suite_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1940): error C2371: 'psa_pake_cipher_suite_init': redefinition; different basic types [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1165): note: see declaration of 'psa_pake_cipher_suite_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1947): error C2556: 'psa_pake_operation_s psa_pake_operation_init(void)': overloaded function differs only by return type from 'void psa_pake_operation_init(void)' [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1292): note: see declaration of 'psa_pake_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1946): error C2371: 'psa_pake_operation_init': redefinition; different basic types [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1292): note: see declaration of 'psa_pake_operation_init'
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1948): error C2059: syntax error: '.' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1948): error C2143: syntax error: missing ';' before '}' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1949): error C2059: syntax error: 'return' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1950): error C2059: syntax error: '}' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1950): error C2143: syntax error: missing ';' before '}' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1953): error C2143: syntax error: missing ';' before '}' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\psa\crypto_extra.h(1953): error C2059: syntax error: '}' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/asn1.h(143): error C2143: syntax error: missing ';' before '{' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/asn1.h(143): error C2447: '{': missing function header (old-style formal list?) [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(228): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(228): error C2146: syntax error: missing ';' before identifier 'mbedtls_x509_buf' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(233): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(233): error C2146: syntax error: missing ';' before identifier 'mbedtls_x509_bitstring' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(239): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(239): error C2146: syntax error: missing ';' before identifier 'mbedtls_x509_name' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(244): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(244): error C2146: syntax error: missing ';' before identifier 'mbedtls_x509_sequence' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(267): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(267): error C2143: syntax error: missing ',' before '*' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(280): error C2143: syntax error: missing ';' before '*' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(280): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(280): error C2370: 'mbedtls_x509_name': redefinition; different storage class [c:\proj\_deps\io-build\tools_io.vcxproj]
  c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(239): note: see declaration of 'mbedtls_x509_name'
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(281): error C2065: 'dn': undeclared identifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(281): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(282): error C2448: 'mbedtls_x509_dn_get_next': function-style initializer appears to be a function definition [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(299): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(299): error C2143: syntax error: missing ',' before '*' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(336): error C2061: syntax error: identifier 'mbedtls_x509_name' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(338): error C2061: syntax error: identifier 'mbedtls_x509_buf' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(340): error C2061: syntax error: identifier 'mbedtls_x509_buf' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(342): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(342): error C2143: syntax error: missing ',' before '*' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(346): error C2061: syntax error: identifier 'mbedtls_x509_buf' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(347): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(347): error C2143: syntax error: missing ',' before '*' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(353): error C2061: syntax error: identifier 'mbedtls_x509_buf' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(355): error C2061: syntax error: identifier 'mbedtls_x509_buf' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(357): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509.h(357): error C2143: syntax error: missing ',' before '*' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(54): error C3646: 'raw': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(54): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(56): error C3646: 'serial': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(56): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(64): error C3646: 'entry_ext': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(64): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(79): error C3646: 'raw': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(79): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(80): error C3646: 'tbs': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(80): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(83): error C3646: 'sig_oid': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(83): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(85): error C3646: 'issuer_raw': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(85): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(87): error C3646: 'issuer': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(87): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(94): error C3646: 'crl_ext': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(94): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(96): error C3646: 'private_sig_oid2': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(96): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(97): error C3646: 'private_sig': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crl.h(97): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(58): error C3646: 'raw': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(58): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(59): error C3646: 'tbs': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(59): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(62): error C3646: 'serial': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(62): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(63): error C3646: 'sig_oid': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(63): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(65): error C3646: 'issuer_raw': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(65): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(66): error C3646: 'subject_raw': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(66): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(68): error C3646: 'issuer': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(68): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(69): error C3646: 'subject': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(69): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(74): error C3646: 'pk_raw': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(74): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(77): error C3646: 'issuer_id': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(77): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(78): error C3646: 'subject_id': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(78): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(79): error C3646: 'v3_ext': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(79): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(80): error C3646: 'subject_alt_names': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(80): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(82): error C3646: 'certificate_policies': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(82): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(90): error C3646: 'ext_key_usage': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(90): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(94): error C3646: 'private_sig': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(94): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(122): error C3646: 'type_id': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(122): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(133): error C3646: 'oid': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(133): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(134): error C3646: 'val': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(134): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(154): error C3646: 'unstructured_name': unknown override specifier [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(154): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(454): error C2061: syntax error: identifier 'mbedtls_x509_buf' [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(628): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [c:\proj\_deps\io-build\tools_io.vcxproj]
c:\proj\_deps\mbedtls-src\include\mbedtls/x509_crt.h(628): error C2143: syntax error: missing ',' before '*' [c:\proj\_deps\io-build\tools_io.vcxproj]
C:\projects\mbedtls_test\libs\tools_io\sslsocketio.cpp(225): warning C4244: 'argument': conversion from '_Rep' to 'uint32_t', possible loss of data [c:\proj\_deps\io-build\tools_io.vcxproj]

Steps to reproduce

Additional information

cmake project standard - c++17
cmake args: -G"Visual Studio 15 2017" -Tv141_xp

@tom-cosgrove-arm
Copy link
Contributor

If I build Mbed TLS itself with cmake and "args -G"Visual Studio 15 2017" -Tv141_xp" it builds correctly. (Once I add "support to build C++ apps for XP" - a no-longer-supported-by-its-developer operating system.)

I note you have Mbed TLS in c:\proj\_deps\mbedtls-src but you are building a source file from C:\projects\mbedtls_test\libs\tools_io, and you've only included a part of the error messages.

We do ask that people reporting issues give us enough information to replicate the problem, which this isn't.

Can you give a bit more information about exactly what you are doing, and (a link to) a full transcript of the build?

In addition, if 3.2.1 is working for you, and 3.3 isn't, you could actually determine what has caused this breakage, making it easier for us to fix!

@swex
Copy link
Author

swex commented Feb 11, 2023

C projects builds and works ok, but C++ fails, with strange C linkage function cannot return C++ class 'psa_key_attributes_s' and more, I thought it may be fixed by including all mbedtls headers inside #extern "C" block but it didn't help.
here is a complete example:

bugreport.zip
build it under windows like below:

mkdir build
cd build
cmake ..  -G"Visual Studio 15 2017" -Tv141_xp
cmake --build . --target bugreport

@gilles-peskine-arm
Copy link
Contributor

Does it work without -Tv141_xp?

Checking on Linux, g++ -std=c++17 and clang++ -std=c++17 work fine. On our CI, we test with Visual Studio 2017, but not with an XP target, and we test the build of a C++ program, but only with GCC.

Given that you're observing not just link errors but also syntax error, there's more to it than a missing extern "C". (Which could happen, but we do test for it.) It looks like either a language dialect problem (but surely C++17 has all the C99 features we use in headers) or some macro name that we use is predefined (but what could it be?).

@swex
Copy link
Author

swex commented Feb 11, 2023

No, it does not. It fails with the same messages with just -G"Visual Studio 15 2017"

@tom-cosgrove-arm
Copy link
Contributor

tom-cosgrove-arm commented Feb 12, 2023

Okay, a simpler reproducer

D:\home\tom\projects\mbedtls\pr7087>dir /b
CMakeLists.txt
main.cpp

D:\home\tom\projects\mbedtls\pr7087>type main.cpp
#include "psa/crypto.h"

int main()
{
    return 0;
}

D:\home\tom\projects\mbedtls\pr7087>type CMakeLists.txt
cmake_minimum_required(VERSION 3.15)

project(bugreport LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)

FetchContent_Declare(
        mbedtls
        GIT_REPOSITORY https://github.com/ARMmbed/mbedtls.git
        GIT_TAG v3.3.0
        GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(mbedtls)

add_executable(bugreport main.cpp)
target_link_libraries(bugreport mbedtls)
install(TARGETS bugreport
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

D:\home\tom\projects\mbedtls\pr7087>cmake -G "Visual Studio 15 2017" .
-- Selecting Windows SDK version 10.0.20348.0 to target Windows 10.0.19044.
-- The CXX compiler identification is MSVC 19.16.27045.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- The C compiler identification is MSVC 19.16.27045.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found Python3: C:/apps/python39/python.exe (found version "3.9.10") found components: Interpreter
-- Looking for pthread.h
-- Looking for pthread.h - not found
-- Found Threads: TRUE
-- Configuring done
-- Generating done
-- Build files have been written to: D:/home/tom/projects/mbedtls/pr7087

D:\home\tom\projects\mbedtls\pr7087>cmake --build .
:
:
  main.cpp
D:\home\tom\projects\mbedtls\pr7087\_deps\mbedtls-src\include\psa/crypto.h(118): error C2526: 'psa_key_attributes_init': C linkage function cannot return C++ class
 'psa_key_attributes_s' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
  d:\home\tom\projects\mbedtls\pr7087\_deps\mbedtls-src\include\psa\crypto_types.h(437): note: see declaration of 'psa_key_attributes_s'
:
d:\home\tom\projects\mbedtls\pr7087\_deps\mbedtls-src\include\psa\crypto_extra.h(1946): error C2371: 'psa_pake_operation_init': redefinition; different basic types 
 [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
  d:\home\tom\projects\mbedtls\pr7087\_deps\mbedtls-src\include\psa\crypto_extra.h(1292): note: see declaration of 'psa_pake_operation_init'
d:\home\tom\projects\mbedtls\pr7087\_deps\mbedtls-src\include\psa\crypto_extra.h(1948): error C2059: syntax error: '.' [D:\home\tom\projects\mbedtls\pr7087\bugrepo 
rt.vcxproj]
d:\home\tom\projects\mbedtls\pr7087\_deps\mbedtls-src\include\psa\crypto_extra.h(1948): error C2143: syntax error: missing ';' before '}' [D:\home\tom\projects\mbe 
dtls\pr7087\bugreport.vcxproj]
:

@tom-cosgrove-arm
Copy link
Contributor

tom-cosgrove-arm commented Feb 12, 2023

And more information.

This simple main.cpp builds without errors

#ifdef __cplusplus
extern "C" {
#endif

struct foo_s {
    int foo_int;
};

typedef struct foo_s foo_t;

foo_t get_a_foo(int search);

#ifdef __cplusplus
}
#endif

int main()
{
    return 0;
}

but THIS one doesn't:

#ifdef __cplusplus
extern "C" {
#endif

typedef struct foo_s foo_t;

foo_t get_a_foo(int search);

struct foo_s {
    int foo_int;
};

#ifdef __cplusplus
}
#endif

int main()
{
    return 0;
}

complaining:

  main.cpp
D:\home\tom\projects\mbedtls\pr7087\main.cpp(8): error C2526: 'get_a_foo': C linkage function cannot return C++ class 'foo_s' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
  D:\home\tom\projects\mbedtls\pr7087\main.cpp(6): note: see declaration of 'foo_s'

@tom-cosgrove-arm
Copy link
Contributor

And of course, the problem is returning a structure (rather than a pointer-to-structure) that the compiler hasn't seen at that point.

Pointer-to-structure forward declarations do compile without complaint

#ifdef __cplusplus
extern "C" {
#endif

typedef struct foo_s *foo_t;

foo_t get_a_foo(int search);

#ifdef __cplusplus
}
#endif

int main()
{
    return 0;
}

@tom-cosgrove-arm
Copy link
Contributor

tom-cosgrove-arm commented Feb 12, 2023

So the issue in Mbed TLS is (at least - there may be other problems hiding behind this) functions such as

psa/crypto.c:
/** Return an initial value for a key attributes structure.
 */
static psa_key_attributes_t psa_key_attributes_init(void);

and

crypto_extra.h:
/** Return an initial value for a PAKE cipher suite object.
 */
static psa_pake_cipher_suite_t psa_pake_cipher_suite_init(void);
:
:
/** Return an initial value for a PAKE operation object.
 */
static psa_pake_operation_t psa_pake_operation_init(void);

which are returning structures that, at the time the compiler sees the function definition, haven't been fully defined, only forward-declared.

@tom-cosgrove-arm
Copy link
Contributor

tom-cosgrove-arm commented Feb 12, 2023

... and this seems to be a Visual Studio problem, rather than a generic C++ problem (at least, this isn't a problem on macOS with clang++)

@tom-cosgrove-arm
Copy link
Contributor

tom-cosgrove-arm commented Feb 12, 2023

And finally, the syntax errors are coming from the following, where the definition of PSA_PAKE_OPERATION_INIT is because MBEDTLS_PSA_BUILTIN_PAKE is defined

#define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, 0, 0,              \
                                 NULL, 0                ,               \
                                 PSA_PAKE_ROLE_NONE, {0}, 0, 0,         \
                                 {.dummy = 0}}
:
static inline struct psa_pake_operation_s psa_pake_operation_init(void)
{
    const struct psa_pake_operation_s v = PSA_PAKE_OPERATION_INIT;
    return v;
}

leads to

d:\home\tom\projects\mbedtls\pr7087\_deps\mbedtls-src\include\psa\crypto_extra.h(1960): error C2059: syntax error: '.' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]

where line 1960 is the v = PSA_PAKE_OPERATION_INIT; line.

This is a bit weird, since Visual Studio is supposed to support designated initialisers since VS2013. Maybe a problem because it's a union element?

@tom-cosgrove-arm
Copy link
Contributor

tom-cosgrove-arm commented Feb 12, 2023

... and a demonstrator for the initialiser problem

#ifdef __cplusplus
extern "C" {
#endif

struct foo_s {
    unsigned int state;
    union {
        int bar;
        char dummy;
    } ctx;
};
#define FOO_INIT { 0, { .dummy = 0 } }

static inline struct foo_s foo_init(void)
{
    const struct foo_s f = FOO_INIT;
    return f;
}

#ifdef __cplusplus
}
#endif

int main()
{
    return 0;
}

which leads to

D:\home\tom\projects\mbedtls\pr7087\main.cpp(16): error C2059: syntax error: '.' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
D:\home\tom\projects\mbedtls\pr7087\main.cpp(16): error C2143: syntax error: missing ';' before '}' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
D:\home\tom\projects\mbedtls\pr7087\main.cpp(17): error C2059: syntax error: 'return' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
D:\home\tom\projects\mbedtls\pr7087\main.cpp(18): error C2059: syntax error: '}' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
D:\home\tom\projects\mbedtls\pr7087\main.cpp(18): error C2143: syntax error: missing ';' before '}' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
D:\home\tom\projects\mbedtls\pr7087\main.cpp(21): error C2143: syntax error: missing ';' before '}' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
D:\home\tom\projects\mbedtls\pr7087\main.cpp(21): error C2059: syntax error: '}' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
D:\home\tom\projects\mbedtls\pr7087\main.cpp(25): error C2143: syntax error: missing ';' before '{' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]
D:\home\tom\projects\mbedtls\pr7087\main.cpp(25): error C2447: '{': missing function header (old-style formal list?) [D:\home\tom\projects\mbedtls\pr7087\bugreport .vcxproj]

(what silences the compiler here is #define FOO_INIT { 0, { 0 } } - but not great for initialising dummy!)

@tom-cosgrove-arm
Copy link
Contributor

And here is a diff which silences all of the errors. Probably not exactly what we'd want to commit, though

diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 03181ed3..79164417 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -103,6 +103,10 @@ psa_status_t psa_crypto_init(void);
 
 /**@}*/
 
+/* The file "crypto_struct.h" contains definitions for
+ * implementation-specific structs that are declared above. */
+#include "crypto_struct.h"
+
 /** \addtogroup attributes
  * @{
  */
@@ -4053,10 +4057,6 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
  * macros whose definitions are implementation-specific. */
 #include "crypto_sizes.h"
 
-/* The file "crypto_struct.h" contains definitions for
- * implementation-specific structs that are declared above. */
-#include "crypto_struct.h"
-
 /* The file "crypto_extra.h" contains vendor-specific definitions. This
  * can include vendor-defined algorithms, extra functions, etc. */
 #include "crypto_extra.h"
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index 33e2e77b..c1c7ec3a 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -1152,6 +1152,15 @@ typedef uint32_t psa_pake_primitive_t;
  */
 #define PSA_PAKE_STEP_ZK_PROOF                  ((psa_pake_step_t)0x03)
 
+struct psa_pake_cipher_suite_s
+{
+    psa_algorithm_t algorithm;
+    psa_pake_primitive_type_t type;
+    psa_pake_family_t family;
+    uint16_t  bits;
+    psa_algorithm_t hash;
+};
+
 /** The type of the data structure for PAKE cipher suites.
  *
  * This is an implementation-defined \c struct. Applications should not
@@ -1257,6 +1266,39 @@ static psa_algorithm_t psa_pake_cs_get_hash(
 static void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite,
                                   psa_algorithm_t hash );
 
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
+#include <mbedtls/ecjpake.h>
+/* Note: the format for mbedtls_ecjpake_read/write function has an extra
+ * length byte for each step, plus an extra 3 bytes for ECParameters in the
+ * server's 2nd round. */
+#define MBEDTLS_PSA_PAKE_BUFFER_SIZE ( ( 3 + 1 + 65 + 1 + 65 + 1 + 32 ) * 2 )
+#endif
+
+struct psa_pake_operation_s
+{
+    psa_algorithm_t MBEDTLS_PRIVATE(alg);
+    unsigned int MBEDTLS_PRIVATE(state);
+    unsigned int MBEDTLS_PRIVATE(sequence);
+#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
+    unsigned int MBEDTLS_PRIVATE(input_step);
+    unsigned int MBEDTLS_PRIVATE(output_step);
+    uint8_t* MBEDTLS_PRIVATE(password);
+    size_t MBEDTLS_PRIVATE(password_len);
+    psa_pake_role_t MBEDTLS_PRIVATE(role);
+    uint8_t MBEDTLS_PRIVATE(buffer[MBEDTLS_PSA_PAKE_BUFFER_SIZE]);
+    size_t MBEDTLS_PRIVATE(buffer_length);
+    size_t MBEDTLS_PRIVATE(buffer_offset);
+#endif
+    union
+    {
+        /* Make the union non-empty even with no supported algorithms. */
+        uint8_t dummy;
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
+        mbedtls_ecjpake_context ecjpake;
+#endif
+    } MBEDTLS_PRIVATE(ctx);
+};
+
 /** The type of the state data structure for PAKE operations.
  *
  * Before calling any function on a PAKE operation object, the application
@@ -1831,20 +1873,11 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation );
 #define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, 0, 0,              \
                                  NULL, 0                ,               \
                                  PSA_PAKE_ROLE_NONE, {0}, 0, 0,         \
-                                 {.dummy = 0}}
+                                 {0}}
 #else
 #define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, {0}}
 #endif
 
-struct psa_pake_cipher_suite_s
-{
-    psa_algorithm_t algorithm;
-    psa_pake_primitive_type_t type;
-    psa_pake_family_t family;
-    uint16_t  bits;
-    psa_algorithm_t hash;
-};
-
 static inline psa_algorithm_t psa_pake_cs_get_algorithm(
                         const psa_pake_cipher_suite_t *cipher_suite )
 {
@@ -1904,39 +1937,6 @@ static inline void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite,
         cipher_suite->hash = hash;
 }
 
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
-#include <mbedtls/ecjpake.h>
-/* Note: the format for mbedtls_ecjpake_read/write function has an extra
- * length byte for each step, plus an extra 3 bytes for ECParameters in the
- * server's 2nd round. */
-#define MBEDTLS_PSA_PAKE_BUFFER_SIZE ( ( 3 + 1 + 65 + 1 + 65 + 1 + 32 ) * 2 )
-#endif
-
-struct psa_pake_operation_s
-{
-    psa_algorithm_t MBEDTLS_PRIVATE(alg);
-    unsigned int MBEDTLS_PRIVATE(state);
-    unsigned int MBEDTLS_PRIVATE(sequence);
-#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
-    unsigned int MBEDTLS_PRIVATE(input_step);
-    unsigned int MBEDTLS_PRIVATE(output_step);
-    uint8_t* MBEDTLS_PRIVATE(password);
-    size_t MBEDTLS_PRIVATE(password_len);
-    psa_pake_role_t MBEDTLS_PRIVATE(role);
-    uint8_t MBEDTLS_PRIVATE(buffer[MBEDTLS_PSA_PAKE_BUFFER_SIZE]);
-    size_t MBEDTLS_PRIVATE(buffer_length);
-    size_t MBEDTLS_PRIVATE(buffer_offset);
-#endif
-    union
-    {
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
-        mbedtls_ecjpake_context ecjpake;
-#endif
-        /* Make the union non-empty even with no supported algorithms. */
-        uint8_t dummy;
-    } MBEDTLS_PRIVATE(ctx);
-};
-
 static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init( void )
 {
     const struct psa_pake_cipher_suite_s v = PSA_PAKE_CIPHER_SUITE_INIT;

@tom-cosgrove-arm tom-cosgrove-arm added bug size-m Estimated task size: medium (~1w) priority-medium Medium priority - this can be reviewed as time permits labels Feb 12, 2023
@tom-cosgrove-arm
Copy link
Contributor

tom-cosgrove-arm commented Feb 12, 2023

... and to use that diff, write it to a file mbedtls.diff in the same directory as the CMakeLists.txt file, and add a PATCH_COMMAND to it:

cmake_minimum_required(VERSION 3.15)

project(bugreport LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)

FetchContent_Declare(
        mbedtls
        GIT_REPOSITORY https://github.com/ARMmbed/mbedtls.git
        GIT_TAG v3.3.0
        GIT_SHALLOW TRUE
        PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/mbedtls.diff
)
FetchContent_MakeAvailable(mbedtls)

add_executable(bugreport main.cpp)
target_link_libraries(bugreport mbedtls)
install(TARGETS bugreport
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

With this change, the very simple main.cpp with just #include <psa/crypto.h> and main() now compiles cleanly for me from scratch.

@gilles-peskine-arm
Copy link
Contributor

gilles-peskine-arm commented Feb 12, 2023

@tom-cosgrove-arm Thanks for investigating!

Is there a bug in our code or not? As far as I can tell it's conforming C99, which is all we promise. We also try to make it compliant to reasonably modern C++, but I don't know C++ well enough: are we using features that aren't in modern C++, is it a bug in old-but-still-supported versions of Visual Studio when compiling C++ code, or is that a bug in some old runtime that we don't care about (sorry, but Windows XP is not a target we care about anymore)?

Getting rid of named initializers for the INIT macros wouldn't be a big deal. We have the dummy member precisely so we can write initializers without having to worry about the content of the union that depends on the configuration. We can assume that it's always the first member.

On the other hand, your second patch doesn't look right. crypto_struct.h includes crypto_sizes.h (now via crypto_driver_common.h), so it doesn't make sense to move it above the including of crypto_sizes.h in crypto.h.

@tom-cosgrove-arm
Copy link
Contributor

Is there a bug in our code or not?

Honestly, I'm not really sure!

The minimal reproducer (#include <psa/crypto.h> under C++) works when compiled with clang++, but not Visual Studio. The issue is almost certainly with Visual Studio, but that doesn't help us if we want C++ projects to build using Mbed TLS using it - we have to work around the problems.

It's nothing to do with XP - it's still an issue when building just with cmake -G "Visual Studio 15 2017" ..

On the other hand, your second patch doesn't look right. crypto_struct.h includes crypto_sizes.h [...] so it doesn't make sense to move it above the including of crypto_sizes.h in crypto.h.

Oh, I'm not suggesting that as a change we make - it would have been a PR in that case. I don't grok the PSA header structure well enough yet to do that.

What Visual Studio requires is: any function that returns a structure (rather than a pointer to a structure) must have the structure fully defined before the declaration of that function. (It thinks any forward-declared structure is going to be a C++ class!) Moving the include achieves this as a proof-of-concept, but I doubt would be the best solution.

@gilles-peskine-arm
Copy link
Contributor

Designated initializers have long existed as a GCC extension, but they were only added to C++ in C++20. We don't have an explicit minimum version of the C++ language to support our header files, but C++20 is too recent. So this is a bug in our code, and we can check for it on the CI:

% g++ -std=c++98 -pedantic -Werror initializer.cpp
initializer.cpp: In function ‘foo_s foo_init()’:
initializer.cpp:12:25: error: C++ designated initializers only available with ‘-std=c++2a’ or ‘-std=gnu++2a’ [-Werror=pedantic]
   12 | #define FOO_INIT { 0, { .dummy = 0 } }
      |                         ^
initializer.cpp:16:28: note: in expansion of macro ‘FOO_INIT’
   16 |     const struct foo_s f = FOO_INIT;
      |                            ^~~~~~~~
cc1plus: all warnings being treated as errors

(We might choose c++11 instead of c++98.)


GCC doesn't have any problem with the linkage involving a forward declaration, but Clang does. So this is a bug in our code, and we can check it on the CI.

% xenial clang++ -Werror forward.cpp
forward.cpp:7:7: error: 'get_a_foo' has C-linkage specified, but returns
      incomplete type 'foo_t' (aka 'foo_s') which could be incompatible with C
      [-Werror,-Wreturn-type-c-linkage]
foo_t get_a_foo(int search);
      ^
1 error generated.

Therefore the goals of this issue are:

  • In tests/scripts/all.sh, try building cpp_dummy_build both with GCC and Clang, both in pedantic mode for C++98 (or C++11?).
  • Don't use designated initializers in public headers. We keep initializers close to the type definition, so that won't harm readability much.
  • Don't declare a function that returns a structure until the structure is defined. I'm not sure how much we'll have to change there. We can add new headers, but we need to preserve some of the current header division: specifically, implementations that provide a client-server structure expose an alternative crypto_struct.h on the client side where operation structures are adjusted (generally, to just contain a handle to the operation).

@gilles-peskine-arm gilles-peskine-arm added component-psa PSA keystore/dispatch layer (storage, drivers, …) component-test Test framework and CI scripts labels Feb 14, 2023
@gilles-peskine-arm
Copy link
Contributor

gilles-peskine-arm commented Feb 14, 2023

At this stage of the analysis, I think the fix will be in the high size-S to low size-M range.

@jamiebird-arm
Copy link

I'm also facing this issue. I made an attempt at fixing this in PR #7174, similar to your solution @tom-cosgrove-arm of moving the crypto_struct.h include to the start, but this introduced other issues with clang which the CI tests highlighted.

Is there a fix expected for this?

@gilles-peskine-arm
Copy link
Contributor

We definitely intend to fix this, however I can't give a timeline. For now I'm adding this issue to our task list for the next quarter, but we haven't planned the next quarter yet and I can't guarantee that it'll remain planned. (But conversely we might get around to it sooner depending on how we advance with this quarter's bugfix queue.) Please don't hesitate to submit a PR if you have even a partial fix, as long as it doesn't break the CI (different versions of GCC and Clang have different sets of warnings).

@gilles-peskine-arm
Copy link
Contributor

gilles-peskine-arm commented Mar 3, 2023

I'm trying to reproduce the forward declaration linkage issue with clang on Linux. forward.cpp makes it complain (quoted above), but with cpp_dummy_build.cpp, it only complains about the designated initializer and not about the forward declaration, even with -Wall -Wextra -Werror -std=c++11 -pedantic. @tom-cosgrove-arm Have you been able to reproduce the linkage issue with Clang with the Mbed TLS headers?

daantimmer added a commit to philips-software/amp-embedded-infra-lib that referenced this issue Mar 27, 2023
There is a known issue with building 3.3.0 using visual studio
- bugtracker: Mbed-TLS/mbedtls#7087
rjaegers added a commit to philips-software/amp-embedded-infra-lib that referenced this issue Mar 28, 2023
feat: Downgrade mbedtls to 3.2.1 from 3.3.0

There is a known issue with building 3.3.0 using visual studio
- bugtracker: Mbed-TLS/mbedtls#7087

Co-authored-by: Ron <45816308+rjaegers@users.noreply.github.com>
@daverodgman daverodgman added this to Technical debt 2023Q2 in EPICs for Mbed TLS Apr 4, 2023
@daverodgman daverodgman removed this from Technical debt 2023Q2 in Backlog for Mbed TLS Apr 4, 2023
Jojo-1000 added a commit to enwi/hueplusplus that referenced this issue May 2, 2023
@kleuter
Copy link

kleuter commented May 10, 2023

This issue is the reason why people can't upgrade from 3.2.1 to anything newer unfortunately 😢

@gilles-peskine-arm
Copy link
Contributor

I'm afraid I don't have any bandwidth for this at the moment. If you have a solution that doesn't break anything else, please submit a pull request.

@kleuter
Copy link

kleuter commented May 12, 2023

If interested, here's the fix that worked for me, just minor headers tuning
kleuter@5c25ee4

@RytoEX
Copy link

RytoEX commented May 17, 2023

And finally, the syntax errors are coming from the following, where the definition of PSA_PAKE_OPERATION_INIT is because MBEDTLS_PSA_BUILTIN_PAKE is defined

#define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, 0, 0,              \
                                 NULL, 0                ,               \
                                 PSA_PAKE_ROLE_NONE, {0}, 0, 0,         \
                                 {.dummy = 0}}
:
static inline struct psa_pake_operation_s psa_pake_operation_init(void)
{
    const struct psa_pake_operation_s v = PSA_PAKE_OPERATION_INIT;
    return v;
}

leads to

d:\home\tom\projects\mbedtls\pr7087\_deps\mbedtls-src\include\psa\crypto_extra.h(1960): error C2059: syntax error: '.' [D:\home\tom\projects\mbedtls\pr7087\bugreport.vcxproj]

where line 1960 is the v = PSA_PAKE_OPERATION_INIT; line.

This is a bit weird, since Visual Studio is supposed to support designated initialisers since VS2013. Maybe a problem because it's a union element?

Incidentally, #6567 removed the Designated Initializer in include\psa\crypto_extra.h that was cited here.

enwi pushed a commit to enwi/hueplusplus that referenced this issue May 22, 2023
@aslze
Copy link

aslze commented Aug 4, 2023

The problem seems to persist in mbedTLS 3.4.1, released yesterday. (Visual Studio 2019 here)

@dan-masek
Copy link

This issue is the reason why people can't upgrade from 3.2.1 to anything newer unfortunately 😢

Upgrade? I just tried to re-use a build of 3.2.1 I made for open62541 (still using VS2015) in my C++ app, and ran into the same issues including the header. Managed to simplify the workaround patch of yours a bit further to get it to compile:

diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 211ea8acd..7c3800598 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -24,6 +24,8 @@
 
 #include "crypto_platform.h"
 
+#include "crypto_struct.h"
+
 #include <stddef.h>
 
 #ifdef __DOXYGEN_ONLY__
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index 73da364bc..5377f19aa 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -1152,6 +1152,15 @@ typedef uint32_t psa_pake_primitive_t;
  */
 #define PSA_PAKE_STEP_ZK_PROOF                  ((psa_pake_step_t)0x03)
 
+struct psa_pake_cipher_suite_s
+{
+    psa_algorithm_t algorithm;
+    psa_pake_primitive_type_t type;
+    psa_pake_family_t family;
+    uint16_t  bits;
+    psa_algorithm_t hash;
+};
+
 /** The type of the data structure for PAKE cipher suites.
  *
  * This is an implementation-defined \c struct. Applications should not
@@ -1257,6 +1266,17 @@ static psa_algorithm_t psa_pake_cs_get_hash(
 static void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite,
                                   psa_algorithm_t hash );
 
+
+struct psa_pake_operation_s
+{
+    psa_algorithm_t alg;
+    union
+    {
+        /* Make the union non-empty even with no supported algorithms. */
+        uint8_t dummy;
+    } ctx;
+};
+
 /** The type of the state data structure for PAKE operations.
  *
  * Before calling any function on a PAKE operation object, the application
@@ -1811,15 +1831,6 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation );
  */
 #define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, {0}}
 
-struct psa_pake_cipher_suite_s
-{
-    psa_algorithm_t algorithm;
-    psa_pake_primitive_type_t type;
-    psa_pake_family_t family;
-    uint16_t  bits;
-    psa_algorithm_t hash;
-};
-
 static inline psa_algorithm_t psa_pake_cs_get_algorithm(
                         const psa_pake_cipher_suite_t *cipher_suite )
 {
@@ -1879,16 +1890,6 @@ static inline void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite,
         cipher_suite->hash = hash;
 }
 
-struct psa_pake_operation_s
-{
-    psa_algorithm_t alg;
-    union
-    {
-        /* Make the union non-empty even with no supported algorithms. */
-        uint8_t dummy;
-    } ctx;
-};
-
 static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init( void )
 {
     const struct psa_pake_cipher_suite_s v = PSA_PAKE_CIPHER_SUITE_INIT; 

@gilles-peskine-arm
Copy link
Contributor

Related (but not in scope here) — since 3.6.0 there is a flexible array member in a header (struct psa_key_production_parameters_s in include/psa/crypto_struct.h), which is not valid C++11.

@gilles-peskine-arm
Copy link
Contributor

I've filed the flexible array member as a separate issue: #9020

We (Arm) are going to look for a workaround for the flexible array member issue. The API is going to stay in Mbed TLS 3.6.x, but we'll look at changing it in 4.0. In C++, if worst comes to worst, maybe we'll just disable psa_generate_key_ext and the associated problematic data type when compiling a C++ program, but at least I hope that 3.6.1 will not fail to build because of that.

Please note that we still have no fix for the other C++ issues mentioned in this thread, and we would welcome a pull request if someone can fix them (without changing the API or ABI for C builds of course).

@gilles-peskine-arm gilles-peskine-arm removed their assignment Apr 9, 2024
gouriano pushed a commit to ncbi/ncbi-cxx-toolkit-public that referenced this issue Apr 24, 2024
... including in the default external version to use when explicitly
directed to do so (currently possible only under the traditional Unix
build system).  Formally adjust existing tuneups (whose files have
notably been renamed) and ensure forward declarations for structs
returned by value(!) are in place early enough to avoid errors when
directly using Mbed TLS from C++ under Visual Studio, per
Mbed-TLS/mbedtls#7087.  JIRA: CXX-13565.

git-svn-id: https://anonsvn.ncbi.nlm.nih.gov/repos/v1/trunk/c++@102330 78c7ea69-d796-4a43-9a09-de51944f1b03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug component-psa PSA keystore/dispatch layer (storage, drivers, …) component-test Test framework and CI scripts priority-medium Medium priority - this can be reviewed as time permits size-m Estimated task size: medium (~1w)
Projects
None yet
Development

No branches or pull requests

8 participants