Mbed-TLS / mbedtls

An open source, portable, easy to use, readable and flexible TLS library, and reference implementation of the PSA Cryptography API. Releases are on a varying cadence, typically around 3 - 6 months between releases.
https://www.trustedfirmware.org/projects/mbed-tls/
Other
5.07k stars 2.52k forks source link

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

Open swex opened 1 year ago

swex commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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

tom-cosgrove-arm commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

... 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 commented 1 year ago

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 commented 1 year ago

... 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 commented 1 year ago

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 commented 1 year ago

... 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 commented 1 year ago

@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 commented 1 year ago

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 commented 1 year ago

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:

gilles-peskine-arm commented 1 year ago

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

jamiebird-arm commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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?

kleuter commented 1 year ago

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

gilles-peskine-arm commented 1 year ago

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 commented 1 year ago

If interested, here's the fix that worked for me, just minor headers tuning https://github.com/kleuter/mbedtls/commit/5c25ee42095c29a2e8902affa301d382986c26d3

RytoEX commented 1 year ago

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.

aslze commented 11 months ago

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

dan-masek commented 9 months ago

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 commented 3 months ago

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 commented 3 months ago

I've filed the flexible array member as a separate issue: https://github.com/Mbed-TLS/mbedtls/issues/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).