diff options
author | Robert Sloan <varomodt@google.com> | 2018-01-23 23:04:10 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2018-01-23 23:04:10 +0000 |
commit | 05b7f4d1e470e4c096c502b557f4bc4cbbb95810 (patch) | |
tree | 18f725077b4089ab4c60f4fc19c2b265f9f79bda | |
parent | 7375becf5eb38f8e7cc10f10bb52186e559688f1 (diff) | |
parent | 2b4ddd0ae55a93b3092052ae9e745d033e3acc1a (diff) | |
download | boringssl-05b7f4d1e470e4c096c502b557f4bc4cbbb95810.tar.gz |
NO PARTIAL RERUN external/boringssl: Sync to cb15cfda29c0c60d8d74145b17c93b43a7667837. am: 978112cdf0
am: 2b4ddd0ae5
Change-Id: I2f61e2ac4700bb0c635ce4f0393ca9e001943bd0
36 files changed, 1764 insertions, 884 deletions
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION index 76dfcd61..11fa0f58 100644 --- a/BORINGSSL_REVISION +++ b/BORINGSSL_REVISION @@ -1 +1 @@ -37c6eb4284bea36be9fa41d35b582008f2023dcf +cb15cfda29c0c60d8d74145b17c93b43a7667837 @@ -185,43 +185,43 @@ const uint32_t kOpenSSLReasonValues[] = { 0x28340c5e, 0x283480ac, 0x283500ea, - 0x2c322c99, + 0x2c322cb9, 0x2c3292a5, - 0x2c332ca7, - 0x2c33acb9, - 0x2c342ccd, - 0x2c34acdf, - 0x2c352cfa, - 0x2c35ad0c, - 0x2c362d1f, + 0x2c332cc7, + 0x2c33acd9, + 0x2c342ced, + 0x2c34acff, + 0x2c352d1a, + 0x2c35ad2c, + 0x2c362d3f, 0x2c36832d, - 0x2c372d2c, - 0x2c37ad3e, - 0x2c382d63, - 0x2c38ad7a, - 0x2c392d88, - 0x2c39ad98, - 0x2c3a2daa, - 0x2c3aadbe, - 0x2c3b2dcf, - 0x2c3badee, + 0x2c372d4c, + 0x2c37ad5e, + 0x2c382d83, + 0x2c38ad9a, + 0x2c392da8, + 0x2c39adb8, + 0x2c3a2dca, + 0x2c3aadde, + 0x2c3b2def, + 0x2c3bae0e, 0x2c3c12b7, 0x2c3c92cd, - 0x2c3d2e02, + 0x2c3d2e22, 0x2c3d92e6, - 0x2c3e2e1f, - 0x2c3eae2d, - 0x2c3f2e45, - 0x2c3fae5d, - 0x2c402e6a, + 0x2c3e2e3f, + 0x2c3eae4d, + 0x2c3f2e65, + 0x2c3fae7d, + 0x2c402e8a, 0x2c4091b8, - 0x2c412e7b, - 0x2c41ae8e, + 0x2c412e9b, + 0x2c41aeae, 0x2c42117e, - 0x2c42ae9f, + 0x2c42aebf, 0x2c430720, - 0x2c43ade0, - 0x2c442d51, + 0x2c43ae00, + 0x2c442d71, 0x30320000, 0x30328015, 0x3033001f, @@ -425,153 +425,154 @@ const uint32_t kOpenSSLReasonValues[] = { 0x40541f98, 0x40549fbb, 0x40551fc9, - 0x40559fe6, - 0x40561ff3, - 0x4056a00c, - 0x40572024, - 0x4057a037, - 0x4058204c, - 0x4058a073, - 0x405920a2, - 0x4059a0cf, - 0x405a20e3, - 0x405aa0f3, - 0x405b210b, - 0x405ba11c, - 0x405c212f, - 0x405ca16e, - 0x405d217b, - 0x405da192, - 0x405e21d0, + 0x4055a006, + 0x40562013, + 0x4056a02c, + 0x40572044, + 0x4057a057, + 0x4058206c, + 0x4058a093, + 0x405920c2, + 0x4059a0ef, + 0x405a2103, + 0x405aa113, + 0x405b212b, + 0x405ba13c, + 0x405c214f, + 0x405ca18e, + 0x405d219b, + 0x405da1b2, + 0x405e21f0, 0x405e8ab1, - 0x405f21f1, - 0x405fa1fe, - 0x4060220c, - 0x4060a22e, - 0x40612272, - 0x4061a2aa, - 0x406222c1, - 0x4062a2d2, - 0x406322e3, - 0x4063a2f8, - 0x4064230f, - 0x4064a33b, - 0x40652356, - 0x4065a36d, - 0x40662385, - 0x4066a3af, - 0x406723da, - 0x4067a3fb, - 0x40682422, - 0x4068a443, - 0x40692475, - 0x4069a4a3, - 0x406a24c4, - 0x406aa4e4, - 0x406b266c, - 0x406ba68f, - 0x406c26a5, - 0x406ca920, - 0x406d294f, - 0x406da977, - 0x406e29a5, - 0x406ea9f2, - 0x406f2a11, - 0x406faa49, - 0x40702a5c, - 0x4070aa79, + 0x405f2211, + 0x405fa21e, + 0x4060222c, + 0x4060a24e, + 0x40612292, + 0x4061a2ca, + 0x406222e1, + 0x4062a2f2, + 0x40632303, + 0x4063a318, + 0x4064232f, + 0x4064a35b, + 0x40652376, + 0x4065a38d, + 0x406623a5, + 0x4066a3cf, + 0x406723fa, + 0x4067a41b, + 0x40682442, + 0x4068a463, + 0x40692495, + 0x4069a4c3, + 0x406a24e4, + 0x406aa504, + 0x406b268c, + 0x406ba6af, + 0x406c26c5, + 0x406ca940, + 0x406d296f, + 0x406da997, + 0x406e29c5, + 0x406eaa12, + 0x406f2a31, + 0x406faa69, + 0x40702a7c, + 0x4070aa99, 0x40710800, - 0x4071aa8b, - 0x40722a9e, - 0x4072aab7, - 0x40732acf, + 0x4071aaab, + 0x40722abe, + 0x4072aad7, + 0x40732aef, 0x407394a4, - 0x40742ae3, - 0x4074aafd, - 0x40752b0e, - 0x4075ab22, - 0x40762b30, + 0x40742b03, + 0x4074ab1d, + 0x40752b2e, + 0x4075ab42, + 0x40762b50, 0x4076927b, - 0x40772b55, - 0x4077ab77, - 0x40782b92, - 0x4078abcb, - 0x40792be2, - 0x4079abf8, - 0x407a2c04, - 0x407aac17, - 0x407b2c2c, - 0x407bac3e, - 0x407c2c6f, - 0x407cac78, - 0x407d245e, + 0x40772b75, + 0x4077ab97, + 0x40782bb2, + 0x4078abeb, + 0x40792c02, + 0x4079ac18, + 0x407a2c24, + 0x407aac37, + 0x407b2c4c, + 0x407bac5e, + 0x407c2c8f, + 0x407cac98, + 0x407d247e, 0x407d9eca, - 0x407e2ba7, - 0x407ea083, + 0x407e2bc7, + 0x407ea0a3, 0x407f1c93, 0x407f9a53, 0x40801ea1, 0x40809cbb, 0x40811f46, 0x40819e7b, - 0x40822990, + 0x408229b0, 0x40829a39, - 0x4083205e, - 0x4083a320, + 0x4083207e, + 0x4083a340, 0x40841ccf, - 0x4084a0bb, - 0x40852140, - 0x4085a256, - 0x408621b2, + 0x4084a0db, + 0x40852160, + 0x4085a276, + 0x408621d2, 0x40869ee4, - 0x408729d6, - 0x4087a287, + 0x408729f6, + 0x4087a2a7, 0x40881a9a, - 0x4088a40e, + 0x4088a42e, 0x40891ae9, 0x40899a76, - 0x408a26c5, + 0x408a26e5, 0x408a9884, - 0x408b2c53, - 0x408baa26, - 0x408c2150, + 0x408b2c73, + 0x408baa46, + 0x408c2170, 0x408c98a0, 0x408d1d12, 0x408d9ce3, 0x408e1e2c, - 0x41f42597, - 0x41f92629, - 0x41fe251c, - 0x41fea711, - 0x41ff2802, - 0x420325b0, - 0x420825d2, - 0x4208a60e, - 0x42092500, - 0x4209a648, - 0x420a2557, - 0x420aa537, - 0x420b2577, - 0x420ba5f0, - 0x420c281e, - 0x420ca6de, - 0x420d26f8, - 0x420da72f, - 0x42122749, - 0x421727e5, - 0x4217a78b, - 0x421c27ad, - 0x421f2768, - 0x42212835, - 0x422627c8, - 0x422b2904, - 0x422ba8b2, - 0x422c28ec, - 0x422ca871, - 0x422d2850, - 0x422da8d1, - 0x422e2897, - 0x422ea9bd, + 0x408e9fe6, + 0x41f425b7, + 0x41f92649, + 0x41fe253c, + 0x41fea731, + 0x41ff2822, + 0x420325d0, + 0x420825f2, + 0x4208a62e, + 0x42092520, + 0x4209a668, + 0x420a2577, + 0x420aa557, + 0x420b2597, + 0x420ba610, + 0x420c283e, + 0x420ca6fe, + 0x420d2718, + 0x420da74f, + 0x42122769, + 0x42172805, + 0x4217a7ab, + 0x421c27cd, + 0x421f2788, + 0x42212855, + 0x422627e8, + 0x422b2924, + 0x422ba8d2, + 0x422c290c, + 0x422ca891, + 0x422d2870, + 0x422da8f1, + 0x422e28b7, + 0x422ea9dd, 0x4432072b, 0x4432873a, 0x44330746, @@ -624,69 +625,69 @@ const uint32_t kOpenSSLReasonValues[] = { 0x4c4014c9, 0x4c4092f7, 0x4c4114ed, - 0x50322eb1, - 0x5032aec0, - 0x50332ecb, - 0x5033aedb, - 0x50342ef4, - 0x5034af0e, - 0x50352f1c, - 0x5035af32, - 0x50362f44, - 0x5036af5a, - 0x50372f73, - 0x5037af86, - 0x50382f9e, - 0x5038afaf, - 0x50392fc4, - 0x5039afd8, - 0x503a2ff8, - 0x503ab00e, - 0x503b3026, - 0x503bb038, - 0x503c3054, - 0x503cb06b, - 0x503d3084, - 0x503db09a, - 0x503e30a7, - 0x503eb0bd, - 0x503f30cf, + 0x50322ed1, + 0x5032aee0, + 0x50332eeb, + 0x5033aefb, + 0x50342f14, + 0x5034af2e, + 0x50352f3c, + 0x5035af52, + 0x50362f64, + 0x5036af7a, + 0x50372f93, + 0x5037afa6, + 0x50382fbe, + 0x5038afcf, + 0x50392fe4, + 0x5039aff8, + 0x503a3018, + 0x503ab02e, + 0x503b3046, + 0x503bb058, + 0x503c3074, + 0x503cb08b, + 0x503d30a4, + 0x503db0ba, + 0x503e30c7, + 0x503eb0dd, + 0x503f30ef, 0x503f8382, - 0x504030e2, - 0x5040b0f2, - 0x5041310c, - 0x5041b11b, - 0x50423135, - 0x5042b152, - 0x50433162, - 0x5043b172, - 0x50443181, + 0x50403102, + 0x5040b112, + 0x5041312c, + 0x5041b13b, + 0x50423155, + 0x5042b172, + 0x50433182, + 0x5043b192, + 0x504431a1, 0x5044843f, - 0x50453195, - 0x5045b1b3, - 0x504631c6, - 0x5046b1dc, - 0x504731ee, - 0x5047b203, - 0x50483229, - 0x5048b237, - 0x5049324a, - 0x5049b25f, - 0x504a3275, - 0x504ab285, - 0x504b32a5, - 0x504bb2b8, - 0x504c32db, - 0x504cb309, - 0x504d331b, - 0x504db338, - 0x504e3353, - 0x504eb36f, - 0x504f3381, - 0x504fb398, - 0x505033a7, + 0x504531b5, + 0x5045b1d3, + 0x504631e6, + 0x5046b1fc, + 0x5047320e, + 0x5047b223, + 0x50483249, + 0x5048b257, + 0x5049326a, + 0x5049b27f, + 0x504a3295, + 0x504ab2a5, + 0x504b32c5, + 0x504bb2d8, + 0x504c32fb, + 0x504cb329, + 0x504d333b, + 0x504db358, + 0x504e3373, + 0x504eb38f, + 0x504f33a1, + 0x504fb3b8, + 0x505033c7, 0x505086ef, - 0x505133ba, + 0x505133da, 0x58320f3a, 0x68320efc, 0x68328c6a, @@ -1134,6 +1135,7 @@ const char kOpenSSLReasonStringData[] = "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\0" "MTU_TOO_SMALL\0" "NEGOTIATED_BOTH_NPN_AND_ALPN\0" + "NEGOTIATED_TB_WITHOUT_EMS_OR_RI\0" "NESTED_GROUP\0" "NO_CERTIFICATES_RETURNED\0" "NO_CERTIFICATE_ASSIGNED\0" @@ -424,6 +424,7 @@ cc_defaults { "src/crypto/pool/pool_test.cc", "src/crypto/refcount_test.cc", "src/crypto/rsa_extra/rsa_test.cc", + "src/crypto/self_test.cc", "src/crypto/test/file_test_gtest.cc", "src/crypto/test/gtest_main.cc", "src/crypto/thread_test.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 78623075..46a8465a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,17 +48,18 @@ endif() if(CMAKE_COMPILER_IS_GNUCXX OR CLANG) # Note clang-cl is odd and sets both CLANG and MSVC. We base our configuration - # primarily on our normal Clang one because the MSVC one is mostly - # suppressions for an overaggressive -Wall. - set(C_CXX_FLAGS "-Wall -Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings") + # primarily on our normal Clang one. + set(C_CXX_FLAGS "-Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings") if(MSVC) - # clang-cl sets different default warnings than clang. - set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-unused-parameter -fmsc-version=1900") + # clang-cl sets different default warnings than clang. It also treats -Wall + # as -Weverything, to match MSVC. Instead -W3 is the alias for -Wall. + # See http://llvm.org/viewvc/llvm-project?view=revision&revision=319116 + set(C_CXX_FLAGS "${C_CXX_FLAGS} -W3 -Wno-unused-parameter -fmsc-version=1900") # googletest suppresses warning C4996 via a pragma, but clang-cl does not # honor it. Suppress it here to compensate. See https://crbug.com/772117. set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-deprecated-declarations") else() - set(C_CXX_FLAGS "${C_CXX_FLAGS} -ggdb -fvisibility=hidden -fno-common") + set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wall -ggdb -fvisibility=hidden -fno-common") endif() if(CLANG) diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index 469838a1..3ca223b4 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -53,7 +53,7 @@ if(NOT OPENSSL_NO_ASM) set(PERLASM_STYLE win32n) set(PERLASM_FLAGS "-DOPENSSL_IA32_SSE2") endif() - set(CMAKE_ASM_NASM_FLAGS "-g cv8") + set(CMAKE_ASM_NASM_FLAGS "-gcv8") # On Windows, we use the NASM output, specifically built with Yasm. set(ASM_EXT asm) @@ -260,6 +260,7 @@ add_executable( pool/pool_test.cc refcount_test.cc rsa_extra/rsa_test.cc + self_test.cc test/file_test_gtest.cc thread_test.cc x509/x509_test.cc diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata index 58c91154..eadb25d1 100644 --- a/src/crypto/err/ssl.errordata +++ b/src/crypto/err/ssl.errordata @@ -86,6 +86,7 @@ SSL,167,MISSING_TMP_ECDH_KEY SSL,168,MIXED_SPECIAL_OPERATOR_WITH_GROUPS SSL,169,MTU_TOO_SMALL SSL,170,NEGOTIATED_BOTH_NPN_AND_ALPN +SSL,285,NEGOTIATED_TB_WITHOUT_EMS_OR_RI SSL,171,NESTED_GROUP SSL,172,NO_CERTIFICATES_RETURNED SSL,173,NO_CERTIFICATE_ASSIGNED diff --git a/src/crypto/fipsmodule/bcm.c b/src/crypto/fipsmodule/bcm.c index 1e5742b1..3e1890fc 100644 --- a/src/crypto/fipsmodule/bcm.c +++ b/src/crypto/fipsmodule/bcm.c @@ -87,15 +87,17 @@ #include "rsa/blinding.c" #include "rsa/padding.c" #include "rsa/rsa.c" -#include "tls/kdf.c" #include "rsa/rsa_impl.c" #include "sha/sha1-altivec.c" #include "sha/sha1.c" #include "sha/sha256.c" #include "sha/sha512.c" +#include "tls/kdf.c" -#if defined(BORINGSSL_FIPS) +// MSVC wants to put a NUL byte at the end of non-char arrays and so cannot +// compile this. +#if !defined(_MSC_VER) static void hexdump(const uint8_t *in, size_t len) { for (size_t i = 0; i < len; i++) { @@ -288,41 +290,7 @@ static EC_KEY *self_test_ecdsa_key(void) { return ec_key; } -#if !defined(OPENSSL_ASAN) -// These symbols are filled in by delocate.go. They point to the start and end -// of the module, and the location of the integrity hash, respectively. -extern const uint8_t BORINGSSL_bcm_text_start[]; -extern const uint8_t BORINGSSL_bcm_text_end[]; -extern const uint8_t BORINGSSL_bcm_text_hash[]; -#endif - -static void __attribute__((constructor)) -BORINGSSL_bcm_power_on_self_test(void) { - CRYPTO_library_init(); - -#if !defined(OPENSSL_ASAN) - // Integrity tests cannot run under ASAN because it involves reading the full - // .text section, which triggers the global-buffer overflow detection. - const uint8_t *const start = BORINGSSL_bcm_text_start; - const uint8_t *const end = BORINGSSL_bcm_text_end; - - static const uint8_t kHMACKey[64] = {0}; - uint8_t result[SHA512_DIGEST_LENGTH]; - - unsigned result_len; - if (!HMAC(EVP_sha512(), kHMACKey, sizeof(kHMACKey), start, end - start, - result, &result_len) || - result_len != sizeof(result)) { - goto err; - } - - const uint8_t *expected = BORINGSSL_bcm_text_hash; - - if (!check_test(expected, result, sizeof(result), "FIPS integrity test")) { - goto err; - } -#endif - +int BORINGSSL_self_test(void) { static const uint8_t kAESKey[16] = "BoringCrypto Key"; static const uint8_t kAESIV[16] = {0}; static const uint8_t kPlaintext[64] = @@ -475,6 +443,13 @@ BORINGSSL_bcm_power_on_self_test(void) { 0xf0, 0xcc, 0x81, 0xe5, 0xea, 0x3f, 0xc2, 0x41, 0x7f, 0xd8, }; + EVP_AEAD_CTX aead_ctx; + EVP_AEAD_CTX_zero(&aead_ctx); + RSA *rsa_key = NULL; + EC_KEY *ec_key = NULL; + ECDSA_SIG *sig = NULL; + int ret = 0; + AES_KEY aes_key; uint8_t aes_iv[16]; uint8_t output[256]; @@ -506,7 +481,6 @@ BORINGSSL_bcm_power_on_self_test(void) { size_t out_len; uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; OPENSSL_memset(nonce, 0, sizeof(nonce)); - EVP_AEAD_CTX aead_ctx; if (!EVP_AEAD_CTX_init(&aead_ctx, EVP_aead_aes_128_gcm(), kAESKey, sizeof(kAESKey), 0, NULL)) { goto err; @@ -531,8 +505,6 @@ BORINGSSL_bcm_power_on_self_test(void) { goto err; } - EVP_AEAD_CTX_cleanup(&aead_ctx); - DES_key_schedule des1, des2, des3; DES_cblock des_iv; DES_set_key(&kDESKey1, &des1); @@ -578,7 +550,7 @@ BORINGSSL_bcm_power_on_self_test(void) { goto err; } - RSA *rsa_key = self_test_rsa_key(); + rsa_key = self_test_rsa_key(); if (rsa_key == NULL) { printf("RSA KeyGen failed\n"); goto err; @@ -605,9 +577,7 @@ BORINGSSL_bcm_power_on_self_test(void) { goto err; } - RSA_free(rsa_key); - - EC_KEY *ec_key = self_test_ecdsa_key(); + ec_key = self_test_ecdsa_key(); if (ec_key == NULL) { printf("ECDSA KeyGen failed\n"); goto err; @@ -623,8 +593,7 @@ BORINGSSL_bcm_power_on_self_test(void) { goto err; } - ECDSA_SIG *sig = - ECDSA_do_sign(kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key); + sig = ECDSA_do_sign(kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key); uint8_t ecdsa_r_bytes[sizeof(kECDSASigR)]; uint8_t ecdsa_s_bytes[sizeof(kECDSASigS)]; @@ -639,9 +608,6 @@ BORINGSSL_bcm_power_on_self_test(void) { goto err; } - ECDSA_SIG_free(sig); - EC_KEY_free(ec_key); - // DBRG KAT CTR_DRBG_STATE drbg; if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization, @@ -665,6 +631,58 @@ BORINGSSL_bcm_power_on_self_test(void) { goto err; } + ret = 1; + +err: + EVP_AEAD_CTX_cleanup(&aead_ctx); + RSA_free(rsa_key); + EC_KEY_free(ec_key); + ECDSA_SIG_free(sig); + + return ret; +} + +#if defined(BORINGSSL_FIPS) + +#if !defined(OPENSSL_ASAN) +// These symbols are filled in by delocate.go. They point to the start and end +// of the module, and the location of the integrity hash, respectively. +extern const uint8_t BORINGSSL_bcm_text_start[]; +extern const uint8_t BORINGSSL_bcm_text_end[]; +extern const uint8_t BORINGSSL_bcm_text_hash[]; +#endif + +static void __attribute__((constructor)) +BORINGSSL_bcm_power_on_self_test(void) { + CRYPTO_library_init(); + +#if !defined(OPENSSL_ASAN) + // Integrity tests cannot run under ASAN because it involves reading the full + // .text section, which triggers the global-buffer overflow detection. + const uint8_t *const start = BORINGSSL_bcm_text_start; + const uint8_t *const end = BORINGSSL_bcm_text_end; + + static const uint8_t kHMACKey[64] = {0}; + uint8_t result[SHA512_DIGEST_LENGTH]; + + unsigned result_len; + if (!HMAC(EVP_sha512(), kHMACKey, sizeof(kHMACKey), start, end - start, + result, &result_len) || + result_len != sizeof(result)) { + goto err; + } + + const uint8_t *expected = BORINGSSL_bcm_text_hash; + + if (!check_test(expected, result, sizeof(result), "FIPS integrity test")) { + goto err; + } +#endif + + if (!BORINGSSL_self_test()) { + goto err; + } + return; err: @@ -677,4 +695,7 @@ void BORINGSSL_FIPS_abort(void) { exit(1); } } + #endif // BORINGSSL_FIPS + +#endif // !_MSC_VER diff --git a/src/crypto/internal.h b/src/crypto/internal.h index e6bab02b..95b8d289 100644 --- a/src/crypto/internal.h +++ b/src/crypto/internal.h @@ -116,7 +116,14 @@ #include <assert.h> #include <string.h> -#if !defined(__cplusplus) +#if defined(__GNUC__) && \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 +// |alignas| and |alignof| were added in C11. GCC added support in version 4.8. +// Testing for __STDC_VERSION__/__cplusplus doesn't work because 4.7 already +// reports support for C11. +#define alignas(x) __attribute__ ((aligned (x))) +#define alignof(x) __alignof__ (x) +#elif !defined(__cplusplus) #if defined(_MSC_VER) #define alignas(x) __declspec(align(x)) #define alignof __alignof diff --git a/src/crypto/self_test.cc b/src/crypto/self_test.cc new file mode 100644 index 00000000..c20b5def --- /dev/null +++ b/src/crypto/self_test.cc @@ -0,0 +1,24 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <openssl/crypto.h> + +#include <gtest/gtest.h> + + +TEST(SelfTests, KAT) { +#if !defined(_MSC_VER) + EXPECT_TRUE(BORINGSSL_self_test()); +#endif +} diff --git a/src/include/openssl/base.h b/src/include/openssl/base.h index 9edaa5ca..dea069ab 100644 --- a/src/include/openssl/base.h +++ b/src/include/openssl/base.h @@ -151,7 +151,7 @@ extern "C" { // A consumer may use this symbol in the preprocessor to temporarily build // against multiple revisions of BoringSSL at the same time. It is not // recommended to do so for longer than is necessary. -#define BORINGSSL_API_VERSION 6 +#define BORINGSSL_API_VERSION 7 #if defined(BORINGSSL_SHARED_LIBRARY) diff --git a/src/include/openssl/crypto.h b/src/include/openssl/crypto.h index dc87dd2d..ccf5012c 100644 --- a/src/include/openssl/crypto.h +++ b/src/include/openssl/crypto.h @@ -58,6 +58,10 @@ OPENSSL_EXPORT int CRYPTO_has_asm(void); // which case it returns one. OPENSSL_EXPORT int FIPS_mode(void); +// BORINGSSL_self_test triggers the FIPS KAT-based self tests. It returns one +// on success and zero on error. +OPENSSL_EXPORT int BORINGSSL_self_test(void); + // Deprecated functions. diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h index b868d3f2..7ae82767 100644 --- a/src/include/openssl/ssl.h +++ b/src/include/openssl/ssl.h @@ -2785,6 +2785,33 @@ OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))( SSL *ssl, EVP_PKEY **out_pkey); +// Token Binding. +// +// See draft-ietf-tokbind-protocol-16. + +// SSL_set_token_binding_params sets |params| as the Token Binding Key +// parameters (section 3 of draft-ietf-tokbind-protocol-16) to negotiate on the +// connection. If this function is not called, or if |len| is 0, then this +// endpoint will not attempt to negotiate Token Binding. |params| are provided +// in preference order, with the more preferred parameters at the beginning of +// the list. This function returns 1 on success and 0 on failure. +OPENSSL_EXPORT int SSL_set_token_binding_params(SSL *ssl, const uint8_t *params, + size_t len); + +// SSL_is_token_binding_negotiated returns 1 if Token Binding was negotiated +// on this connection and 0 otherwise. On a server, it is possible for this +// function to return 1 when the client's view of the connection is that Token +// Binding was not negotiated. This occurs when the server indicates a version +// of Token Binding less than the client's minimum version. +OPENSSL_EXPORT int SSL_is_token_binding_negotiated(const SSL *ssl); + +// SSL_get_negotiated_token_binding_param returns the TokenBindingKeyParameters +// enum value that was negotiated. It is only valid to call this function if +// SSL_is_token_binding_negotiated returned 1, otherwise this function returns +// an undefined value. +OPENSSL_EXPORT uint8_t SSL_get_negotiated_token_binding_param(const SSL *ssl); + + // DTLS-SRTP. // // See RFC 5764. @@ -4588,6 +4615,7 @@ OPENSSL_EXPORT bool SealRecord(SSL *ssl, Span<uint8_t> out_prefix, #define SSL_R_EMPTY_HELLO_RETRY_REQUEST 282 #define SSL_R_EARLY_DATA_NOT_IN_USE 283 #define SSL_R_HANDSHAKE_NOT_COMPLETE 284 +#define SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI 285 #define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000 #define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 #define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h index 4b5d2262..682bb9ba 100644 --- a/src/include/openssl/tls1.h +++ b/src/include/openssl/tls1.h @@ -202,6 +202,9 @@ extern "C" { // ExtensionType value from RFC7627 #define TLSEXT_TYPE_extended_master_secret 23 +// ExtensionType value from draft-ietf-tokbind-negotiation-10 +#define TLSEXT_TYPE_token_binding 24 + // ExtensionType value from RFC4507 #define TLSEXT_TYPE_session_ticket 35 diff --git a/src/ssl/handshake_client.cc b/src/ssl/handshake_client.cc index 4c7012b2..4e2158e1 100644 --- a/src/ssl/handshake_client.cc +++ b/src/ssl/handshake_client.cc @@ -757,6 +757,13 @@ static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { return ssl_hs_error; } + if (ssl->token_binding_negotiated && + (!hs->extended_master_secret || !ssl->s3->send_connection_binding)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return ssl_hs_error; + } + ssl->method->next_message(ssl); if (ssl->session != NULL) { diff --git a/src/ssl/internal.h b/src/ssl/internal.h index 91ca1f7e..fb991016 100644 --- a/src/ssl/internal.h +++ b/src/ssl/internal.h @@ -1376,6 +1376,12 @@ struct SSL_HANDSHAKE { // peer_key is the peer's ECDH key for a TLS 1.2 client. Array<uint8_t> peer_key; + // negotiated_token_binding_version is used by a server to store the + // on-the-wire encoding of the Token Binding protocol version to advertise in + // the ServerHello/EncryptedExtensions if the Token Binding extension is to be + // sent. + uint16_t negotiated_token_binding_version; + // server_params, in a TLS 1.2 server, stores the ServerKeyExchange // parameters. It has client and server randoms prepended for signing // convenience. @@ -2606,6 +2612,14 @@ struct SSLConnection { uint8_t *alpn_client_proto_list; unsigned alpn_client_proto_list_len; + // Contains a list of supported Token Binding key parameters. + uint8_t *token_binding_params; + size_t token_binding_params_len; + + // The negotiated Token Binding key parameter. Only valid if + // |token_binding_negotiated| is set. + uint8_t negotiated_token_binding_param; + // renegotiate_mode controls how peer renegotiation attempts are handled. enum ssl_renegotiate_mode_t renegotiate_mode; @@ -2633,6 +2647,9 @@ struct SSLConnection { // we'll advertise support. bool tlsext_channel_id_enabled:1; + // token_binding_negotiated is set if Token Binding was negotiated. + bool token_binding_negotiated:1; + // retain_only_sha256_of_client_certs is true if we should compute the SHA256 // hash of the peer's certificate and then discard it to save memory and // session space. Only effective on the server side. diff --git a/src/ssl/ssl_lib.cc b/src/ssl/ssl_lib.cc index 8f53dcd5..75e438d4 100644 --- a/src/ssl/ssl_lib.cc +++ b/src/ssl/ssl_lib.cc @@ -771,6 +771,7 @@ void SSL_free(SSL *ssl) { SSL_CTX_free(ssl->session_ctx); OPENSSL_free(ssl->supported_group_list); OPENSSL_free(ssl->alpn_client_proto_list); + OPENSSL_free(ssl->token_binding_params); EVP_PKEY_free(ssl->tlsext_channel_id_private); OPENSSL_free(ssl->psk_identity_hint); sk_CRYPTO_BUFFER_pop_free(ssl->client_CA, CRYPTO_BUFFER_free); @@ -2122,6 +2123,28 @@ size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out, size_t max_out) { return 64; } +int SSL_set_token_binding_params(SSL *ssl, const uint8_t *params, size_t len) { + if (len > 256) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + OPENSSL_free(ssl->token_binding_params); + ssl->token_binding_params = (uint8_t *)BUF_memdup(params, len); + if (!ssl->token_binding_params) { + return 0; + } + ssl->token_binding_params_len = len; + return 1; +} + +int SSL_is_token_binding_negotiated(const SSL *ssl) { + return ssl->token_binding_negotiated; +} + +uint8_t SSL_get_negotiated_token_binding_param(const SSL *ssl) { + return ssl->negotiated_token_binding_param; +} + size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) { if (ssl->server || ssl->s3->hs == NULL) { *out_types = NULL; diff --git a/src/ssl/t1_lib.cc b/src/ssl/t1_lib.cc index a8833e05..dafb885d 100644 --- a/src/ssl/t1_lib.cc +++ b/src/ssl/t1_lib.cc @@ -2439,6 +2439,153 @@ static bool ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs, return true; } +// Token Binding +// +// https://tools.ietf.org/html/draft-ietf-tokbind-negotiation-10 + +// The Token Binding version number currently matches the draft number of +// draft-ietf-tokbind-protocol, and when published as an RFC it will be 0x0100. +// Since there are no wire changes to the protocol from draft 13 through the +// current draft (16), this implementation supports all versions in that range. +static uint16_t kTokenBindingMaxVersion = 16; +static uint16_t kTokenBindingMinVersion = 13; + +static bool ext_token_binding_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->token_binding_params == nullptr || SSL_is_dtls(ssl)) { + return true; + } + + CBB contents, params; + if (!CBB_add_u16(out, TLSEXT_TYPE_token_binding) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16(&contents, kTokenBindingMaxVersion) || + !CBB_add_u8_length_prefixed(&contents, ¶ms) || + !CBB_add_bytes(¶ms, ssl->token_binding_params, + ssl->token_binding_params_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_token_binding_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == nullptr) { + return true; + } + + CBS params_list; + uint16_t version; + uint8_t param; + if (!CBS_get_u16(contents, &version) || + !CBS_get_u8_length_prefixed(contents, ¶ms_list) || + !CBS_get_u8(¶ms_list, ¶m) || + CBS_len(¶ms_list) > 0 || + CBS_len(contents) > 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // The server-negotiated version must be less than or equal to our version. + if (version > kTokenBindingMaxVersion) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // If the server-selected version is less than what we support, then Token + // Binding wasn't negotiated (but the extension was parsed successfully). + if (version < kTokenBindingMinVersion) { + return true; + } + + for (size_t i = 0; i < ssl->token_binding_params_len; ++i) { + if (param == ssl->token_binding_params[i]) { + ssl->negotiated_token_binding_param = param; + ssl->token_binding_negotiated = true; + return true; + } + } + + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; +} + +// select_tb_param looks for the first token binding param in +// |ssl->token_binding_params| that is also in |params| and puts it in +// |ssl->negotiated_token_binding_param|. It returns true if a token binding +// param is found, and false otherwise. +static bool select_tb_param(SSL *ssl, Span<const uint8_t> peer_params) { + for (size_t i = 0; i < ssl->token_binding_params_len; ++i) { + uint8_t tb_param = ssl->token_binding_params[i]; + for (uint8_t peer_param : peer_params) { + if (tb_param == peer_param) { + ssl->negotiated_token_binding_param = tb_param; + return true; + } + } + } + return false; +} + +static bool ext_token_binding_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == nullptr || ssl->token_binding_params == nullptr) { + return true; + } + + CBS params; + uint16_t version; + if (!CBS_get_u16(contents, &version) || + !CBS_get_u8_length_prefixed(contents, ¶ms) || + CBS_len(¶ms) == 0 || + CBS_len(contents) > 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // If the client-selected version is less than what we support, then Token + // Binding wasn't negotiated (but the extension was parsed successfully). + if (version < kTokenBindingMinVersion) { + return true; + } + + // If the client-selected version is higher than we support, use our max + // version. Otherwise, use the client's version. + hs->negotiated_token_binding_version = + std::min(version, kTokenBindingMaxVersion); + if (!select_tb_param(ssl, params)) { + return true; + } + + ssl->token_binding_negotiated = true; + return true; +} + +static bool ext_token_binding_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + + if (!ssl->token_binding_negotiated) { + return true; + } + + CBB contents, params; + if (!CBB_add_u16(out, TLSEXT_TYPE_token_binding) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16(&contents, hs->negotiated_token_binding_version) || + !CBB_add_u8_length_prefixed(&contents, ¶ms) || + !CBB_add_u8(¶ms, ssl->negotiated_token_binding_param) || + !CBB_flush(out)) { + return false; + } + + return true; +} // kExtensions contains all the supported extensions. static const struct tls_extension kExtensions[] = { @@ -2608,6 +2755,14 @@ static const struct tls_extension kExtensions[] = { ext_supported_groups_parse_clienthello, dont_add_serverhello, }, + { + TLSEXT_TYPE_token_binding, + NULL, + ext_token_binding_add_clienthello, + ext_token_binding_parse_serverhello, + ext_token_binding_parse_clienthello, + ext_token_binding_add_serverhello, + }, }; #define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension)) @@ -2970,6 +3125,15 @@ static int ssl_scan_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs, static int ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; + + if (ssl->token_binding_negotiated && + !(SSL_get_secure_renegotiation_support(ssl) && + SSL_get_extms_support(ssl))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return -1; + } + int ret = SSL_TLSEXT_ERR_NOACK; int al = SSL_AD_UNRECOGNIZED_NAME; diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc index 0123df7a..50182b1b 100644 --- a/src/ssl/test/bssl_shim.cc +++ b/src/ssl/test/bssl_shim.cc @@ -1725,6 +1725,18 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume, } } + if (config->expected_token_binding_param != -1) { + if (!SSL_is_token_binding_negotiated(ssl)) { + fprintf(stderr, "no Token Binding negotiated\n"); + return false; + } + if (SSL_get_negotiated_token_binding_param(ssl) != + static_cast<uint8_t>(config->expected_token_binding_param)) { + fprintf(stderr, "Token Binding param mismatch\n"); + return false; + } + } + if (config->expect_extended_master_secret && !SSL_get_extms_support(ssl)) { fprintf(stderr, "No EMS for connection when expected\n"); return false; @@ -1970,6 +1982,12 @@ static bool DoConnection(bssl::UniquePtr<SSL_SESSION> *out_session, } } } + if (!config->send_token_binding_params.empty()) { + SSL_set_token_binding_params(ssl.get(), + reinterpret_cast<const uint8_t *>( + config->send_token_binding_params.data()), + config->send_token_binding_params.length()); + } if (!config->host_name.empty() && !SSL_set_tlsext_host_name(ssl.get(), config->host_name.c_str())) { return false; diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go index 15e42ffe..a543e81b 100644 --- a/src/ssl/test/runner/common.go +++ b/src/ssl/test/runner/common.go @@ -122,6 +122,7 @@ const ( extensionSignedCertificateTimestamp uint16 = 18 extensionPadding uint16 = 21 extensionExtendedMasterSecret uint16 = 23 + extensionTokenBinding uint16 = 24 extensionSessionTicket uint16 = 35 extensionOldKeyShare uint16 = 40 // draft-ietf-tls-tls13-16 extensionPreSharedKey uint16 = 41 // draft-ietf-tls-tls13-16 @@ -261,6 +262,8 @@ type ConnectionState struct { PeerCertificates []*x509.Certificate // certificate chain presented by remote peer VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates ChannelID *ecdsa.PublicKey // the channel ID for this connection + TokenBindingNegotiated bool // whether Token Binding was negotiated + TokenBindingParam uint8 // the negotiated Token Binding key parameter SRTPProtectionProfile uint16 // the negotiated DTLS-SRTP protection profile TLSUnique []byte // the tls-unique channel binding SCTList []byte // signed certificate timestamp list @@ -453,6 +456,20 @@ type Config struct { // returned in the ConnectionState. RequestChannelID bool + // TokenBindingParams contains a list of TokenBindingKeyParameters + // (draft-ietf-tokbind-protocol-16) to attempt to negotiate. If + // nil, Token Binding will not be negotiated. + TokenBindingParams []byte + + // TokenBindingVersion contains the serialized ProtocolVersion to + // use when negotiating Token Binding. + TokenBindingVersion uint16 + + // ExpectTokenBindingParams is checked by a server that the client + // sent ExpectTokenBindingParams as its list of Token Binding + // paramters. + ExpectTokenBindingParams []byte + // PreSharedKey, if not nil, is the pre-shared key to use with // the PSK cipher suites. PreSharedKey []byte diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go index 6493aa75..c38fba9a 100644 --- a/src/ssl/test/runner/conn.go +++ b/src/ssl/test/runner/conn.go @@ -78,6 +78,9 @@ type Conn struct { channelID *ecdsa.PublicKey + tokenBindingNegotiated bool + tokenBindingParam uint8 + srtpProtectionProfile uint16 clientVersion uint16 @@ -1812,6 +1815,8 @@ func (c *Conn) ConnectionState() ConnectionState { state.VerifiedChains = c.verifiedChains state.ServerName = c.serverName state.ChannelID = c.channelID + state.TokenBindingNegotiated = c.tokenBindingNegotiated + state.TokenBindingParam = c.tokenBindingParam state.SRTPProtectionProfile = c.srtpProtectionProfile state.TLSUnique = c.firstFinished[:] state.SCTList = c.sctList diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go index e477edf9..ab41e120 100644 --- a/src/ssl/test/runner/handshake_client.go +++ b/src/ssl/test/runner/handshake_client.go @@ -89,6 +89,8 @@ func (c *Conn) clientHandshake() error { alpnProtocols: c.config.NextProtos, duplicateExtension: c.config.Bugs.DuplicateExtension, channelIDSupported: c.config.ChannelID != nil, + tokenBindingParams: c.config.TokenBindingParams, + tokenBindingVersion: c.config.TokenBindingVersion, npnAfterAlpn: c.config.Bugs.SwapNPNAndALPN, extendedMasterSecret: maxVersion >= VersionTLS10, srtpProtectionProfiles: c.config.SRTPProtectionProfiles, @@ -1451,6 +1453,29 @@ func (hs *clientHandshakeState) processServerExtensions(serverExtensions *server return errors.New("server advertised unrequested Channel ID extension") } + if len(serverExtensions.tokenBindingParams) == 1 { + found := false + for _, p := range c.config.TokenBindingParams { + if p == serverExtensions.tokenBindingParams[0] { + c.tokenBindingParam = p + found = true + break + } + } + if !found { + return errors.New("tls: server advertised unsupported Token Binding key param") + } + if serverExtensions.tokenBindingVersion > c.config.TokenBindingVersion { + return errors.New("tls: server's Token Binding version is too new") + } + if c.vers < VersionTLS13 { + if !serverExtensions.extendedMasterSecret || serverExtensions.secureRenegotiation == nil { + return errors.New("server sent Token Binding without EMS or RI") + } + } + c.tokenBindingNegotiated = true + } + if serverExtensions.extendedMasterSecret && c.vers >= VersionTLS13 { return errors.New("tls: server advertised extended master secret over TLS 1.3") } diff --git a/src/ssl/test/runner/handshake_messages.go b/src/ssl/test/runner/handshake_messages.go index 16d858f5..c80b1cfc 100644 --- a/src/ssl/test/runner/handshake_messages.go +++ b/src/ssl/test/runner/handshake_messages.go @@ -281,6 +281,8 @@ type clientHelloMsg struct { alpnProtocols []string duplicateExtension bool channelIDSupported bool + tokenBindingParams []byte + tokenBindingVersion uint16 npnAfterAlpn bool extendedMasterSecret bool srtpProtectionProfiles []uint16 @@ -331,6 +333,8 @@ func (m *clientHelloMsg) equal(i interface{}) bool { eqStrings(m.alpnProtocols, m1.alpnProtocols) && m.duplicateExtension == m1.duplicateExtension && m.channelIDSupported == m1.channelIDSupported && + bytes.Equal(m.tokenBindingParams, m1.tokenBindingParams) && + m.tokenBindingVersion == m1.tokenBindingVersion && m.npnAfterAlpn == m1.npnAfterAlpn && m.extendedMasterSecret == m1.extendedMasterSecret && eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) && @@ -519,6 +523,13 @@ func (m *clientHelloMsg) marshal() []byte { extensions.addU16(extensionChannelID) extensions.addU16(0) // Length is always 0 } + if m.tokenBindingParams != nil { + extensions.addU16(extensionTokenBinding) + tokbindExtension := extensions.addU16LengthPrefixed() + tokbindExtension.addU16(m.tokenBindingVersion) + tokbindParams := tokbindExtension.addU8LengthPrefixed() + tokbindParams.addBytes(m.tokenBindingParams) + } if m.nextProtoNeg && m.npnAfterAlpn { extensions.addU16(extensionNextProtoNeg) extensions.addU16(0) // Length is always 0 @@ -826,6 +837,12 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool { return false } m.channelIDSupported = true + case extensionTokenBinding: + if !body.readU16(&m.tokenBindingVersion) || + !body.readU8LengthPrefixedBytes(&m.tokenBindingParams) || + len(body) != 0 { + return false + } case extensionExtendedMasterSecret: if len(body) != 0 { return false @@ -1116,6 +1133,8 @@ type serverExtensions struct { alpnProtocolEmpty bool duplicateExtension bool channelIDRequested bool + tokenBindingParams []byte + tokenBindingVersion uint16 extendedMasterSecret bool srtpProtectionProfile uint16 srtpMasterKeyIdentifier string @@ -1175,6 +1194,13 @@ func (m *serverExtensions) marshal(extensions *byteBuilder) { extensions.addU16(extensionChannelID) extensions.addU16(0) } + if m.tokenBindingParams != nil { + extensions.addU16(extensionTokenBinding) + tokbindExtension := extensions.addU16LengthPrefixed() + tokbindExtension.addU16(m.tokenBindingVersion) + tokbindParams := tokbindExtension.addU8LengthPrefixed() + tokbindParams.addBytes(m.tokenBindingParams) + } if m.duplicateExtension { // Add a duplicate bogus extension at the beginning and end. extensions.addU16(0xffff) @@ -1303,6 +1329,13 @@ func (m *serverExtensions) unmarshal(data byteReader, version uint16) bool { return false } m.channelIDRequested = true + case extensionTokenBinding: + if !body.readU16(&m.tokenBindingVersion) || + !body.readU8LengthPrefixedBytes(&m.tokenBindingParams) || + len(m.tokenBindingParams) != 1 || + len(body) != 0 { + return false + } case extensionExtendedMasterSecret: if len(body) != 0 { return false diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go index d317d016..dc742593 100644 --- a/src/ssl/test/runner/handshake_server.go +++ b/src/ssl/test/runner/handshake_server.go @@ -1381,6 +1381,21 @@ func (hs *serverHandshakeState) processClientExtensions(serverExtensions *server serverExtensions.channelIDRequested = true } + if config.TokenBindingParams != nil { + if !bytes.Equal(config.ExpectTokenBindingParams, hs.clientHello.tokenBindingParams) { + return errors.New("client did not send expected token binding params") + } + + // For testing, blindly send whatever is set in config, even if + // it is invalid. + serverExtensions.tokenBindingParams = config.TokenBindingParams + serverExtensions.tokenBindingVersion = config.TokenBindingVersion + } + + if len(hs.clientHello.tokenBindingParams) > 0 && (!hs.clientHello.extendedMasterSecret || hs.clientHello.secureRenegotiation == nil) { + return errors.New("client sent Token Binding without EMS and/or RI") + } + if hs.clientHello.srtpProtectionProfiles != nil { SRTPLoop: for _, p1 := range c.config.SRTPProtectionProfiles { diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go index 1f2a20a4..ebe533f0 100644 --- a/src/ssl/test/runner/runner.go +++ b/src/ssl/test/runner/runner.go @@ -343,6 +343,12 @@ type testCase struct { // expectChannelID controls whether the connection should have // negotiated a Channel ID with channelIDKey. expectChannelID bool + // expectTokenBinding controls whether the connection should have + // negotiated Token Binding. + expectTokenBinding bool + // expectedTokenBindingParam is the Token Binding parameter that should + // have been negotiated (if expectTokenBinding is true). + expectedTokenBindingParam uint8 // expectedNextProto controls whether the connection should // negotiate a next protocol via NPN or ALPN. expectedNextProto string @@ -648,6 +654,17 @@ func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool, tr return fmt.Errorf("channel ID unexpectedly negotiated") } + if test.expectTokenBinding { + if !connState.TokenBindingNegotiated { + return errors.New("no Token Binding negotiated") + } + if connState.TokenBindingParam != test.expectedTokenBindingParam { + return fmt.Errorf("expected param %02x, but got %02x", test.expectedTokenBindingParam, connState.TokenBindingParam) + } + } else if connState.TokenBindingNegotiated { + return errors.New("Token Binding unexpectedly negotiated") + } + if expected := test.expectedNextProto; expected != "" { if actual := connState.NegotiatedProtocol; actual != expected { return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected) @@ -1351,6 +1368,13 @@ var tlsVersions = []tlsVersion{ tls13Variant: TLS13Draft22, }, { + name: "TLS13Draft23", + version: VersionTLS13, + excludeFlag: "-no-tls13", + versionWire: tls13Draft23Version, + tls13Variant: TLS13Draft23, + }, + { name: "TLS13Experiment2", version: VersionTLS13, excludeFlag: "-no-tls13", @@ -6149,6 +6173,404 @@ func addExtensionTests() { }) } + // Test Token Binding. + + const maxTokenBindingVersion = 16 + const minTokenBindingVersion = 13 + testCases = append(testCases, testCase{ + testType: serverTest, + name: "TokenBinding-Server-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{0, 1, 2}, + TokenBindingVersion: maxTokenBindingVersion, + }, + expectTokenBinding: true, + expectedTokenBindingParam: 2, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + "-expected-token-binding-param", + "2", + }, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "TokenBinding-Server-UnsupportedParam-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{3}, + TokenBindingVersion: maxTokenBindingVersion, + }, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + }, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "TokenBinding-Server-OldVersion-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{0, 1, 2}, + TokenBindingVersion: minTokenBindingVersion - 1, + }, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + }, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "TokenBinding-Server-NewVersion-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{0, 1, 2}, + TokenBindingVersion: maxTokenBindingVersion + 1, + }, + expectTokenBinding: true, + expectedTokenBindingParam: 2, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + "-expected-token-binding-param", + "2", + }, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "TokenBinding-Server-NoParams-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{}, + TokenBindingVersion: maxTokenBindingVersion, + }, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + }, + shouldFail: true, + expectedError: ":ERROR_PARSING_EXTENSION:", + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "TokenBinding-Server-RepeatedParam" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{0, 1, 2, 2}, + TokenBindingVersion: maxTokenBindingVersion, + }, + expectTokenBinding: true, + expectedTokenBindingParam: 2, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + "-expected-token-binding-param", + "2", + }, + }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-Client-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{2}, + TokenBindingVersion: maxTokenBindingVersion, + ExpectTokenBindingParams: []byte{0, 1, 2}, + }, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{0, 1, 2}), + "-expected-token-binding-param", + "2", + }, + }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-Client-Unexpected-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{2}, + TokenBindingVersion: maxTokenBindingVersion, + }, + tls13Variant: ver.tls13Variant, + shouldFail: true, + expectedError: ":UNEXPECTED_EXTENSION:", + }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-Client-ExtraParams-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{2, 1}, + TokenBindingVersion: maxTokenBindingVersion, + ExpectTokenBindingParams: []byte{0, 1, 2}, + }, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{0, 1, 2}), + "-expected-token-binding-param", + "2", + }, + tls13Variant: ver.tls13Variant, + shouldFail: true, + expectedError: ":ERROR_PARSING_EXTENSION:", + }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-Client-NoParams-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{}, + TokenBindingVersion: maxTokenBindingVersion, + ExpectTokenBindingParams: []byte{0, 1, 2}, + }, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{0, 1, 2}), + "-expected-token-binding-param", + "2", + }, + tls13Variant: ver.tls13Variant, + shouldFail: true, + expectedError: ":ERROR_PARSING_EXTENSION:", + }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-Client-WrongParam-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{3}, + TokenBindingVersion: maxTokenBindingVersion, + ExpectTokenBindingParams: []byte{0, 1, 2}, + }, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{0, 1, 2}), + "-expected-token-binding-param", + "2", + }, + tls13Variant: ver.tls13Variant, + shouldFail: true, + expectedError: ":ERROR_PARSING_EXTENSION:", + }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-Client-OldVersion-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{2}, + TokenBindingVersion: minTokenBindingVersion - 1, + ExpectTokenBindingParams: []byte{0, 1, 2}, + }, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{0, 1, 2}), + }, + tls13Variant: ver.tls13Variant, + }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-Client-MinVersion-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{2}, + TokenBindingVersion: minTokenBindingVersion, + ExpectTokenBindingParams: []byte{0, 1, 2}, + }, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{0, 1, 2}), + "-expected-token-binding-param", + "2", + }, + tls13Variant: ver.tls13Variant, + }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-Client-VersionTooNew-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{2}, + TokenBindingVersion: maxTokenBindingVersion + 1, + ExpectTokenBindingParams: []byte{0, 1, 2}, + }, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{0, 1, 2}), + }, + tls13Variant: ver.tls13Variant, + shouldFail: true, + expectedError: "ERROR_PARSING_EXTENSION", + }) + if ver.version < VersionTLS13 { + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-Client-NoEMS-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{2}, + TokenBindingVersion: maxTokenBindingVersion, + ExpectTokenBindingParams: []byte{2, 1, 0}, + Bugs: ProtocolBugs{ + NoExtendedMasterSecret: true, + }, + }, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + }, + shouldFail: true, + expectedError: ":NEGOTIATED_TB_WITHOUT_EMS_OR_RI:", + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "TokenBinding-Server-NoEMS-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{0, 1, 2}, + TokenBindingVersion: maxTokenBindingVersion, + Bugs: ProtocolBugs{ + NoExtendedMasterSecret: true, + }, + }, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + }, + shouldFail: true, + expectedError: ":NEGOTIATED_TB_WITHOUT_EMS_OR_RI:", + }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-Client-NoRI-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{2}, + TokenBindingVersion: maxTokenBindingVersion, + ExpectTokenBindingParams: []byte{2, 1, 0}, + Bugs: ProtocolBugs{ + NoRenegotiationInfo: true, + }, + }, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + }, + shouldFail: true, + expectedError: ":NEGOTIATED_TB_WITHOUT_EMS_OR_RI:", + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "TokenBinding-Server-NoRI-" + ver.name, + + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{0, 1, 2}, + TokenBindingVersion: maxTokenBindingVersion, + Bugs: ProtocolBugs{ + NoRenegotiationInfo: true, + }, + }, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + }, + shouldFail: true, + expectedError: ":NEGOTIATED_TB_WITHOUT_EMS_OR_RI:", + }) + } else { + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TokenBinding-WithEarlyDataFails-" + ver.name, + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{2}, + TokenBindingVersion: maxTokenBindingVersion, + ExpectTokenBindingParams: []byte{2, 1, 0}, + MaxEarlyDataSize: 16384, + }, + resumeSession: true, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-enable-early-data", + "-expect-ticket-supports-early-data", + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + }, + shouldFail: true, + expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:", + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "TokenBinding-EarlyDataRejected-" + ver.name, + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + TokenBindingParams: []byte{0, 1, 2}, + TokenBindingVersion: maxTokenBindingVersion, + MaxEarlyDataSize: 16384, + }, + resumeSession: true, + expectTokenBinding: true, + expectedTokenBindingParam: 2, + tls13Variant: ver.tls13Variant, + flags: []string{ + "-enable-early-data", + "-expect-ticket-supports-early-data", + "-token-binding-params", + base64.StdEncoding.EncodeToString([]byte{2, 1, 0}), + }, + }) + } + // Test ticket behavior. // Resume with a corrupt ticket. diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc index 0d11f900..7c660c8a 100644 --- a/src/ssl/test/test_config.cc +++ b/src/ssl/test/test_config.cc @@ -163,6 +163,7 @@ const Flag<std::string> kStringFlags[] = { const Flag<std::string> kBase64Flags[] = { { "-expect-certificate-types", &TestConfig::expected_certificate_types }, { "-expect-channel-id", &TestConfig::expected_channel_id }, + { "-token-binding-params", &TestConfig::send_token_binding_params }, { "-expect-ocsp-response", &TestConfig::expected_ocsp_response }, { "-expect-signed-cert-timestamps", &TestConfig::expected_signed_cert_timestamps }, @@ -174,6 +175,8 @@ const Flag<std::string> kBase64Flags[] = { const Flag<int> kIntFlags[] = { { "-port", &TestConfig::port }, { "-resume-count", &TestConfig::resume_count }, + { "-expected-token-binding-param", + &TestConfig::expected_token_binding_param }, { "-min-version", &TestConfig::min_version }, { "-max-version", &TestConfig::max_version }, { "-expect-version", &TestConfig::expect_version }, diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h index fe107bce..75743378 100644 --- a/src/ssl/test/test_config.h +++ b/src/ssl/test/test_config.h @@ -49,6 +49,8 @@ struct TestConfig { std::string expected_channel_id; bool enable_channel_id = false; std::string send_channel_id; + int expected_token_binding_param = -1; + std::string send_token_binding_params; bool shim_writes_first = false; std::string host_name; std::string advertise_alpn; diff --git a/src/ssl/tls13_client.cc b/src/ssl/tls13_client.cc index f4375195..f013afda 100644 --- a/src/ssl/tls13_client.cc +++ b/src/ssl/tls13_client.cc @@ -476,7 +476,8 @@ static enum ssl_hs_wait_t do_read_encrypted_extensions(SSL_HANDSHAKE *hs) { OPENSSL_PUT_ERROR(SSL, SSL_R_ALPN_MISMATCH_ON_EARLY_DATA); return ssl_hs_error; } - if (ssl->s3->tlsext_channel_id_valid || hs->received_custom_extension) { + if (ssl->s3->tlsext_channel_id_valid || hs->received_custom_extension || + ssl->token_binding_negotiated) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA); return ssl_hs_error; } diff --git a/src/ssl/tls13_server.cc b/src/ssl/tls13_server.cc index 72273dae..331e0d57 100644 --- a/src/ssl/tls13_server.cc +++ b/src/ssl/tls13_server.cc @@ -398,6 +398,8 @@ static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) { hs->early_data_offered && // Channel ID is incompatible with 0-RTT. !ssl->s3->tlsext_channel_id_valid && + // If Token Binding is negotiated, reject 0-RTT. + !ssl->token_binding_negotiated && // Custom extensions is incompatible with 0-RTT. hs->custom_extensions.received == 0 && // The negotiated ALPN must match the one in the ticket. diff --git a/src/util/bot/DEPS b/src/util/bot/DEPS index a4c3a7ff..b58d1040 100644 --- a/src/util/bot/DEPS +++ b/src/util/bot/DEPS @@ -22,7 +22,7 @@ vars = { deps = { 'boringssl/util/bot/android_tools': { - 'url': Var('chromium_git') + '/android_tools.git' + '@' + 'a2e9bc7c1b41d983577907df51d339fb1e0fd02f', + 'url': Var('chromium_git') + '/android_tools.git' + '@' + 'c9f9bbf0a6c862fbef6115e80e8617093cd58e6b', 'condition': 'checkout_android', }, @@ -30,7 +30,7 @@ deps = { Var('chromium_git') + '/external/gyp.git' + '@' + 'd61a9397e668fa9843c4aa7da9e79460fe590bfb', 'boringssl/util/bot/libFuzzer': { - 'url': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git' + '@' + 'a00e8070bea627f21df4a7eb1d58083f1bcfbba1', + 'url': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git' + '@' + 'ba2c1cd6f87accb32b5dbce297387c56a2e53a2f', 'condition': 'checkout_fuzzer', }, } diff --git a/src/util/bot/update_clang.py b/src/util/bot/update_clang.py index ffe7880c..dceb585b 100644 --- a/src/util/bot/update_clang.py +++ b/src/util/bot/update_clang.py @@ -19,8 +19,8 @@ import urllib2 # CLANG_REVISION and CLANG_SUB_REVISION determine the build of clang # to use. These should be synced with tools/clang/scripts/update.py in # Chromium. -CLANG_REVISION = '318667' -CLANG_SUB_REVISION=1 +CLANG_REVISION = '321529' +CLANG_SUB_REVISION=2 PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION) diff --git a/src/util/bot/vs_toolchain.py b/src/util/bot/vs_toolchain.py index 64da79a1..71b59c89 100644 --- a/src/util/bot/vs_toolchain.py +++ b/src/util/bot/vs_toolchain.py @@ -87,8 +87,9 @@ def _GetDesiredVsToolchainHashes(): # Update 3 final with 10.0.15063.468 SDK and no vctip.exe. return ['f53e4598951162bad6330f7a167486c7ae5db1e5'] if env_version == '2017': - # VS 2017 Update 3.2 with 10.0.15063.468 SDK and patched setenv.cmd. - return ['a9e1098bba66d2acccc377d5ee81265910f29272'] + # VS 2017 Update 3.2 with 10.0.15063.468 SDK, patched setenv.cmd, and + # 10.0.16299.15 debuggers. + return ['1180cb75833ea365097e279efb2d5d7a42dee4b0'] raise Exception('Unsupported VS version %s' % env_version) diff --git a/src/util/fipstools/delocate.go b/src/util/fipstools/delocate.go index 2c1ba498..b4371fc6 100644 --- a/src/util/fipstools/delocate.go +++ b/src/util/fipstools/delocate.go @@ -1038,7 +1038,7 @@ Args: targetReg = d.contents(argNodes[1]) wrappers = append(wrappers, finalTransform(d.output, instructionName, targetReg)) if isValidLEATarget(targetReg) { - return nil, fmt.Errorf("Currently transforming moves are assumed to target XMM registers. Otherwise we'll pop %rax before reading it to do the transform.") + return nil, errors.New("Currently transforming moves are assumed to target XMM registers. Otherwise we'll pop %rax before reading it to do the transform.") } default: return nil, fmt.Errorf("Cannot rewrite GOTPCREL reference for instruction %q", instructionName) diff --git a/src/util/fipstools/delocate.peg b/src/util/fipstools/delocate.peg index 85cb72d1..abcd9534 100644 --- a/src/util/fipstools/delocate.peg +++ b/src/util/fipstools/delocate.peg @@ -55,7 +55,7 @@ SymbolName <- [[A-Z._]][[A-Z.0-9$_]]* LocalSymbol <- '.L' [[A-Z.0-9$_]]+ LocalLabel <- [0-9][0-9$]* LocalLabelRef <- [0-9][0-9$]*[bf] -Instruction <- InstructionName (WS InstructionArg ((WS? ',' WS?) InstructionArg)*)? +Instruction <- InstructionName (WS InstructionArg ((WS? ',' WS?) InstructionArg)*)? (WS? '{' InstructionArg '}')* InstructionName <- [[A-Z]][[A-Z0-9]]* [.+\-]? InstructionArg <- IndirectionIndicator? (RegisterOrConstant / LocalLabelRef / TOCRefHigh / TOCRefLow / MemoryRef) TOCRefHigh <- '.TOC.-' ('0b' / ('.L' [a-zA-Z_0-9]+)) "@ha" diff --git a/src/util/fipstools/delocate.peg.go b/src/util/fipstools/delocate.peg.go index 9afd4d3e..4cbdcada 100644 --- a/src/util/fipstools/delocate.peg.go +++ b/src/util/fipstools/delocate.peg.go @@ -2697,7 +2697,7 @@ func (p *Asm) Init() { position, tokenIndex = position322, tokenIndex322 return false }, - /* 25 Instruction <- <(InstructionName (WS InstructionArg (WS? ',' WS? InstructionArg)*)?)> */ + /* 25 Instruction <- <(InstructionName (WS InstructionArg (WS? ',' WS? InstructionArg)*)? (WS? '{' InstructionArg '}')*)> */ func() bool { position330, tokenIndex330 := position, tokenIndex { @@ -2752,6 +2752,34 @@ func (p *Asm) Init() { position, tokenIndex = position332, tokenIndex332 } l333: + l340: + { + position341, tokenIndex341 := position, tokenIndex + { + position342, tokenIndex342 := position, tokenIndex + if !_rules[ruleWS]() { + goto l342 + } + goto l343 + l342: + position, tokenIndex = position342, tokenIndex342 + } + l343: + if buffer[position] != rune('{') { + goto l341 + } + position++ + if !_rules[ruleInstructionArg]() { + goto l341 + } + if buffer[position] != rune('}') { + goto l341 + } + position++ + goto l340 + l341: + position, tokenIndex = position341, tokenIndex341 + } add(ruleInstruction, position331) } return true @@ -2761,1218 +2789,1218 @@ func (p *Asm) Init() { }, /* 26 InstructionName <- <(([a-z] / [A-Z]) ([a-z] / [A-Z] / ([0-9] / [0-9]))* ('.' / '+' / '-')?)> */ func() bool { - position340, tokenIndex340 := position, tokenIndex + position344, tokenIndex344 := position, tokenIndex { - position341 := position + position345 := position { - position342, tokenIndex342 := position, tokenIndex + position346, tokenIndex346 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l343 + goto l347 } position++ - goto l342 - l343: - position, tokenIndex = position342, tokenIndex342 + goto l346 + l347: + position, tokenIndex = position346, tokenIndex346 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l340 + goto l344 } position++ } - l342: - l344: + l346: + l348: { - position345, tokenIndex345 := position, tokenIndex + position349, tokenIndex349 := position, tokenIndex { - position346, tokenIndex346 := position, tokenIndex + position350, tokenIndex350 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l347 + goto l351 } position++ - goto l346 - l347: - position, tokenIndex = position346, tokenIndex346 + goto l350 + l351: + position, tokenIndex = position350, tokenIndex350 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l348 + goto l352 } position++ - goto l346 - l348: - position, tokenIndex = position346, tokenIndex346 + goto l350 + l352: + position, tokenIndex = position350, tokenIndex350 { - position349, tokenIndex349 := position, tokenIndex + position353, tokenIndex353 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l350 + goto l354 } position++ - goto l349 - l350: - position, tokenIndex = position349, tokenIndex349 + goto l353 + l354: + position, tokenIndex = position353, tokenIndex353 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l345 + goto l349 } position++ } - l349: + l353: } - l346: - goto l344 - l345: - position, tokenIndex = position345, tokenIndex345 + l350: + goto l348 + l349: + position, tokenIndex = position349, tokenIndex349 } { - position351, tokenIndex351 := position, tokenIndex + position355, tokenIndex355 := position, tokenIndex { - position353, tokenIndex353 := position, tokenIndex + position357, tokenIndex357 := position, tokenIndex if buffer[position] != rune('.') { - goto l354 + goto l358 } position++ - goto l353 - l354: - position, tokenIndex = position353, tokenIndex353 + goto l357 + l358: + position, tokenIndex = position357, tokenIndex357 if buffer[position] != rune('+') { - goto l355 + goto l359 } position++ - goto l353 - l355: - position, tokenIndex = position353, tokenIndex353 + goto l357 + l359: + position, tokenIndex = position357, tokenIndex357 if buffer[position] != rune('-') { - goto l351 + goto l355 } position++ } - l353: - goto l352 - l351: - position, tokenIndex = position351, tokenIndex351 + l357: + goto l356 + l355: + position, tokenIndex = position355, tokenIndex355 } - l352: - add(ruleInstructionName, position341) + l356: + add(ruleInstructionName, position345) } return true - l340: - position, tokenIndex = position340, tokenIndex340 + l344: + position, tokenIndex = position344, tokenIndex344 return false }, /* 27 InstructionArg <- <(IndirectionIndicator? (RegisterOrConstant / LocalLabelRef / TOCRefHigh / TOCRefLow / MemoryRef))> */ func() bool { - position356, tokenIndex356 := position, tokenIndex + position360, tokenIndex360 := position, tokenIndex { - position357 := position + position361 := position { - position358, tokenIndex358 := position, tokenIndex + position362, tokenIndex362 := position, tokenIndex if !_rules[ruleIndirectionIndicator]() { - goto l358 + goto l362 } - goto l359 - l358: - position, tokenIndex = position358, tokenIndex358 + goto l363 + l362: + position, tokenIndex = position362, tokenIndex362 } - l359: + l363: { - position360, tokenIndex360 := position, tokenIndex + position364, tokenIndex364 := position, tokenIndex if !_rules[ruleRegisterOrConstant]() { - goto l361 + goto l365 } - goto l360 - l361: - position, tokenIndex = position360, tokenIndex360 + goto l364 + l365: + position, tokenIndex = position364, tokenIndex364 if !_rules[ruleLocalLabelRef]() { - goto l362 + goto l366 } - goto l360 - l362: - position, tokenIndex = position360, tokenIndex360 + goto l364 + l366: + position, tokenIndex = position364, tokenIndex364 if !_rules[ruleTOCRefHigh]() { - goto l363 + goto l367 } - goto l360 - l363: - position, tokenIndex = position360, tokenIndex360 + goto l364 + l367: + position, tokenIndex = position364, tokenIndex364 if !_rules[ruleTOCRefLow]() { - goto l364 + goto l368 } - goto l360 - l364: - position, tokenIndex = position360, tokenIndex360 + goto l364 + l368: + position, tokenIndex = position364, tokenIndex364 if !_rules[ruleMemoryRef]() { - goto l356 + goto l360 } } - l360: - add(ruleInstructionArg, position357) + l364: + add(ruleInstructionArg, position361) } return true - l356: - position, tokenIndex = position356, tokenIndex356 + l360: + position, tokenIndex = position360, tokenIndex360 return false }, /* 28 TOCRefHigh <- <('.' 'T' 'O' 'C' '.' '-' (('0' 'b') / ('.' 'L' ([a-z] / [A-Z] / '_' / [0-9])+)) ('@' ('h' / 'H') ('a' / 'A')))> */ func() bool { - position365, tokenIndex365 := position, tokenIndex + position369, tokenIndex369 := position, tokenIndex { - position366 := position + position370 := position if buffer[position] != rune('.') { - goto l365 + goto l369 } position++ if buffer[position] != rune('T') { - goto l365 + goto l369 } position++ if buffer[position] != rune('O') { - goto l365 + goto l369 } position++ if buffer[position] != rune('C') { - goto l365 + goto l369 } position++ if buffer[position] != rune('.') { - goto l365 + goto l369 } position++ if buffer[position] != rune('-') { - goto l365 + goto l369 } position++ { - position367, tokenIndex367 := position, tokenIndex + position371, tokenIndex371 := position, tokenIndex if buffer[position] != rune('0') { - goto l368 + goto l372 } position++ if buffer[position] != rune('b') { - goto l368 + goto l372 } position++ - goto l367 - l368: - position, tokenIndex = position367, tokenIndex367 + goto l371 + l372: + position, tokenIndex = position371, tokenIndex371 if buffer[position] != rune('.') { - goto l365 + goto l369 } position++ if buffer[position] != rune('L') { - goto l365 + goto l369 } position++ { - position371, tokenIndex371 := position, tokenIndex + position375, tokenIndex375 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l372 + goto l376 } position++ - goto l371 - l372: - position, tokenIndex = position371, tokenIndex371 + goto l375 + l376: + position, tokenIndex = position375, tokenIndex375 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l373 + goto l377 } position++ - goto l371 - l373: - position, tokenIndex = position371, tokenIndex371 + goto l375 + l377: + position, tokenIndex = position375, tokenIndex375 if buffer[position] != rune('_') { - goto l374 + goto l378 } position++ - goto l371 - l374: - position, tokenIndex = position371, tokenIndex371 + goto l375 + l378: + position, tokenIndex = position375, tokenIndex375 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l365 + goto l369 } position++ } - l371: - l369: + l375: + l373: { - position370, tokenIndex370 := position, tokenIndex + position374, tokenIndex374 := position, tokenIndex { - position375, tokenIndex375 := position, tokenIndex + position379, tokenIndex379 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l376 + goto l380 } position++ - goto l375 - l376: - position, tokenIndex = position375, tokenIndex375 + goto l379 + l380: + position, tokenIndex = position379, tokenIndex379 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l377 + goto l381 } position++ - goto l375 - l377: - position, tokenIndex = position375, tokenIndex375 + goto l379 + l381: + position, tokenIndex = position379, tokenIndex379 if buffer[position] != rune('_') { - goto l378 + goto l382 } position++ - goto l375 - l378: - position, tokenIndex = position375, tokenIndex375 + goto l379 + l382: + position, tokenIndex = position379, tokenIndex379 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l370 + goto l374 } position++ } - l375: - goto l369 - l370: - position, tokenIndex = position370, tokenIndex370 + l379: + goto l373 + l374: + position, tokenIndex = position374, tokenIndex374 } } - l367: + l371: if buffer[position] != rune('@') { - goto l365 + goto l369 } position++ { - position379, tokenIndex379 := position, tokenIndex + position383, tokenIndex383 := position, tokenIndex if buffer[position] != rune('h') { - goto l380 + goto l384 } position++ - goto l379 - l380: - position, tokenIndex = position379, tokenIndex379 + goto l383 + l384: + position, tokenIndex = position383, tokenIndex383 if buffer[position] != rune('H') { - goto l365 + goto l369 } position++ } - l379: + l383: { - position381, tokenIndex381 := position, tokenIndex + position385, tokenIndex385 := position, tokenIndex if buffer[position] != rune('a') { - goto l382 + goto l386 } position++ - goto l381 - l382: - position, tokenIndex = position381, tokenIndex381 + goto l385 + l386: + position, tokenIndex = position385, tokenIndex385 if buffer[position] != rune('A') { - goto l365 + goto l369 } position++ } - l381: - add(ruleTOCRefHigh, position366) + l385: + add(ruleTOCRefHigh, position370) } return true - l365: - position, tokenIndex = position365, tokenIndex365 + l369: + position, tokenIndex = position369, tokenIndex369 return false }, /* 29 TOCRefLow <- <('.' 'T' 'O' 'C' '.' '-' (('0' 'b') / ('.' 'L' ([a-z] / [A-Z] / '_' / [0-9])+)) ('@' ('l' / 'L')))> */ func() bool { - position383, tokenIndex383 := position, tokenIndex + position387, tokenIndex387 := position, tokenIndex { - position384 := position + position388 := position if buffer[position] != rune('.') { - goto l383 + goto l387 } position++ if buffer[position] != rune('T') { - goto l383 + goto l387 } position++ if buffer[position] != rune('O') { - goto l383 + goto l387 } position++ if buffer[position] != rune('C') { - goto l383 + goto l387 } position++ if buffer[position] != rune('.') { - goto l383 + goto l387 } position++ if buffer[position] != rune('-') { - goto l383 + goto l387 } position++ { - position385, tokenIndex385 := position, tokenIndex + position389, tokenIndex389 := position, tokenIndex if buffer[position] != rune('0') { - goto l386 + goto l390 } position++ if buffer[position] != rune('b') { - goto l386 + goto l390 } position++ - goto l385 - l386: - position, tokenIndex = position385, tokenIndex385 + goto l389 + l390: + position, tokenIndex = position389, tokenIndex389 if buffer[position] != rune('.') { - goto l383 + goto l387 } position++ if buffer[position] != rune('L') { - goto l383 + goto l387 } position++ { - position389, tokenIndex389 := position, tokenIndex + position393, tokenIndex393 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l390 + goto l394 } position++ - goto l389 - l390: - position, tokenIndex = position389, tokenIndex389 + goto l393 + l394: + position, tokenIndex = position393, tokenIndex393 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l391 + goto l395 } position++ - goto l389 - l391: - position, tokenIndex = position389, tokenIndex389 + goto l393 + l395: + position, tokenIndex = position393, tokenIndex393 if buffer[position] != rune('_') { - goto l392 + goto l396 } position++ - goto l389 - l392: - position, tokenIndex = position389, tokenIndex389 + goto l393 + l396: + position, tokenIndex = position393, tokenIndex393 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l383 + goto l387 } position++ } - l389: - l387: + l393: + l391: { - position388, tokenIndex388 := position, tokenIndex + position392, tokenIndex392 := position, tokenIndex { - position393, tokenIndex393 := position, tokenIndex + position397, tokenIndex397 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l394 + goto l398 } position++ - goto l393 - l394: - position, tokenIndex = position393, tokenIndex393 + goto l397 + l398: + position, tokenIndex = position397, tokenIndex397 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l395 + goto l399 } position++ - goto l393 - l395: - position, tokenIndex = position393, tokenIndex393 + goto l397 + l399: + position, tokenIndex = position397, tokenIndex397 if buffer[position] != rune('_') { - goto l396 + goto l400 } position++ - goto l393 - l396: - position, tokenIndex = position393, tokenIndex393 + goto l397 + l400: + position, tokenIndex = position397, tokenIndex397 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l388 + goto l392 } position++ } - l393: - goto l387 - l388: - position, tokenIndex = position388, tokenIndex388 + l397: + goto l391 + l392: + position, tokenIndex = position392, tokenIndex392 } } - l385: + l389: if buffer[position] != rune('@') { - goto l383 + goto l387 } position++ { - position397, tokenIndex397 := position, tokenIndex + position401, tokenIndex401 := position, tokenIndex if buffer[position] != rune('l') { - goto l398 + goto l402 } position++ - goto l397 - l398: - position, tokenIndex = position397, tokenIndex397 + goto l401 + l402: + position, tokenIndex = position401, tokenIndex401 if buffer[position] != rune('L') { - goto l383 + goto l387 } position++ } - l397: - add(ruleTOCRefLow, position384) + l401: + add(ruleTOCRefLow, position388) } return true - l383: - position, tokenIndex = position383, tokenIndex383 + l387: + position, tokenIndex = position387, tokenIndex387 return false }, /* 30 IndirectionIndicator <- <'*'> */ func() bool { - position399, tokenIndex399 := position, tokenIndex + position403, tokenIndex403 := position, tokenIndex { - position400 := position + position404 := position if buffer[position] != rune('*') { - goto l399 + goto l403 } position++ - add(ruleIndirectionIndicator, position400) + add(ruleIndirectionIndicator, position404) } return true - l399: - position, tokenIndex = position399, tokenIndex399 + l403: + position, tokenIndex = position403, tokenIndex403 return false }, /* 31 RegisterOrConstant <- <((('%' ([a-z] / [A-Z]) ([a-z] / [A-Z] / ([0-9] / [0-9]))*) / ('$'? ((Offset Offset) / Offset))) !('f' / 'b' / ':' / '(' / '+' / '-'))> */ func() bool { - position401, tokenIndex401 := position, tokenIndex + position405, tokenIndex405 := position, tokenIndex { - position402 := position + position406 := position { - position403, tokenIndex403 := position, tokenIndex + position407, tokenIndex407 := position, tokenIndex if buffer[position] != rune('%') { - goto l404 + goto l408 } position++ { - position405, tokenIndex405 := position, tokenIndex + position409, tokenIndex409 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l406 + goto l410 } position++ - goto l405 - l406: - position, tokenIndex = position405, tokenIndex405 + goto l409 + l410: + position, tokenIndex = position409, tokenIndex409 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l404 + goto l408 } position++ } - l405: - l407: + l409: + l411: { - position408, tokenIndex408 := position, tokenIndex + position412, tokenIndex412 := position, tokenIndex { - position409, tokenIndex409 := position, tokenIndex + position413, tokenIndex413 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l410 + goto l414 } position++ - goto l409 - l410: - position, tokenIndex = position409, tokenIndex409 + goto l413 + l414: + position, tokenIndex = position413, tokenIndex413 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l411 + goto l415 } position++ - goto l409 - l411: - position, tokenIndex = position409, tokenIndex409 + goto l413 + l415: + position, tokenIndex = position413, tokenIndex413 { - position412, tokenIndex412 := position, tokenIndex + position416, tokenIndex416 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l413 + goto l417 } position++ - goto l412 - l413: - position, tokenIndex = position412, tokenIndex412 + goto l416 + l417: + position, tokenIndex = position416, tokenIndex416 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l408 + goto l412 } position++ } - l412: + l416: } - l409: - goto l407 - l408: - position, tokenIndex = position408, tokenIndex408 + l413: + goto l411 + l412: + position, tokenIndex = position412, tokenIndex412 } - goto l403 - l404: - position, tokenIndex = position403, tokenIndex403 + goto l407 + l408: + position, tokenIndex = position407, tokenIndex407 { - position414, tokenIndex414 := position, tokenIndex + position418, tokenIndex418 := position, tokenIndex if buffer[position] != rune('$') { - goto l414 + goto l418 } position++ - goto l415 - l414: - position, tokenIndex = position414, tokenIndex414 + goto l419 + l418: + position, tokenIndex = position418, tokenIndex418 } - l415: + l419: { - position416, tokenIndex416 := position, tokenIndex + position420, tokenIndex420 := position, tokenIndex if !_rules[ruleOffset]() { - goto l417 + goto l421 } if !_rules[ruleOffset]() { - goto l417 + goto l421 } - goto l416 - l417: - position, tokenIndex = position416, tokenIndex416 + goto l420 + l421: + position, tokenIndex = position420, tokenIndex420 if !_rules[ruleOffset]() { - goto l401 + goto l405 } } - l416: + l420: } - l403: + l407: { - position418, tokenIndex418 := position, tokenIndex + position422, tokenIndex422 := position, tokenIndex { - position419, tokenIndex419 := position, tokenIndex + position423, tokenIndex423 := position, tokenIndex if buffer[position] != rune('f') { - goto l420 + goto l424 } position++ - goto l419 - l420: - position, tokenIndex = position419, tokenIndex419 + goto l423 + l424: + position, tokenIndex = position423, tokenIndex423 if buffer[position] != rune('b') { - goto l421 + goto l425 } position++ - goto l419 - l421: - position, tokenIndex = position419, tokenIndex419 + goto l423 + l425: + position, tokenIndex = position423, tokenIndex423 if buffer[position] != rune(':') { - goto l422 + goto l426 } position++ - goto l419 - l422: - position, tokenIndex = position419, tokenIndex419 + goto l423 + l426: + position, tokenIndex = position423, tokenIndex423 if buffer[position] != rune('(') { - goto l423 + goto l427 } position++ - goto l419 - l423: - position, tokenIndex = position419, tokenIndex419 + goto l423 + l427: + position, tokenIndex = position423, tokenIndex423 if buffer[position] != rune('+') { - goto l424 + goto l428 } position++ - goto l419 - l424: - position, tokenIndex = position419, tokenIndex419 + goto l423 + l428: + position, tokenIndex = position423, tokenIndex423 if buffer[position] != rune('-') { - goto l418 + goto l422 } position++ } - l419: - goto l401 - l418: - position, tokenIndex = position418, tokenIndex418 + l423: + goto l405 + l422: + position, tokenIndex = position422, tokenIndex422 } - add(ruleRegisterOrConstant, position402) + add(ruleRegisterOrConstant, position406) } return true - l401: - position, tokenIndex = position401, tokenIndex401 + l405: + position, tokenIndex = position405, tokenIndex405 return false }, /* 32 MemoryRef <- <((SymbolRef BaseIndexScale) / SymbolRef / (Offset* BaseIndexScale) / (SegmentRegister Offset BaseIndexScale) / (SegmentRegister BaseIndexScale) / (SegmentRegister Offset) / BaseIndexScale)> */ func() bool { - position425, tokenIndex425 := position, tokenIndex + position429, tokenIndex429 := position, tokenIndex { - position426 := position + position430 := position { - position427, tokenIndex427 := position, tokenIndex + position431, tokenIndex431 := position, tokenIndex if !_rules[ruleSymbolRef]() { - goto l428 + goto l432 } if !_rules[ruleBaseIndexScale]() { - goto l428 + goto l432 } - goto l427 - l428: - position, tokenIndex = position427, tokenIndex427 + goto l431 + l432: + position, tokenIndex = position431, tokenIndex431 if !_rules[ruleSymbolRef]() { - goto l429 + goto l433 } - goto l427 - l429: - position, tokenIndex = position427, tokenIndex427 - l431: + goto l431 + l433: + position, tokenIndex = position431, tokenIndex431 + l435: { - position432, tokenIndex432 := position, tokenIndex + position436, tokenIndex436 := position, tokenIndex if !_rules[ruleOffset]() { - goto l432 + goto l436 } - goto l431 - l432: - position, tokenIndex = position432, tokenIndex432 + goto l435 + l436: + position, tokenIndex = position436, tokenIndex436 } if !_rules[ruleBaseIndexScale]() { - goto l430 + goto l434 } - goto l427 - l430: - position, tokenIndex = position427, tokenIndex427 + goto l431 + l434: + position, tokenIndex = position431, tokenIndex431 if !_rules[ruleSegmentRegister]() { - goto l433 + goto l437 } if !_rules[ruleOffset]() { - goto l433 + goto l437 } if !_rules[ruleBaseIndexScale]() { - goto l433 + goto l437 } - goto l427 - l433: - position, tokenIndex = position427, tokenIndex427 + goto l431 + l437: + position, tokenIndex = position431, tokenIndex431 if !_rules[ruleSegmentRegister]() { - goto l434 + goto l438 } if !_rules[ruleBaseIndexScale]() { - goto l434 + goto l438 } - goto l427 - l434: - position, tokenIndex = position427, tokenIndex427 + goto l431 + l438: + position, tokenIndex = position431, tokenIndex431 if !_rules[ruleSegmentRegister]() { - goto l435 + goto l439 } if !_rules[ruleOffset]() { - goto l435 + goto l439 } - goto l427 - l435: - position, tokenIndex = position427, tokenIndex427 + goto l431 + l439: + position, tokenIndex = position431, tokenIndex431 if !_rules[ruleBaseIndexScale]() { - goto l425 + goto l429 } } - l427: - add(ruleMemoryRef, position426) + l431: + add(ruleMemoryRef, position430) } return true - l425: - position, tokenIndex = position425, tokenIndex425 + l429: + position, tokenIndex = position429, tokenIndex429 return false }, /* 33 SymbolRef <- <((Offset* '+')? (LocalSymbol / SymbolName) Offset* ('@' Section Offset*)?)> */ func() bool { - position436, tokenIndex436 := position, tokenIndex + position440, tokenIndex440 := position, tokenIndex { - position437 := position + position441 := position { - position438, tokenIndex438 := position, tokenIndex - l440: + position442, tokenIndex442 := position, tokenIndex + l444: { - position441, tokenIndex441 := position, tokenIndex + position445, tokenIndex445 := position, tokenIndex if !_rules[ruleOffset]() { - goto l441 + goto l445 } - goto l440 - l441: - position, tokenIndex = position441, tokenIndex441 + goto l444 + l445: + position, tokenIndex = position445, tokenIndex445 } if buffer[position] != rune('+') { - goto l438 + goto l442 } position++ - goto l439 - l438: - position, tokenIndex = position438, tokenIndex438 + goto l443 + l442: + position, tokenIndex = position442, tokenIndex442 } - l439: + l443: { - position442, tokenIndex442 := position, tokenIndex + position446, tokenIndex446 := position, tokenIndex if !_rules[ruleLocalSymbol]() { - goto l443 + goto l447 } - goto l442 - l443: - position, tokenIndex = position442, tokenIndex442 + goto l446 + l447: + position, tokenIndex = position446, tokenIndex446 if !_rules[ruleSymbolName]() { - goto l436 + goto l440 } } - l442: - l444: + l446: + l448: { - position445, tokenIndex445 := position, tokenIndex + position449, tokenIndex449 := position, tokenIndex if !_rules[ruleOffset]() { - goto l445 + goto l449 } - goto l444 - l445: - position, tokenIndex = position445, tokenIndex445 + goto l448 + l449: + position, tokenIndex = position449, tokenIndex449 } { - position446, tokenIndex446 := position, tokenIndex + position450, tokenIndex450 := position, tokenIndex if buffer[position] != rune('@') { - goto l446 + goto l450 } position++ if !_rules[ruleSection]() { - goto l446 + goto l450 } - l448: + l452: { - position449, tokenIndex449 := position, tokenIndex + position453, tokenIndex453 := position, tokenIndex if !_rules[ruleOffset]() { - goto l449 + goto l453 } - goto l448 - l449: - position, tokenIndex = position449, tokenIndex449 + goto l452 + l453: + position, tokenIndex = position453, tokenIndex453 } - goto l447 - l446: - position, tokenIndex = position446, tokenIndex446 + goto l451 + l450: + position, tokenIndex = position450, tokenIndex450 } - l447: - add(ruleSymbolRef, position437) + l451: + add(ruleSymbolRef, position441) } return true - l436: - position, tokenIndex = position436, tokenIndex436 + l440: + position, tokenIndex = position440, tokenIndex440 return false }, /* 34 BaseIndexScale <- <('(' RegisterOrConstant? WS? (',' WS? RegisterOrConstant WS? (',' [0-9]+)?)? ')')> */ func() bool { - position450, tokenIndex450 := position, tokenIndex + position454, tokenIndex454 := position, tokenIndex { - position451 := position + position455 := position if buffer[position] != rune('(') { - goto l450 + goto l454 } position++ { - position452, tokenIndex452 := position, tokenIndex + position456, tokenIndex456 := position, tokenIndex if !_rules[ruleRegisterOrConstant]() { - goto l452 + goto l456 } - goto l453 - l452: - position, tokenIndex = position452, tokenIndex452 + goto l457 + l456: + position, tokenIndex = position456, tokenIndex456 } - l453: + l457: { - position454, tokenIndex454 := position, tokenIndex + position458, tokenIndex458 := position, tokenIndex if !_rules[ruleWS]() { - goto l454 + goto l458 } - goto l455 - l454: - position, tokenIndex = position454, tokenIndex454 + goto l459 + l458: + position, tokenIndex = position458, tokenIndex458 } - l455: + l459: { - position456, tokenIndex456 := position, tokenIndex + position460, tokenIndex460 := position, tokenIndex if buffer[position] != rune(',') { - goto l456 + goto l460 } position++ { - position458, tokenIndex458 := position, tokenIndex + position462, tokenIndex462 := position, tokenIndex if !_rules[ruleWS]() { - goto l458 + goto l462 } - goto l459 - l458: - position, tokenIndex = position458, tokenIndex458 + goto l463 + l462: + position, tokenIndex = position462, tokenIndex462 } - l459: + l463: if !_rules[ruleRegisterOrConstant]() { - goto l456 + goto l460 } { - position460, tokenIndex460 := position, tokenIndex + position464, tokenIndex464 := position, tokenIndex if !_rules[ruleWS]() { - goto l460 + goto l464 } - goto l461 - l460: - position, tokenIndex = position460, tokenIndex460 + goto l465 + l464: + position, tokenIndex = position464, tokenIndex464 } - l461: + l465: { - position462, tokenIndex462 := position, tokenIndex + position466, tokenIndex466 := position, tokenIndex if buffer[position] != rune(',') { - goto l462 + goto l466 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l462 + goto l466 } position++ - l464: + l468: { - position465, tokenIndex465 := position, tokenIndex + position469, tokenIndex469 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l465 + goto l469 } position++ - goto l464 - l465: - position, tokenIndex = position465, tokenIndex465 + goto l468 + l469: + position, tokenIndex = position469, tokenIndex469 } - goto l463 - l462: - position, tokenIndex = position462, tokenIndex462 + goto l467 + l466: + position, tokenIndex = position466, tokenIndex466 } - l463: - goto l457 - l456: - position, tokenIndex = position456, tokenIndex456 + l467: + goto l461 + l460: + position, tokenIndex = position460, tokenIndex460 } - l457: + l461: if buffer[position] != rune(')') { - goto l450 + goto l454 } position++ - add(ruleBaseIndexScale, position451) + add(ruleBaseIndexScale, position455) } return true - l450: - position, tokenIndex = position450, tokenIndex450 + l454: + position, tokenIndex = position454, tokenIndex454 return false }, /* 35 Operator <- <('+' / '-')> */ func() bool { - position466, tokenIndex466 := position, tokenIndex + position470, tokenIndex470 := position, tokenIndex { - position467 := position + position471 := position { - position468, tokenIndex468 := position, tokenIndex + position472, tokenIndex472 := position, tokenIndex if buffer[position] != rune('+') { - goto l469 + goto l473 } position++ - goto l468 - l469: - position, tokenIndex = position468, tokenIndex468 + goto l472 + l473: + position, tokenIndex = position472, tokenIndex472 if buffer[position] != rune('-') { - goto l466 + goto l470 } position++ } - l468: - add(ruleOperator, position467) + l472: + add(ruleOperator, position471) } return true - l466: - position, tokenIndex = position466, tokenIndex466 + l470: + position, tokenIndex = position470, tokenIndex470 return false }, /* 36 Offset <- <('+'? '-'? (('0' ('b' / 'B') ('0' / '1')+) / ('0' ('x' / 'X') ([0-9] / [0-9] / ([a-f] / [A-F]))+) / [0-9]+))> */ func() bool { - position470, tokenIndex470 := position, tokenIndex + position474, tokenIndex474 := position, tokenIndex { - position471 := position + position475 := position { - position472, tokenIndex472 := position, tokenIndex + position476, tokenIndex476 := position, tokenIndex if buffer[position] != rune('+') { - goto l472 + goto l476 } position++ - goto l473 - l472: - position, tokenIndex = position472, tokenIndex472 + goto l477 + l476: + position, tokenIndex = position476, tokenIndex476 } - l473: + l477: { - position474, tokenIndex474 := position, tokenIndex + position478, tokenIndex478 := position, tokenIndex if buffer[position] != rune('-') { - goto l474 + goto l478 } position++ - goto l475 - l474: - position, tokenIndex = position474, tokenIndex474 + goto l479 + l478: + position, tokenIndex = position478, tokenIndex478 } - l475: + l479: { - position476, tokenIndex476 := position, tokenIndex + position480, tokenIndex480 := position, tokenIndex if buffer[position] != rune('0') { - goto l477 + goto l481 } position++ { - position478, tokenIndex478 := position, tokenIndex + position482, tokenIndex482 := position, tokenIndex if buffer[position] != rune('b') { - goto l479 + goto l483 } position++ - goto l478 - l479: - position, tokenIndex = position478, tokenIndex478 + goto l482 + l483: + position, tokenIndex = position482, tokenIndex482 if buffer[position] != rune('B') { - goto l477 + goto l481 } position++ } - l478: + l482: { - position482, tokenIndex482 := position, tokenIndex + position486, tokenIndex486 := position, tokenIndex if buffer[position] != rune('0') { - goto l483 + goto l487 } position++ - goto l482 - l483: - position, tokenIndex = position482, tokenIndex482 + goto l486 + l487: + position, tokenIndex = position486, tokenIndex486 if buffer[position] != rune('1') { - goto l477 + goto l481 } position++ } - l482: - l480: + l486: + l484: { - position481, tokenIndex481 := position, tokenIndex + position485, tokenIndex485 := position, tokenIndex { - position484, tokenIndex484 := position, tokenIndex + position488, tokenIndex488 := position, tokenIndex if buffer[position] != rune('0') { - goto l485 + goto l489 } position++ - goto l484 - l485: - position, tokenIndex = position484, tokenIndex484 + goto l488 + l489: + position, tokenIndex = position488, tokenIndex488 if buffer[position] != rune('1') { - goto l481 + goto l485 } position++ } - l484: - goto l480 - l481: - position, tokenIndex = position481, tokenIndex481 + l488: + goto l484 + l485: + position, tokenIndex = position485, tokenIndex485 } - goto l476 - l477: - position, tokenIndex = position476, tokenIndex476 + goto l480 + l481: + position, tokenIndex = position480, tokenIndex480 if buffer[position] != rune('0') { - goto l486 + goto l490 } position++ { - position487, tokenIndex487 := position, tokenIndex + position491, tokenIndex491 := position, tokenIndex if buffer[position] != rune('x') { - goto l488 + goto l492 } position++ - goto l487 - l488: - position, tokenIndex = position487, tokenIndex487 + goto l491 + l492: + position, tokenIndex = position491, tokenIndex491 if buffer[position] != rune('X') { - goto l486 + goto l490 } position++ } - l487: + l491: { - position491, tokenIndex491 := position, tokenIndex + position495, tokenIndex495 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l492 + goto l496 } position++ - goto l491 - l492: - position, tokenIndex = position491, tokenIndex491 + goto l495 + l496: + position, tokenIndex = position495, tokenIndex495 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l493 + goto l497 } position++ - goto l491 - l493: - position, tokenIndex = position491, tokenIndex491 + goto l495 + l497: + position, tokenIndex = position495, tokenIndex495 { - position494, tokenIndex494 := position, tokenIndex + position498, tokenIndex498 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('f') { - goto l495 + goto l499 } position++ - goto l494 - l495: - position, tokenIndex = position494, tokenIndex494 + goto l498 + l499: + position, tokenIndex = position498, tokenIndex498 if c := buffer[position]; c < rune('A') || c > rune('F') { - goto l486 + goto l490 } position++ } - l494: + l498: } - l491: - l489: + l495: + l493: { - position490, tokenIndex490 := position, tokenIndex + position494, tokenIndex494 := position, tokenIndex { - position496, tokenIndex496 := position, tokenIndex + position500, tokenIndex500 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l497 + goto l501 } position++ - goto l496 - l497: - position, tokenIndex = position496, tokenIndex496 + goto l500 + l501: + position, tokenIndex = position500, tokenIndex500 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l498 + goto l502 } position++ - goto l496 - l498: - position, tokenIndex = position496, tokenIndex496 + goto l500 + l502: + position, tokenIndex = position500, tokenIndex500 { - position499, tokenIndex499 := position, tokenIndex + position503, tokenIndex503 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('f') { - goto l500 + goto l504 } position++ - goto l499 - l500: - position, tokenIndex = position499, tokenIndex499 + goto l503 + l504: + position, tokenIndex = position503, tokenIndex503 if c := buffer[position]; c < rune('A') || c > rune('F') { - goto l490 + goto l494 } position++ } - l499: + l503: } - l496: - goto l489 - l490: - position, tokenIndex = position490, tokenIndex490 + l500: + goto l493 + l494: + position, tokenIndex = position494, tokenIndex494 } - goto l476 - l486: - position, tokenIndex = position476, tokenIndex476 + goto l480 + l490: + position, tokenIndex = position480, tokenIndex480 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l470 + goto l474 } position++ - l501: + l505: { - position502, tokenIndex502 := position, tokenIndex + position506, tokenIndex506 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l502 + goto l506 } position++ - goto l501 - l502: - position, tokenIndex = position502, tokenIndex502 + goto l505 + l506: + position, tokenIndex = position506, tokenIndex506 } } - l476: - add(ruleOffset, position471) + l480: + add(ruleOffset, position475) } return true - l470: - position, tokenIndex = position470, tokenIndex470 + l474: + position, tokenIndex = position474, tokenIndex474 return false }, /* 37 Section <- <([a-z] / [A-Z] / '@')+> */ func() bool { - position503, tokenIndex503 := position, tokenIndex + position507, tokenIndex507 := position, tokenIndex { - position504 := position + position508 := position { - position507, tokenIndex507 := position, tokenIndex + position511, tokenIndex511 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l508 + goto l512 } position++ - goto l507 - l508: - position, tokenIndex = position507, tokenIndex507 + goto l511 + l512: + position, tokenIndex = position511, tokenIndex511 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l509 + goto l513 } position++ - goto l507 - l509: - position, tokenIndex = position507, tokenIndex507 + goto l511 + l513: + position, tokenIndex = position511, tokenIndex511 if buffer[position] != rune('@') { - goto l503 + goto l507 } position++ } - l507: - l505: + l511: + l509: { - position506, tokenIndex506 := position, tokenIndex + position510, tokenIndex510 := position, tokenIndex { - position510, tokenIndex510 := position, tokenIndex + position514, tokenIndex514 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l511 + goto l515 } position++ - goto l510 - l511: - position, tokenIndex = position510, tokenIndex510 + goto l514 + l515: + position, tokenIndex = position514, tokenIndex514 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l512 + goto l516 } position++ - goto l510 - l512: - position, tokenIndex = position510, tokenIndex510 + goto l514 + l516: + position, tokenIndex = position514, tokenIndex514 if buffer[position] != rune('@') { - goto l506 + goto l510 } position++ } + l514: + goto l509 l510: - goto l505 - l506: - position, tokenIndex = position506, tokenIndex506 + position, tokenIndex = position510, tokenIndex510 } - add(ruleSection, position504) + add(ruleSection, position508) } return true - l503: - position, tokenIndex = position503, tokenIndex503 + l507: + position, tokenIndex = position507, tokenIndex507 return false }, /* 38 SegmentRegister <- <('%' ([c-g] / 's') ('s' ':'))> */ func() bool { - position513, tokenIndex513 := position, tokenIndex + position517, tokenIndex517 := position, tokenIndex { - position514 := position + position518 := position if buffer[position] != rune('%') { - goto l513 + goto l517 } position++ { - position515, tokenIndex515 := position, tokenIndex + position519, tokenIndex519 := position, tokenIndex if c := buffer[position]; c < rune('c') || c > rune('g') { - goto l516 + goto l520 } position++ - goto l515 - l516: - position, tokenIndex = position515, tokenIndex515 + goto l519 + l520: + position, tokenIndex = position519, tokenIndex519 if buffer[position] != rune('s') { - goto l513 + goto l517 } position++ } - l515: + l519: if buffer[position] != rune('s') { - goto l513 + goto l517 } position++ if buffer[position] != rune(':') { - goto l513 + goto l517 } position++ - add(ruleSegmentRegister, position514) + add(ruleSegmentRegister, position518) } return true - l513: - position, tokenIndex = position513, tokenIndex513 + l517: + position, tokenIndex = position517, tokenIndex517 return false }, } diff --git a/src/util/fipstools/testdata/x86_64-Basic/in.s b/src/util/fipstools/testdata/x86_64-Basic/in.s index e31c3707..3b535ed7 100644 --- a/src/util/fipstools/testdata/x86_64-Basic/in.s +++ b/src/util/fipstools/testdata/x86_64-Basic/in.s @@ -35,6 +35,8 @@ foo: vpclmulqdq $0x00,%xmm6,%xmm3,%xmm3 vpxor %xmm0,%xmm1,%xmm4 vpxor %xmm4,%xmm3,%xmm3 + vmovdqu8 %ymm1,%ymm6{%k1}{z} + vmovdqu8 %ymm2,%ymm4{%k3} .byte 0xf3,0xc3 movq %rax, %rbx # Comments can be on the same line as an instruction. .L3: # Or on the same line as a label. diff --git a/src/util/fipstools/testdata/x86_64-Basic/out.s b/src/util/fipstools/testdata/x86_64-Basic/out.s index 040d8af0..211b7ea1 100644 --- a/src/util/fipstools/testdata/x86_64-Basic/out.s +++ b/src/util/fipstools/testdata/x86_64-Basic/out.s @@ -38,6 +38,8 @@ foo: vpclmulqdq $0x00,%xmm6,%xmm3,%xmm3 vpxor %xmm0,%xmm1,%xmm4 vpxor %xmm4,%xmm3,%xmm3 + vmovdqu8 %ymm1,%ymm6{%k1}{z} + vmovdqu8 %ymm2,%ymm4{%k3} .byte 0xf3,0xc3 movq %rax, %rbx # Comments can be on the same line as an instruction. .L3: |