summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Sloan <varomodt@google.com>2018-01-23 23:04:10 +0000
committerandroid-build-merger <android-build-merger@google.com>2018-01-23 23:04:10 +0000
commit05b7f4d1e470e4c096c502b557f4bc4cbbb95810 (patch)
tree18f725077b4089ab4c60f4fc19c2b265f9f79bda
parent7375becf5eb38f8e7cc10f10bb52186e559688f1 (diff)
parent2b4ddd0ae55a93b3092052ae9e745d033e3acc1a (diff)
downloadboringssl-05b7f4d1e470e4c096c502b557f4bc4cbbb95810.tar.gz
NO PARTIAL RERUN external/boringssl: Sync to cb15cfda29c0c60d8d74145b17c93b43a7667837. am: 978112cdf0
am: 2b4ddd0ae5 Change-Id: I2f61e2ac4700bb0c635ce4f0393ca9e001943bd0
-rw-r--r--BORINGSSL_REVISION2
-rw-r--r--err_data.c430
-rw-r--r--sources.bp1
-rw-r--r--src/CMakeLists.txt13
-rw-r--r--src/crypto/CMakeLists.txt3
-rw-r--r--src/crypto/err/ssl.errordata1
-rw-r--r--src/crypto/fipsmodule/bcm.c119
-rw-r--r--src/crypto/internal.h9
-rw-r--r--src/crypto/self_test.cc24
-rw-r--r--src/include/openssl/base.h2
-rw-r--r--src/include/openssl/crypto.h4
-rw-r--r--src/include/openssl/ssl.h28
-rw-r--r--src/include/openssl/tls1.h3
-rw-r--r--src/ssl/handshake_client.cc7
-rw-r--r--src/ssl/internal.h17
-rw-r--r--src/ssl/ssl_lib.cc23
-rw-r--r--src/ssl/t1_lib.cc164
-rw-r--r--src/ssl/test/bssl_shim.cc18
-rw-r--r--src/ssl/test/runner/common.go17
-rw-r--r--src/ssl/test/runner/conn.go5
-rw-r--r--src/ssl/test/runner/handshake_client.go25
-rw-r--r--src/ssl/test/runner/handshake_messages.go33
-rw-r--r--src/ssl/test/runner/handshake_server.go15
-rw-r--r--src/ssl/test/runner/runner.go422
-rw-r--r--src/ssl/test/test_config.cc3
-rw-r--r--src/ssl/test/test_config.h2
-rw-r--r--src/ssl/tls13_client.cc3
-rw-r--r--src/ssl/tls13_server.cc2
-rw-r--r--src/util/bot/DEPS4
-rw-r--r--src/util/bot/update_clang.py4
-rw-r--r--src/util/bot/vs_toolchain.py5
-rw-r--r--src/util/fipstools/delocate.go2
-rw-r--r--src/util/fipstools/delocate.peg2
-rw-r--r--src/util/fipstools/delocate.peg.go1232
-rw-r--r--src/util/fipstools/testdata/x86_64-Basic/in.s2
-rw-r--r--src/util/fipstools/testdata/x86_64-Basic/out.s2
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
diff --git a/err_data.c b/err_data.c
index 06003acd..c9e9ae4d 100644
--- a/err_data.c
+++ b/err_data.c
@@ -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"
diff --git a/sources.bp b/sources.bp
index 089bd9b9..8cf85c05 100644
--- a/sources.bp
+++ b/sources.bp
@@ -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, &params) ||
+ !CBB_add_bytes(&params, 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, &params_list) ||
+ !CBS_get_u8(&params_list, &param) ||
+ CBS_len(&params_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, &params) ||
+ CBS_len(&params) == 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, &params) ||
+ !CBB_add_u8(&params, 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: